2013-01-08 43 views
1

代碼:如果我對輸出的解釋是正確的

class TestA { 
    public void foo(String... strings) { 
     System.out.println("TestA::foo"); 
    } 

    public void bar(String a){ 
     System.out.println("TestA::bar"); 
    } 
} 

class TestB extends TestA { 
    public void foo(String strings) { 
     System.out.println("TestB::foo"); 
    } 

    public void bar(String a){ 
     System.out.println("TestB::bar"); 
    } 

    public static void main(String[] args) { 
     TestA a = new TestB(); 
     a.foo("foo"); 
     a.bar("bar"); 
    } 
} 

輸出是

TestA::foo 
TestB::bar 

所以B::bar無效,B::foo過載,當一個函數被重載,它的數據類型參考不關心它指向的對象的類型。我對嗎?

回答

1

當函數被重載時,引用的數據類型並不關心它所指向的對象的類型。我對嗎?

是的。

重載是編譯時綁定,當時只有引用的類型是已知的。雖然重寫是運行時綁定,並根據對象的類型執行調用。

+0

@TedHopp:我寫道:'重寫是運行時綁定'。 – Azodious

+0

好吧,我顯然太困了,以至於無法保持所有事情的順利。評論已刪除。 –

+0

@TedHopp :-) ... – Azodious

1

我不知道您的分析是什麼,但這裏是我看到的:

  • TestA.bar(String)TestB.bar(String)
  • TestA.foo(String...)覆蓋由TestB繼承,然後在TestBTestB.foo(String)
超載

但是,因爲編譯器不知道a.foo("foo")正在調用TestB ob ject,它不知道超載。因此它將它編譯爲一個帶有簽名foo(String...)的方法的調用。如果它知道aTestB,它將綁定到foo(String),因爲它更接近匹配(不需要轉換爲數組參數)。

+0

實際上你提到的情況下輸出是不同的。 –

+0

@IanMcGrath - Ack。我在測試程序中看到一個錯字。我會編輯我的答案。 –

2

TestB類繼承TestA,並且它已經重寫了bar方法和重載的foo方法,在編譯TestA時有一個TestB的引用,所以重載的方法不會被執行,但是如果被重載的bar方法a調用重寫的方法在運行時完成。因爲重載的方法在編譯時加載並在運行時重載方法。