ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA] Object 클래스
    자바 2024. 8. 19. 11:28

    java.lang 패키지

    자바가 기본으로 제공하는 라이브러리(클래스 모음) 중에 가장 기본이 되는 것

    [ java.lang 패키지의 대표적인 클래스들 ]
    Object : 모든 자바 객체의 부모 클래스
    String : 문자열
    Integer , Long , Double : 래퍼 타입, 기본형 데이터 타입을 객체로 만든 것
    Class : 클래스 메타 정보
    System : 시스템과 관련된 기본 기능들을 제공

     

     

     

     

    Object 클래스

    자바에서 모든 클래스의 최상위 부모 클래스는 항상 Object 클래스이다.

    package lang.object;
    
    // 부모가 없으면 묵시적으로 Object 클래스를 상속받는다.
    // public class Parent extends Object {
    public class Parent {
        public void parentMethod() {
            System.out.println("Parent.parentMethod");
        }
    }

    - 클래스에 상속받을 부모 클래스가 없으면 묵시적으로 Object 클래스를 상속받는다.

    - 자바가 extends Object 코드를 넣어주기 때문에 생략하는 것을 권장한다.

    - 클래스에 상속받을 부모 클래스를 명시적으로 지정하면 Object를 상속받지 않는다.

    - Parent는 Object를 묵시적으로 상속받았기 때문에 메모리에도 함께 생성된다.

     

     

    자바에서 Object 클래스가 최상위 부모 클래스인 이유

    1) 공통 기능 제공

    Object는 모든 객체에 필요한 공통 기능을 제공한다.

    Object 는 최상위 부모 클래스이기 때문에 모든 객체는 공통 기능을 편리하게 제공(상속) 받을 수 있다.

    ex) toString(), equals(), getClass()

    2) 다형성의 기본 구현

    Object 는 모든 클래스의 부모 클래스이다. 따라서 모든 객체를 참조할 수 있다.

    즉, Object 는 모든 객체를 다 담을 수 있다.

    타입이 다른 객체들을 어딘가에 보관해야 한다면 바로 Object에 보관하면 된다.

     

     

    Object 다형성

    package lang.object.poly;
    
    class Car {
        public void move() {
            System.out.println("자동차 이동");
        }
    }
    package lang.object.poly;
    
    class Dog {
        public void sound() {
            System.out.println("멍멍");
        }
    }
    package lang.object.poly;
    
    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();
            }
        }
        
    }

    - obj.sound() 호출

        - Object obj의 참조값을 Dog dog로 다운캐스팅 하면서 전달한다.

        - dog.sound()를 호출하면 Dog 타입에서 sound() 를 찾아서 호출한다.

     

     

    Object 배열

    package lang.object.poly;
    
    public class ObjectPolyExample2 {
        public static void main(String[] args) {
        
            Dog dog = new Dog();
            Car car = new Car();
            Object object = new Object(); //Object 인스턴스도 만들 수 있다.
            
            Object[] objects = {dog, car, object};
            
            size(objects);
            
        }
         
        private static void size(Object[] objects) {
            System.out.println("전달된 객체의 수는: " + objects.length); // 3 출력
        }
        
    }
    Object[] objects = {dog, car, object};
    
    //쉽게 풀어서 설명하면 다음과 같다.
    Object objects[0] = new Dog();
    Object objects[1] = new Car();
    Object objects[2] = new Object()

    Object는 모든 타입의 객체를 담을 수 있다.

    따라서 Object[]을 만들면 세상의 모든 객체를 담을 수 있는 배열을 만들 수 있다.

     

     

    Object와 OCP

    public class ObjectPrinter {
        public static void print(Object obj) {
            String string = "객체 정보 출력: " + obj.toString();
            System.out.println(string);
        }
    }

    ObjectPrinter클래스가 Object클래스를 사용하는 것을 ObjectPrinter클래스가 Object에 클래스에 의존한다고 표현한다.

    ObjectPrinter는 구체적인 것(Car, Dog 등)에 의존하는 것이 아니라 추상적인 것(Object)에 의존한다.

     

    ObjectPrinter와 Object를 사용하는 구조는 다형성을 매우 잘 활용하고 있다.

    다형성을 잘 활용한다는 것은 다형적 참조와 메서드 오버라이딩을 적절하게 사용한다는 뜻이다.

    - 다형적 참조 : print(Object obj) , Object 타입을 매개변수로 사용해서 다형적 참조를 사용한다. Car , Dog 인스턴스를 포함한 세상의 모든 객체 인스턴스를 인수로 받을 수 있다.

    - 메서드 오버라이딩 : Object는 모든 클래스의 부모이다. 따라서 Dog , Car와 같은 구체적인 클래스는 Object 가 가지고 있는 toString() 메서드를 오버라이딩 할 수 있다. 따라서 print(Object obj) 메서 드는 Dog , Car 와 같은 구체적인 타입에 의존(사용) 하지 않고, 추상적인 Object 타입에 의존하면서 런타임에 각 인스턴스의 toString()을 호출할 수 있다.

     

    OCP 원칙

    Open: 새로운 클래스를 추가하고, toString() 을 오버라이딩해서 기능을 확장할 수 있다.

    Closed: 새로운 클래스를 추가해도 Object와 toString()을 사용하는 클라이언트 코드인 ObjectPrinter는 변경하지 않아도 된다.

     

    > 다형적 참조, 메서드 오버라이딩, 그리고 클라이언트 코드가 구체적인 Car , Dog에 의존하는 것이 아니라 추상적인 Object에 의존하면서 OCP 원칙을 지킬 수 있었다. 덕분에 새로운 클래스를 추가하고 toString() 메서드를 새롭게 오버라이딩해서 기능을 확장할 수 있다. 그리고 이러한 변화에도 불구하고 클라이언트 코드인 ObjectPrinter는 변경할 필요가 없다.

     

     

     

     


    (참고)

    김영한 실전자바 - 중급 1 (섹션1. Object  클래스)

    728x90

    '자바' 카테고리의 다른 글

    [JAVA] 불변 객체  (0) 2024.08.19
    [JAVA] equals() - 동일성과 동등성  (0) 2024.08.19
    [JAVA] 생성자  (0) 2024.08.14
    [JAVA] 예외처리  (0) 2023.05.07
    [JAVA] path 클래스  (0) 2023.05.06
Designed by Tistory.