2015-09-15 41 views
0

代碼:由於編譯器基於引用類型調用方法,而不是實際的對象類型,爲什麼調用該對象的方法?

public class X 
{ 
    public void methodA() //Base class method 
    { 
     System.out.println ("hello, I'm methodA of class X"); 
    } 
} 

public class Y extends X 
{ 
    public void methodA() //Derived Class method 
    { 
     System.out.println ("hello, I'm methodA of class Y"); 
    } 
} 

public class Z 
{ 
    public static void main (String args []) { 
     X obj1 = new X(); // Reference and object X 
     X obj2 = new Y(); // X reference but Y object 
     obj1.methodA(); 
     obj2.methodA(); 
    } 
} 

輸出:

hello, I'm methodA of class X 
hello, I'm methodA of class Y 

從對象類型的方法獲取調用,而不是引用類型。兩條線都不應該是這樣嗎?

hello, I'm methodA of class X 
hello, I'm methodA of class X 
+1

也許你的第一個假設是錯誤的...這是有趣的,考慮你是正確標記你的問題[標籤:多態性] – dotvav

+0

@HovercraftFullOfEels我不好。我的意思是編譯器決定我們是否可以調用該方法。 –

回答

1

編譯器選擇最方法調用(在具有相同名稱的所有的重載方法,其可用於針對該方法被稱爲變量的編譯時間類型)相匹配的方法簽名。

但是,實際執行的方法僅在運行時根據調用該方法的變量引用的實例的運行時類型來確定。這是壓倒一切的方法。「

在方法重寫(在運行時完成)時,您可能會混淆方法重載(在編譯時完成)。

1

很明顯。當你在子類中再次聲明methodA()時。超類的methodA()被覆蓋。所以現在只要你打電話給methodA(),子類的methodA()就會被調用。

X obj1 = new Y(); 
Y obj2 = new Y(); 
obj1.methodA(); 
((X)obj2).methodA(); 

兩者都會調用overriden方法。

在java中,沒有辦法調用被覆蓋的方法。只有事情可以做調用父類的方法,而重寫的功能是這樣的:

public void methodA() { //Derived Class method 
    super.methodA(); 
    // add other stuff if you want here 
} 
1

Java使用「早期綁定」,即在編譯過程中一個名稱的方法相關聯,以及「動態調度」,選擇方法在運行時與對象類型關聯最密切的實現。 Java在綁定時使用引用類型,因爲在編譯期間可能不知道對象的類型。

X obj1 = new X(); // obj1 is bound to X and of type X 
if (i == 0) { 
    obj1 = new Y(); // obj1 is still bound to X, but now of type Y 
} 
obj1.methodA();  
// Due to early binding, a compiler error occurs if X doesn't contain methodA 
// Due to dynamic dispatch, if it exists, the methodA of obj1's type will be used. Otherwise the closest superclass's methodA will be used. 
相關問題