2014-11-07 2 views
2

Java에서 메서드 재정의 및 오버로드가 어떻게 작동하는지 기본적인 지식을 가지고 있습니다. 하지만 내 질문은 왜 컴파일러는 인수의 컴파일 유형을 기반으로 가장 구체적인 방법을 검색합니까? 즉, 메소드 오버로드의 경우 객체 유형이 아닌 참조 유형을 기반으로 검색하는 이유는 무엇입니까?Java에서 오버로드 된 메소드에서 다형성이 작동하지 않는 이유는 무엇입니까?

class Base { } 

class Derived extends Base { } 

class Test { 

    void foo(Base thing) { System.out.println("foo(Base)"); } 
    void foo(Derived thing) { System.out.println("foo(Derived)"); } 

    public static void main(String[] args) { 
     Test tester = new Test(); 
     Base base = new Base(); 
     tester.foo(base);// 1st call 
     base = new Derived(); 
     tester.foo(base); // 2nd call 
     tester.foo(new Derived()); // 3rd call 
    } 
} 

실제 출력 아래의 예는

1st call: foo(Base) 

2nd call: foo(Base) 

3rd call: foo(Derived) 

출력 내가 기대했다

점검

1st call: foo(Base) 

2nd call: foo(Derived) 

3rd call: foo(Derived) 
+0

[여기에 삽입하십시오.]가 중복되었습니다. 오버로딩은 변수의 정적 유형, 즉 # 1과 # 2에서 모두 'Base base'를 기반으로하는 컴파일 타임입니다. – zapl

+0

이 경우 다형성과 관련하여 어떤 방법이 있습니까?이 메소드는 단순히 전달 된 내용이나 구체적으로 인쇄되는 객체 유형을 전달합니다. –

답변

1

1)과로드 입니다 실행에 시간을 컴파일 방법을 정의 예에서 발생 컴파일 시간에 결정했다.
2) 런타임에 기본 클래스 개체에 파생 클래스 개체 참조를 할당합니다.
3) 그래서 컴파일 타임에 당신의 기본 클래스 객체를 참조하는 것이 미래에 (런타임에) 분명히 알려지지 않습니다. 자체 클래스의 컴파일러를 사용하면 다음과 같은 Bass 유일한 값을 변수 유형을 정의 할 때

0
당신은 기억해야

, 그것은 저장할 수있는 오버로드 방법의 경우 참조의 유형에 보이는 왜
4)이 이유입니다 Derived과 같은 자체로부터 파생 된

변수에 변수 유형이 지정되면 변경할 수 없습니다.

한 가지 방법은 생각하기 :

class Bass { 
String field1; 

} 

Derived 클래스 상점 추가 필드 "

class Derived extends Bass { 
String field2; 

} 

을 말 :

Bass 클래스가 저장하는 하나 개의 필드 값이 말해 이제 저음 인스턴스를 만듭니다.

Bass bass = new Base(); 

개체에서 field1 값에 액세스 할 수 있습니다.

지금 당신은 당신이 다음과 같이 말한다 :

bass = new Derived(); 

당신은 여전히 ​​개체에서 field1 값에 액세스 할 수 있습니다. 그러나 저음 인스턴스는이 값을 저장하지 않으므로 field2 값에 액세스 할 수 없습니다. 그것은 그 구조를 따르지 않습니다.

변수 유형을 파생 클래스 중 하나와 같게 설정하면 원래 변수 유형이 변경되지 않는 이유를 이해하는 데 도움이되기를 바랍니다.