簡體   English   中英

由於編譯器基於引用類型而不是實際對象類型調用方法,為什么調用該對象的方法?

[英]Since the compiler calls a method based on the reference type and not the actual object type, why does the object's method get called?

碼:

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

編譯器選擇與方法調用最匹配的方法簽名(在所有具有相同名稱的重載方法中,這些方法可用於為其調用方法的變量的編譯時類型)。

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

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

這很明顯。 當您再次在子類中聲明methodA()時。 超類的methodA()被覆蓋。 因此,現在無論何時調用methodA() ,子類的methodA()都會被調用。

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

兩者都將調用重寫的方法。

在Java中,無法調用被覆蓋的方法。 重寫函數時,您只能做的事情來調用超類的方法:

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

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.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM