簡體   English   中英

運行時/編譯時多態

[英]runtime/compile time polymorphism

在下面的代碼中,為什么b1.subtract()失敗。 請解釋一下原因,即調用該方法時JVM中會發生什么。

class Base {

public void add() {
System.out.println("Base ADD");
}

}

class Child extends Base {

public void add(){
System.out.println("Child ADD");
}

public void subtract() {
System.out.println("Child Subtract");
}

}

class MainClass {

public static void main(String args[]) {

Base b1 = new Base();
Base b2 = new Child();

Child b3 = new Child();

b1.add();

b2.subtract(); // ?????????**previously it was b1.subtract and its wrong 

b2.add();
b3.subtract();

}

}

我假設,從標題來看,代碼實際上是b2.subtract() 跟着那個:

雖然b2目前是Child的一個實例,但很容易看出在你的代碼中它總是一個Child的實例,Java是靜態類型的,所以不能讓你使用實際類的方法,只是聲明的類。

考慮這個例子:

Base b2 = Math.random() > 0.5 ? new Base() : new Child();
b2.subtract();

現在在編譯時不可能告訴b2實際上是什么實例,所以你顯然不可能調用Child中的任何方法(因為b2可能只是一個普通的Base!)。 對於像你的例子這樣的例子來說,這是一個例外是沒有意義的,因為它會引起很多混亂,這些案例可以很容易地糾正到原樣正常工作(通過將聲明的類型更改為Child)不是基地)。

JVM中沒有任何事情發生,因為代碼無法編譯。 編譯器無法解析方法b1.subtract() ,因為Base沒有此類成員。

該類不編譯! 假設您要檢查實例化子類的基類對象是否有效,答案是肯定的。

    Base b1 = new Base();
    Base b2 = new Child();

    Child b3 = new Child();

    b1.add();

    ((Child) b2).subtract(); // ?????????**

    b2.add();
    b3.subtract();

這將工作,它給出的輸出如下。

Base ADD
Child Subtract
Child ADD
Child Subtract

這就是所謂的運行時多態性。

b1變量的類型為Base 該類沒有subtract()方法,因此無法編譯。

'因為Base沒有減法。

b2和b3已減去'因為它們被定義為Child。

[編輯:]不,等等,b2沒有減法,即使它是用新的Child()定義的,它仍然被聲明為Base。

b1.subtract()的調用可以分解為正在使用的類。

b1 - > Base

subtract() - > Child

由於b1Base ,而不是Child因此對b1.subtract()的調用永遠不會起作用,因為b1沒有名為subtract()的方法。

編譯失敗,因為BASE類沒有減法方法.B1的類型為base。

subtract()方法不是Base類接口的一部分,這就是它失敗的原因。

Java是嚴格靜態類型的語言。 父類不能指向子類方法。 在編譯時,Java編譯器使用閉包原理並查看Base類中是否有減法方法,因為在這種情況下沒有減法方法會導致編譯時錯誤。

暫無
暫無

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

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