[英]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
由於b1
是Base
,而不是Child
因此對b1.subtract()
的調用永遠不會起作用,因為b1
沒有名為subtract()
的方法。
編譯失敗,因為BASE類沒有減法方法.B1的類型為base。
subtract()方法不是Base類接口的一部分,這就是它失敗的原因。
Java是嚴格靜態類型的語言。 父類不能指向子類方法。 在編譯時,Java編譯器使用閉包原理並查看Base類中是否有減法方法,因為在這種情況下沒有減法方法會導致編譯時錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.