인프런 커뮤니티 질문&답변

짱_우님의 프로필 이미지
짱_우

작성한 질문수

김영한의 실전 자바 - 기본편

상속과 메모리 구조

섹션 10: 상속과 메모리 구조 부분에 질문이 있습니다.

작성

·

72

·

수정됨

0

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요?
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요?
3. 질문 잘하기 메뉴얼을 읽어보셨나요?

[질문 내용]

강의하는 부분 5:00 쪽에서 설명해주시면서

이때 부모인 Car 를 통해서 charge() 를 찾을지 아니면 ElectricCar 를 통해서 charge() 를 찾을지 선택해야 한다.

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

 

그리고 마지막에 아래와 같이 정리해주셨는데요.

지금까지 설명한 상속과 메모리 구조는 반드시 이해해야 한다.

  • 상속 관계의 객체를 생성하면 그 내부에는 부모와 자식이 모두 생성된다.

  • 상속 관계의 객체를 호출할 때, 대상 타입을 정해야 한다. 이때 호출자의 타입을 통해 대상 타입을 찾는다.

  • 현재 타입에서 기능을 찾지 못하면 상위 부모 타입으로 기능을 찾아서 실행한다. 기능을 찾지 못하면 컴파일 오류가 발생한다.

 

이때는 호출하는 변수의 타입(클래스)을 기준으로 선택한다. / 상속 관계의 객체를 호출할 때, 대상 타입을 정해야 한다. 이때 호출자의 타입을 통해 대상 타입을 찾는다.

이 부분에 대해 질문을 드립니다. 제가 아직 다음 강의를 듣지 않아서 모르는 것이라고 생각할 수 있는데

아래와 같은 코드를 작성했습니다.

package extends1.ex2;

public class ElectricCar extends Car {
    public void move() {
        System.out.println("Electric Car move");
    }

    public void charge() {
        System.out.println("charge");
    }
}
package extends1.ex2;

public class Car {
    public void move() {
        System.out.println("move");
    }
}
package extends1.ex2;

public class CarMain {
    public static void main(String[] args) {
        ElectricCar electricCar = new ElectricCar();
        electricCar.move();

        Car car = new ElectricCar();
        car.move();
    }
}

위에 있는 이때는 호출하는 변수의 타입(클래스)을 기준으로 선택한다. / 상속 관계의 객체를 호출할 때, 대상 타입을 정해야 한다. 이때 호출자의 타입을 통해 대상 타입을 찾는다. 의 대답이 맞으려면 뭔가 electricCar.move() 를 실행할 때랑 car.move() 를 실행할 때랑 결과가 달라야할 것 같은데 둘다 결과가 Electric Car move 가 나옵니다.

 

제 예상으로는 ElectricCar 로 생성하는 경우는 Electric Car move 가 나와야하고 Car 로 생성하는 경우 move 결과가 나와야 할 것 같아보여서요.

 

혹시 제가 놓치는 부분이 있을까요?

답변 2

0

안녕하세요. 짱_우님, 공식 서포터즈 y2gcoder입니다.

현재 메서드 오버라이딩에 대해 학습하지 않은 상황에서 그러한 고민을 하시는 것은 당연하다고 생각합니다!

메서드 오버라이딩 강의를 학습하시고 나면 이해가 되실 거라 생각합니다 🙂

감사합니다.

0

안녕하세요, 인프런 AI 인턴입니다. 짱_우님.

상속과 메모리 구조 관련 질문 주셔서 감사합니다. 질문해주신 내용은 상속과 다형성에 관련된 부분으로 아주 중요한 내용입니다.

상속 관계에서 객체를 호출할 때 동작 방식에 대해 궁금증을 가지신 것 같습니다. 예제를 통해서 설명드리겠습니다.

먼저, ElectricCar 클래스와 Car 클래스가 있고, CarMain 에서 두 가지 방법으로 객체를 생성하고 메서드를 호출하셨습니다.

public class ElectricCar extends Car {
    public void move() {
        System.out.println("Electric Car move");
    }

    public void charge() {
        System.out.println("charge");
    }
}

public class Car {
    public void move() {
        System.out.println("move");
    }
}

public class CarMain {
    public static void main(String[] args) {
        ElectricCar electricCar = new ElectricCar();
        electricCar.move(); // 출력: Electric Car move

        Car car = new ElectricCar();
        car.move(); // 출력: Electric Car move
    }
}

결과적으로 electricCar.move()car.move() 의 출력이 동일하게 “Electric Car move” 가 나오는 이유를 설명드리겠습니다.

이유: 다형성(polymorphism)에 의한 메서드 호출

  1. 다형성: Car car = new ElectricCar(); 코드와 같이 부모 클래스 타입(카)의 참조 변수로 자식 클래스(ElectricCar) 객체를 참조할 수 있는 기능을 말합니다.

  2. 메서드 오버라이딩: 부모 클래스에 정의된 메서드를 자식 클래스에서 동일한 이름, 동일한 매개변수로 다시 정의하는 것을 말합니다. 자식 클래스에서 오버라이딩된 메서드가 존재하면, 참조 변수의 타입에 관계없이 자식 클래스의 메서드가 호출됩니다.

즉, Car car = new ElectricCar(); 에서 car.move() 를 호출하면 Car 클래스의 move() 가 아닌 ElectricCar 클래스의 move() 가 호출됩니다.

메서드 호출 순서

  • electricCar.move() 호출:

    • ElectricCar 클래스에서 move() 메서드 검색 → 있음 → “Electric Car move” 출력
  • car.move() 호출:

    • ElectricCar 클래스에서 move() 메서드 검색 → 있음 → “Electric Car move” 출력
    • 이 경우는 car 객체가 ElectricCar 클래스 인스턴스를 참조하고 있으므로, ElectricCarmove() 메서드가 호출됩니다.

추가 질문

이번 예제를 통해서 이해가 잘 안되시거나 더 알고 싶은 부분이 있으시면, 다른 유사한 질문과 답변을 통해 좀 더 심도 있게 학습하실 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

짱_우님의 프로필 이미지
짱_우

작성한 질문수

질문하기