Post

[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()를 호출 할 때 컴파일 에러가 발생한다. 매개변수 objObject 타입이기 때문이다.

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를 통해 전달 받은 객체를 호출하려면 각 객체에 맞는 다운캐스팅 과정이 필요하다.

This post is licensed under CC BY 4.0 by the author.