-
[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