자바 동적바인딩

이규훈·2024년 4월 11일
public class test {
    public static void main(String[] args) {
        parent c = new Child();
        c.paint();
        c.draw();    }
}
class parent {
    public void paint(){
        System.out.println("A");
        draw();
    }
    public void draw(){
        System.out.println("B");
        draw();
    }
}
class Child extends parent {
    public void paint(){
        super.draw();
        System.out.println("C");
        this.draw();
    }
    public void draw(){
        System.out.println("D");
    }
}

정처기 문제 공부하면서 못 풀었던 문제이다.
여기서 답은 BDCDD인데

내가 궁금했던 것은

class parent {
    public void paint(){
        System.out.println("A");
        draw();
    }
    public void draw(){
        System.out.println("B");
       ** draw();**
    }
}

이 draw()안에 있던 draw()가 왜 child의 draw() 메서드인지 이해가 안갔다.

이건 자바의 동적 바인딩와 오버라이딩에 대해서 알아야지 알 수 있다.
이해하기 어려웠던 부분을 자세히 설명하겠습니다.

오버라이딩

먼저 오버라이딩(Overriding)의 개념부터 살펴보겠습니다.

오버라이딩이란 상속 관계에 있는 클래스에서 부모 클래스의 메서드와 동일한 시그니처(반환 타입, 메서드 이름, 매개변수)의 메서드를 자식 클래스에서 재정의하는 것을 말합니다.

이 때, 실제로 호출되는 메서드는 동적 바인딩(Dynamic Binding) 에 의해 결정됩니다.

동적 바인딩

동적 바인딩이란 프로그램이 실행될 때 메서드 호출이 결정되는 것을 말합니다. 즉, 컴파일 타임이 아닌 런타임에 실제로 호출되는 메서드가 결정되는 것입니다.

이 코드의 경우, parent c = new Child(); 에서 cChild 객체를 참조하고 있지만, 변수 타입은 parent 입니다.

그리고 c.draw();를 호출하면, 실제로 호출되는 메서드는 Child 클래스의 draw() 메서드가 됩니다.

이것이 동적 바인딩의 핵심 원리입니다. 변수의 타입이 아닌 실제 객체의 타입에 따라 호출될 메서드가 결정되는 것이죠.

이제 parent 클래스의 draw() 메서드 내부에서 draw();가 재귀적으로 호출되는 부분을 보겠습니다.

public void draw(){
    System.out.println("B");
    draw(); // 이 부분
}

여기서 다시 한번 동적 바인딩이 일어납니다.

parent 클래스의 draw() 메서드 내부에서 draw();가 호출되면, 실제로는 Child 클래스의 draw() 메서드가 호출되는 것입니다.

이는 cChild 객체를 가리키고 있기 때문입니다. 따라서 parent 클래스의 draw() 메서드 내부에서의 draw(); 역시 Child 클래스의 draw() 메서드가 호출되는 것입니다.

이것이 바로 동적 바인딩의 특성 때문에 발생하는 현상입니다. 실제 호출되는 메서드는 변수의 타입이 아닌 객체의 실제 타입에 따라 결정된다는 다형성의 핵심 원리에 의한 것입니다.

GPT4 답변

자바의 동적 메소드 디스패치(dynamic method dispatch) 개념에 근거합니다. 자바에서 객체 지향의 다형성은 실행 시점(runtime)에 어떤 메소드를 호출할 것인가를 결정합니다. 이것은 컴파일 시점이 아닌 객체의 실제 타입을 기반으로 합니다.

parent 클래스의 draw() 메서드 내에서 draw()를 호출하더라도, 이 호출은 컴파일 시점에서는 parent 클래스의 draw() 메서드를 호출하는 것처럼 보이지만, 실행 시점에는 실제 객체의 타입을 확인하여 해당 타입의 오버라이드된 메소드를 호출합니다.

예를 들어, parent c = new Child(); 라인에서 cparent 타입의 참조 변수지만, 실제로 가리키는 객체는 Child 클래스의 인스턴스입니다. 따라서 c.draw() 또는 super.draw()와 같은 메서드 호출은 컴파일 시점에서는 parent 클래스의 메서드를 가리키지만, 실행 시점에는 실제 객체 타입인 Child의 오버라이드된 draw() 메서드를 호출합니다.

이러한 이유로, parent 클래스 안에 있는 draw() 메서드에서 재귀적으로 draw()를 호출하려 하면, 실제로는 Child 클래스에 오버라이드된 draw() 메서드가 호출되는 것이며, 이것은 동적 바인딩의 결과입니다. 이 동적 바인딩은 자바의 다형성을 가능하게 하는 핵심적인 메커니즘 중 하나입니다.

profile
개발취준생

0개의 댓글