Search
Duplicate
📒

[Java Study] 02-1. java.lang 패키지, Object 클래스, 다형성

상태
완료
수업
Java Study
주제
4 more properties
참고

java.lang 패키지 소개

NOTE
java.lang 패키지는 자바가 기본으로 제공하는 라이브러리(클래스 모음)중에 가장 기본이 되는 패키지입니다.
대표적인 lang 클래스들
java.lang 패키지는 모든 자바 애플리케이션에 자동으로 import되어 따로 import해주지 않아도 됩니다.

java.lang.Object 클래스

NOTE
자바에서 모든 클래스의 최상위 부모 클래스는 항상 Object 클래스입니다.
자바 상속 이미지
// 부모 클래스 (묵시적 상속으로 Object를 상속 받는다.) public class Parent { public void parentMethod(){ System.out.println("Parent.parentMethod"); } } // 자식 클래스 (명시적 상속으로 Parent를 상속 받는다.) public class Child extends Parent { public void childMethod() { System.out.println("Child.childMethod"); } }
Java
복사
묵시적: 개발자가 코드에 직접 작성하지 않아도 시스템 또는 컴파일러가 자동으로 수행하는 것을 의미합니다.
명시적: 개발자가 코드에 직접 작성하여 작동하는 것을 의미합니다.
자바에서 모든 클래스가 Object 클래스를 상속받는 이유는 주로 두 가지입니다.
1.
모든 객체는 객체 정보 확인, 비교, 클래스 정보 확인과 같은 기본 기능이 필요합니다. 이러한 메서드는 최상위 클래스가 공통 기능으로 제공할 수 있습니다.
2.
자바에서는 부모 클래스가 자식 클래스를 할당받을 수 있습니다. 따라서 Object 클래스는 모든 클래스를 담을 수 있으며, 이는 다형성의 기본을 형성합니다.

Object 다형성

NOTE
Object는 모든 클래스의 부모 클래스이므로, 모든 객체를 참조할 수 있습니다. 이를 통해 다형성을 활용할 수 있습니다.
다형성을 활용한다는 의미는 다형적 참조메서드 오버라이딩을 잘 활용한다는 의미입니다.
다형적 참조는 Object와 같이 추상타입으로 구체 타입을 받는 방식을 말합니다.
메서드 오버라이딩은 구체적인 타입에 의존하지 않으면서, 런타임에는 각각 인스턴스의 오버라이딩된 메서드를 호출하는 방법을 말합니다.

다형적 참조

Dog, Car은 Object를 상속받고 있다.
object의 다형성 예제 (부모에 없는 함수는 호출불가)
// action에는 Object 매개변수를 사용하므로 // Dog, Car 어떠한 인스턴스 타입이든 들어갈 수 있다. Dog dog = new Dog(); Car car = new Car(); action(dog); action(car); private static void action(Object obj) { obj.toString(); // obj.sound() // 컴파일 오류, Object는 sound()가 없다. // obj.move() // 컴파일 오류, Object는 move()가 없다. if (obj instanceof Dog dog) { dog.sound(); } if (obj instanceof Car car) { car.move(); } }
Java
복사
다형석 참조의 한계 - 부모에게 없는 함수 호출 불가
obj.sound() 호출
obj는 Object 타입이므로, sound()는 Object 타입에서 찾아야 합니다.
Object에서 sound()를 찾을 수 없습니다. Object는 최종 부모이므로, 더 이상 상위로 찾아갈 수 없습니다.
dog.sound() 호출
Object obj의 참조값을 Dog 타입의 dog로 다운 캐스팅하여 전달합니다.
dog.sound()를 호출하면, Dog 타입에서 sound()를 찾아 호출합니다.

메서드 오버라이딩

오버라이딩 예시
public class Dog { // ... // toString 오버라이딩 @Override public String toString() { return "Dog{" + "dogName='" + dogName + '\'' + ", age=" + age + '}'; } }
Java
복사
// print 메서드는 런타임시 해당 인스턴스 객체의 toString을 호출한다. public static void print(Object obj) { String string = "객체 정보 출력: " + obj.toString(); System.out.println(string); } Car car1 = new Car("ModelY"); Dog dog1 = new Dog("멍멍이1", 2); // 내부에서 toString 호출 System.out.println(car1); System.out.println(dog1); // 다형성 print(car1); print(dog1);
Java
복사

Object와 OCP

NOTE
OCP는 개방-폐쇄 원칙을 의미하며, 기존 코드를 변경하지 않으면서(closed) 기능을 추가(open)할 수 있도록 설계되어야 한다는 원칙입니다.
앞서 구현한 print()메서드를 통해 자바에서 OCP를 어떻게 준수하는지 설명할 수 있습니다.
public static void print(Object obj) { String string = "객체 정보 출력: " + obj.toString(); System.out.println(string); }
Java
복사
앞서 구현한 print는 System.out.println()과 매우 유사하다.
Open: 새로운 클래스를 추가하더라도, toString()을 오버라이딩하여 기능을 확장할 수 있습니다.
Closed: 새로운 클래스를 추가하더라도, Object와 toString()을 사용하는 클라이언트 코드인 print()를 수정할 필요가 없습니다.

정적 의존관계 vs 동적 의존관계

Object는 동적 의존관계로 동작하고 있다.
정적 의존관계
컴파일 시간에 결정되며, 클래스 간의 관계를 의미한다.
프로그램을 실행하지 않고, 클래스 내에 사용하는 타입들만 보면 쉽게 의존관계를 알 수 있다.
동족 의존관계
프로그램을 실행하는 런타임에 확인할 수 있는 의존관계 이다.
어떤 경우에는 Car, Dog 인스턴스가 넘어온다.
이렇게 런타임에 어떤 인스턴스를 나타내는 것이 동적 의존 관계이다.
참고 (이펙티브 자바 다중정의 참조)
메서드의 오버로딩의 경우, 컴파일단계에서 어떠한 메서드를 호출할지 결정하므로, 매개변수의 타입이 다르더라도, 컴파일 단계에서 부모 클래스의 메서드로 던질 수 있으니 주의하자.