2011-12-21 2 views
0

메서드를 정의하는 클래스 A이 있다고 가정합니다. bar() 메서드는 다른 메서드 foo()을 호출합니다. 그런 다음 AB으로 확장하고 foo()을 재정의하고 bar()을 재정의하지 않습니다 (상속 됨). 이 두 가지 경우에 어느 foo()이 호출되고 있습니까?Java에서의 동적 디스패치

A a = new B(); 
a.bar(); // A or B's foo called? 

B b = new B(); 
b.bar(); // A or B's foo called? 

답변

3

두 가지 모두 B의 foo()를 사용합니다. A는 B가 인스턴스이므로 B의 메소드에 액세스 중입니다. 다음은이 경우의 예를 들면, 인터페이스 등의 (A)의

생각해 새로운 B() 여기서

은 (멋에) 예이다 : http://groovyconsole.appspot.com/script/616002

0

그것은 대한 B의 푸 메소드를 호출 두 경우 모두. java에서 모든 메소드 호출은 동적으로 전달됩니다. 호출 한 참조 또는 컨텍스트에 관계 없습니다. 메소드 호출은 객체 유형을 기반으로합니다.

+1

이 경우 사실을 말하고 있지만 "모든 메서드 호출이 동적으로 전달됩니다."라고주의해야합니다. Java에는 다중 디스패치가 없습니다. 예를 들어 오버로드 된 메서드가있는 경우 전달되는 인수의 런타임 유형에 따라 호출되지 않는 메서드가 호출됩니다. –

+0

메서드가 호출되는 개체의 형식을 기반으로합니다 인수의. – gkamal

0

메서드 호출은 메서드가 호출되는 개체 유형에만 의존하며 호출하는 데 사용되는 참조 형식에는 의존하지 않습니다.

두 경우 모두 B 유형의 오브젝트 메소드를 호출해야하므로 둘 다 B의 foo()를 호출합니다.

class C { 
    public void foo() { 
     System.out.println("foo in C"); 
    } 

    public void bar() { 
     System.out.println("calling foo"); 
     foo(); 
    } 
} 


class B extends C { 
    public void foo() { 
     System.out.println("foo in B"); 
    } 
} 


public class A { 


    public static void main(final String[] args) { 
     C c = new B(); 
     c.bar(); // C or B's foo called? 

     B b = new B(); 
     b.bar(); // C or B's foo called? 

    } 

출력은 : A a = new B();에서

calling foo 
foo in B 
calling foo 
foo in B 
1

B b = new B();

B) (B의 인스턴스 클래스이므로 두 시간 B의 foo에 있습니다 메서드가 호출됩니다.

방법은 자식 클래스에서 재정의되는 경우 (이 경우, B 클래스는) 다음 자식 객체의 인스턴스가 부모 클래스의 그것의 자신의 클래스하지에 존재하는 메소드 호출하기 때문에 (이 경우, 클래스) .