<aside> 💡
다형성은 사용 방법은 동일하지만 다양한 객체를 이용해서 다양한 실행결과가 나오도록 하는 성질입니다.
</aside>
// 부모 클래스
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
public void sound() {
System.out.println("동물이 소리를 냅니다.");
}
}
// 자식 클래스
class Dog extends Animal {
private int age;
public Dog(String name, int age) {
super(name);
this.age = age;
}
@Override
public void sound() {
System.out.println("멍멍!");
}
}
public class Main {
public static void main(String[] args) {
// 다형성을 활용한 객체 생성
Animal animal = new Dog("바둑이", 3);
animal.sound(); // "멍멍!" 출력
}
}
graph TD
subgraph 메소드영역_Method_Area
AnimalClass["Animal 클래스 바이트코드<br/>---------------<br/>+sound() {...}"]
DogClass["Dog 클래스 바이트코드<br/>---------------<br/>+sound() {...}"]
DogClass -->|상속| AnimalClass
end
subgraph 힙_Heap
DogInstance["Dog 인스턴스<br/>---------------<br/>name='바둑이'<br/>age=3"]
DogMetadata["Dog 클래스 메타데이터<br/>---------------<br/>- 메소드 테이블<br/> sound() -> Dog.sound()<br/>- 필드 정보<br/> name: String<br/> age: int"]
AnimalMetadata["Animal 클래스 메타데이터<br/>---------------<br/>- 메소드 테이블<br/> sound() -> Animal.sound()<br/>- 필드 정보<br/> name: String"]
end
subgraph 스택_Stack
animal["animal<br/>(Animal 타입 참조변수)"]
end
DogMetadata -->|상속 메타데이터| AnimalMetadata
DogInstance -->|클래스 정보 참조| DogMetadata
DogMetadata -->|메소드 참조| DogClass
AnimalMetadata -->|메소드 참조| AnimalClass
animal -->|참조| DogInstance
<aside> 💡
이렇게 구성되면 메소드 호출 시:
왜
super
가 힙 메모리에 독립적으로 없는가?
- 객체는 상속 계층 전체를 포함한 단일 메모리 블록으로 힙 메모리에 생성됩니다.
Superclass
의 필드는Subclass
객체 내부에 포함됩니다. 따라서superField
는Subclass
객체의 일부로 존재합니다.
한 객체에 포함되는 이유
- Java의 상속 구조에서 객체는 자신의 상위 클래스 필드를 메모리 구조에 포함합니다.
- 독립적으로
super
와sub
를 나누지 않고, 하나의 객체에 상속된 모든 필드가 통합됩니다.
오버라이드의 동작 원리
- Method Area에 저장되는 메서드 정보:
Superclass
와Subclass
는 각각superMethod()
의 바이트코드 위치를 정의합니다.Subclass
에서superMethod()
를 오버라이드했으므로,Subclass
메타데이터가 오버라이드된 메서드의 바이트코드 위치를 가리킵니다.- Heap Memory의 객체:
- 힙 메모리의
Subclass
객체는 여전히superField
와subField
를 포함합니다.- 참조 변수(
obj
)의 타입에 상관없이, 실제 객체의 클래스(Subclass
)에 정의된 메서드가 호출됩니다.- Stack Memory의 메서드 호출:
obj.superMethod()
호출 시, 실제 객체의 클래스(Subclass
)의 메서드를 실행합니다.- 이는 실행 시점에 메서드가 동적으로 바인딩되기 때문입니다 (Dynamic Method Dispatch).
왜 오버라이드된 메서드가 호출되는가?
- 다형성에서 참조 변수(
Superclass obj
)의 타입은 상위 클래스이지만, **실제 객체의 클래스가Subclass
*입니다.- JVM은
obj
가 참조하는 실제 객체의 메타데이터(Subclass Metadata
)를 확인하여 **오버라이드된 메서드(superMethod in Subclass)**를 호출합니다.