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

Zn아쿠님의 프로필 이미지
Zn아쿠

작성한 질문수

나도코딩의 자바 기본편 - 풀코스 (20시간)

퀴즈 #7

왜 자식클래스의 메서드가 메인에서 실행될까요?

작성

·

265

0

 다형성을 배울때, 변수의 자료형이 부모클래스라면 자식클래스에만 존재하는 메서드는 바로 사용이 되지않아 자식클래스로 형변환 해준뒤 사용한다고 했던거같습니다. 하지만 이번 예제에서, 분명 hamburgers array의 자료형은 Hamburger,즉 부모클래스의 자료형인데, 어째서 루프 안에서 hamburger.cook()이 실행될때마다 오버라이딩된 자식클래스 속의 cook메서드가 실행되는거에요?

답변 2

0

나도코딩님의 프로필 이미지
나도코딩
지식공유자

네! 이해하신 내용이 맞습니다 😊

0

나도코딩님의 프로필 이미지
나도코딩
지식공유자

안녕하세요?

말씀하신 것처럼 참조 변수의 자료형이 부모 클래스라면 자식 클래스에만 존재하는 메소드는 바로 사용을 할 수가 없습니다.

class Parent {
    public void ParentMethod() {
        System.out.println("부모 클래스");
    }
}

class Child extends Parent{
    public void ChildMethod() {
        System.out.println("자식 클래스");
    }
}

위 코드에서 Child 는 Parent 를 상속하므로 다음과 같이 객체를 만들 수는 있지만 ChildMethod() 를 호출할 수는 없지요.

public static void main(String[] args) {
    Parent parent = new Parent();
    Parent child = new Child();
    child.ChildMethod(); // 에러 발생
}

하지만 Parent, Child 로부터 각각 만들어진 객체는 모두 ParentMethod() 는 호출이 가능합니다.

public static void main(String[] args) {
    Parent parent = new Parent();
    Parent child = new Child();

    parent.ParentMethod();
    child.ParentMethod();
}

실행 결과는 이렇습니다.

부모 클래스
부모 클래스

부모 클래스에 정의된 메소드의 동작이 아닌 다른 동작을 하려고 할 때 메소드 오버라이딩을 할 수 있습니다. 즉 부모 클래스의 메소드를 '덮어쓰기' 하는 것이죠.

Child 클래스에 이렇게 메소드를 추가해볼까요?

class Child extends Parent{
    public void ChildMethod() {
        System.out.println("자식 클래스");
    }
	
    // 오버라이딩
    public void ParentMethod() {
        System.out.println("자식 클래스에서 오버라이딩");
    }
}

부모 클래스에 정의된 메소드를 재정의하는 것, 오버라이딩의 용도가 바로 이것입니다. 그래서 동일하게 아래 코드를 실행하게 되면 이번에는 다른 결과를 얻게 됩니다.

public static void main(String[] args) {
    Parent parent = new Parent();
    Parent child = new Child();

    parent.ParentMethod();
    child.ParentMethod();
}

(실행 결과)

부모 클래스
자식 클래스에서 오버라이딩

참조 변수의 자료형이 부모 클래스라면 자식 클래스에만 존재하는 메소드는 바로 사용을 할 수가 없지만, 위 경우는 자식 클래스에만 존재하는 메소드가 아니기 때문에 parent, child 모두 ParentMethod() 호출이 가능하며, Child 클래스로부터 만들어진 child 객체는 부모 클래스의 메소드를 덮어쓰기 때문에 같은 이름의 메소드를 호출해도 자식 클래스에 정의된 메소드가 동작하는 것입니다.

Hamburger 클래스 또한 다음과 같이 cook() 메소드가 정의되어 있으며, 자식 클래스인 CheeseBurger, ShrimpBurger 에도 동일한 이름으로 메소드를 정의하여 부모 클래스의 메소드를 오버라이딩합니다.

public void cook() {
    ....
}

그리고 HamBurger 배열의 각 요소의 객체는 HamBurger, CheeseBurger, ShrimpBurger 로 각각 정의되어 있으므로 각 클래스에서 오버라이딩된 cook() 메소드의 동작이 수행되는 것입니다.

HamBurger[] hamBurgers = new HamBurger[3];
hamBurgers[0] = new HamBurger();
hamBurgers[1] = new CheeseBurger();
hamBurgers[2] = new ShrimpBurger();

답변이 다소 길었는데, 읽어보시고 궁금증 해결이 되지 않는다면 다시 질문 남겨주시면 다른 방식으로 설명드려보겠습니다 😊

감사합니다.

Zn아쿠님의 프로필 이미지
Zn아쿠
질문자

아 이해하는데 조금 걸렸는데 이해한거같습니다. 오버 라이딩을 그래서 강의때 “덮어쓰기”라고 표현하신거군요. 즉, Parent child = new Child 했을때, 비록 child변수 안의 필드와 메서드는 Parent의 형태를 지니지만, Child에서 오버라이딩될수있는것들은 전부 오버라이딩된 채로 선언된다. 라고 이해되는데 맞을까요?

Zn아쿠님의 프로필 이미지
Zn아쿠

작성한 질문수

질문하기