[JAVA] Object 클래스 알아보기
Object 클래스
김영한의 실전 자바 중급 1편을 보며 정리해보는 Object 클래스
자바가 기본으로 제공하는 라이브러리 중 가장 기본이 되는 것이 java.lang
패키지이다. java.lang
패키지는 모든 자바 애플리케이션에 자동으로 import
된다. 대표적인 클래스로는 다음과 같은 클래스들이 있다.
Object
: 모든 자바 객체의 부모 클래스String
: 문자열Integer
,Long
,Double
: 래퍼 타입, 기본형 데이터 타입을 객체로 만든 것Class
: 클래스 메타 정보System
: 시스템과 관련된 기본 기능들을 제공
오늘은 이 클래스들 중 모든 클래스들의 부모인 Object
클래스에 대해 알아보도록 하자.
Object 클래스의 상속
자바에서 모든 클래스의 최상위 부모 클래스는 항상
Object
클래스이다.
1
2
3
4
5
6
// Parent 클래스는 묵시적으로 Object 클래스를 상속받는다.
public class Parent { // extends Object가 생략되어 있는 것과 같다.
public void parentMethod() {
System.out.println("Parent.parentMethod");
}
}
모든 클래스에 상속 받을 부모가 없으면 묵시적으로 Object
클래스를 상속 받는다. 즉, extends Object
를 생략해도 자바가 알아서 Object
를 상속받는 것으로 인식한다.
1
2
3
4
5
6
// Child 클래스는 Parent 클래스를 상속받는다.
public class Child extends Parent {
public void childMethod() {
System.out.println("Child.childMethod");
}
}
클래스에 상속 받을 부모 클래스를 명시적으로 지정하면 Object
를 상속 받지 않는다.
❔ 묵시적(Implicit)과 명시적(Explicit)
묵시적: 개발자가 코드에 직접 기술하지 않아도 시스템 또는 컴파일러에 의해 자동으로 수행되는 것을 의미한다.
명시적: 개발자가 코드에 직접 기술해서 작동하는 것을 의미한다.
자바에서 Object 클래스가 최상위 부모 클래스인 이유💭
Object
클래스가 최상위 부모 클래스이면 아래와 같은 이점을 얻을 수 있다.
공통 기능 제공
모든 객체가 공통 기능을 편리하게 제공(상속) 받을 수 있다.
Object
는 모든 객체에 필요한 공통 기능을 제공한다. Object
는 최상위 부모 클래스이기 때문에 모든 객체는 공통 기능을 편리하게 제공받거나 재정의 해서 사용할 수 있다.
Object
가 제공하는 주요 기능
toString()
: 객체의 정보 제공equals()
: 객체의 같음을 비교getClass()
: 객체의 클래스 정보를 제공clone()
: 객체 복사
따라서 프로그램이 단순화되고 일관성을 가진다.
다형성의 기본 구현 - 다형적 참조
다양한 객체를 통합적으로 처리 할 수 있다.
다형적 참조에 따르면 부모는 자식을 담을 수 있다. 따라서 Object
클래스는 모든 객체를 참조할 수 있다. 모든 자바 객체는 Object
타입으로 처리될 수 있으며, 이는 다양한 타입의 객체를 통합적으로 처리할 수 있게 해준다. 타입이 다른 객체를 어딘가에 보관해야 한다면 Object
에 보관하면 된다.
Object 다형성
Object 다형성의 장점
Object
를 통해 다형적 참조가 가능해지기 때문에 어떤 객체든지 인자로 전달할 수 있게 된다.
다음 코드를 살펴보자.
1
2
3
4
5
public class Dog {
public void sound() {
System.out.println("멍멍");
}
}
1
2
3
4
5
public class Car {
public void move() {
System.out.println("자동차 이동");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class ObjectPolyExample1 {
public static void main(String[] args) {
Dog dog = new Dog();
Car car = new Car();
action(dog);
action(car);
}
private static void action(Object obj) {
// obj.sound(); 컴파일 오류, Object는 sound()가 없음
// obj.move(); 컴파일 오류, Object는 move()가 없음
// 객체에 맞는 다운캐스팅 필요
if (obj instanceof Dog dog) {
dog.sound();
} else if (obj instanceof Car car) {
car.move();
}
}
}
1
2
멍멍
자동차 이동
action(Object obj)
메서드는 Object
타입의 매개변수를 사용한다. 따라서 Dog
, Car
와 같이 서로 전혀 상관 없는 타입들도 입력받아 사용할 수 있게 되었다.
Object 다형성의 한계
그러나 obj.sound()
, obj.move()
를 호출 할 때 컴파일 에러가 발생한다. 매개변수 obj
는 Object
타입이기 때문이다.
obj
를 통해 move()
를 호출하게 되면 먼저 해당 참조에 있는 Object
인스턴스 안에서 move()
를 찾게 되는데, Object
에는 move()
메서드가 없다.
현재 클래스에 찾는 메서드가 없다면 컴파일러는 상위 클래스로 찾아가게 되는데, Object
는 최종 부모이므로 더 이상 찾을 곳이 없다. 따라서 다음과 같은 컴파일 에러를 발생시킨다.
1
2
3
java: cannot find symbol
symbol: method move()
location: variable obj of type java.lang.Object
따라서 Object
를 상속받은 Car
인스턴스의 메서드를 호출하려면 다음과 같이 다운캐스팅을 해야 한다.
1
2
3
if (obj instanceof Car car) {
car.move();
}
Object
는 모든 객체의 부모지만, Object
를 상속받은 객체의 메서드나 정보는 알 수 없다는 것이 한계이다. Object
를 통해 전달 받은 객체를 호출하려면 각 객체에 맞는 다운캐스팅 과정이 필요하다.