본문 바로가기
Language/Java

[Java] 상속과 메모리 구조

by 클레어몬트 2024. 8. 9.

예시로 Car 부모 클래스와 ElectricCar 자식 클래스가 있다고 하자

 

부모 클래스 (슈퍼 클래스)

package extend;

public class Car {
    
    
    
    public void move() {
        System.out.println("차를 이동합니다.");
    }
}

 

자식 클래스 (서브 클래스)

package extend;

public class ElectricCar extends Car {



    public void charge() {
        System.out.println("충전합니다.");
    }
}

 

 

이러한 상황에서 ElectricCar 클래스 객체를 만들어보자

ElectricCar electricCar = new ElectricCar();

new ElectricCar()를 호출하면 ElectricCar뿐만 아니라 상속 관계에 있는 Car까지 함께 포함해서 인스턴스를 생성한다. 참조값은 x001로 하나이지만 실제로 그 안에서는 Car, ElectricCar라는 두 가지 클래스 정보가 공존하는 것이다. 상속이라고 해서 단순하게 부모의 필드와 메서드만 물려받는 게 아니다. 상속 관계를 사용하면 부모 클래스도 함께 포함해서 생성된다. 외부에서 볼 때는 하나의 인스턴스를 생성하는 것 같지만 내부에서는 부모와 자식이 모두 생성되고 공간도 구분된다.

 

 

① electricCar.charge() 호출

electricCar.charge()를 호출하면 참조값을 확인해서 x001.charge()를 호출한다. 따라서 x001을 찾아서 charge()를 호출하면 되는 것인데 상속 관계의 경우에는 내부에 부모와 자식이 모두 존재한다. 이때 부모인 Car를 통해서 charge()를 찾을지 아니면 ElectricCar를 통해서 charge()를 찾을지 선택해야 한다.

이럴 때는 호출하는 변수의 타입(클래스)을 기준으로 선택한다. electricCar 변수의 타입이 ElectricCar이므로 인스턴스 내부에 같은 타입인 ElectricCar를 통해서 charge()를 호출하는 것이다.

 

 

② electricCar.move() 호출

electricCar.move()를 호출하면 먼저 x001 참조로 이동한다. 내부에는 Car, ElectricCar 두 가지 타입이 있다. 이때 호출하는 변수 electricCar의 타입인 ElectricCar를 선택한다.
그런데 ElectricCar에는 move() 메서드가 없다. 상속 관계에서는 자식 타입에 해당 기능이 없으면 부모 타입으로 올라가서 찾는다. 이 경우 ElectricCar의 부모인 Car로 올라가서 move()를 찾는다. 부모인 Carmove()가 있으므로 부모에 있는 move() 메서드를 호출한다.

만약 부모에서도 해당 기능을 찾지 못한다면 더 상위 부모로 계속 올라가서 필요한 기능을 찾는다. 부모에 부모로 계속 올라가면서 필드나 메서드를 찾는 것이다. 물론 계속 찾아도 없다면 그때는 컴파일 오류가 발생한다.

 

 

 

 

정리하자면 이 3가지를 명확하게 숙지하고 있어야 한다

1. 상속 관계의 객체를 생성하면 그 내부에는 부모와 자식이 모두 생성된다
2. 상속 관계의 객체를 호출할 때, 대상 타입을 정해야 한다. 이때 호출자의 타입을 통해 대상 타입을 찾는다
3. 현재 타입에서 기능을 찾지 못하면 상위 부모 타입으로 가 기능을 계속해서 찾는다, 만약에 기능을 찾지 못한다면 컴파일 오류가 발생한다

 

이 개념들은 다형성 파트를 깊게 이해하는 데에 중요하므로 확실히 이해하고 넘어가자

 

 

 

 

 

참고 및 출처: 김영한의 실전 자바 - 기본편 https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B8%B0%EB%B3%B8%ED%8E%B8