我知道下面問題的答案是陳述句 1 和陳述句 3。但我無法解釋為什么陳述句 2 不起作用。有人可以啟發我嗎?謝謝。
考慮以下類定義。
public class Animal
{
public void eat()
{ /* implementation not shown */ }
// constructors and other methods not shown
}
public class Tiger extends Animal
{
public void roar()
{ /* implementation not shown */ }
// constructors and other methods not shown
}
假設以下宣告出現在客戶端類中。
Animal a = new Tiger();
以下哪個陳述句可以正確編譯?
I.a.eat();
二、a.roar();
三、((虎) a).roar();
我假設將 'a' 實體化為 new Tiger() 將允許 'a' 訪問 roar() 方法。但我顯然錯了。我想我沒有很好地理解問題的多型性。
uj5u.com熱心網友回復:
因為“a”被稱為動物。就代碼而言,它只能直接訪問 Animal 定義的方法。您的第三行有效,因為您將其顯式轉換為 Tiger 從而更改背景關系并使其能夠訪問 Tiger 方法,只要沒有 ClassCastException。
應該設計這樣一個類的方式是讓 Animal 成為一個抽象類,然后給它一個抽象的“speak”方法,例如:
public abstract class Animal {
public abstract void speak();
}
然后在你的老虎班
public class Tiger extends Animal {
public void speak() {
System.out.println("Roar.");
}
}
然后你可以打電話
Animal a = new Tiger();
a.speak();
然后你也可以創造一只狗
public class Dog extends Animal {
public void speak() {
System.out.println("Woof.");
}
}
Animal a = new Dog();
a.speak();
uj5u.com熱心網友回復:
關于 SO 有很多這樣的問題,答案總是 Java 認為靜態型別是Animal這樣的,因此對方法的呼叫Tiger不會編譯,但我認為多說一點為什么會有用。
考慮:
Animal a = new Tiger();
a.roar();
很容易看出,雖然a被宣告為 an Animal,但它只能Tiger在呼叫時參考 a roar()。但是考慮一個更復雜的例子:
Animal a = new Tiger();
// . . .
if (zoo.getType() == ZooType.TROPICAL) {
a = new Toucan();
}
for (Condition c : getMeteorologicalConditions()) {
// . . .
if (season == Seasons.WINTER) {
a = new Penguin();
}
// . . .
}
// . . .
a.roar();
在這里打電話安全roar()嗎?什么時候安全?編譯器能否在編譯時靜態地證明,那a將永遠是一個Tiger?也許可以通過某種方式證明,這個代碼永遠不會被呼叫用于熱帶動物園,或者在冬天(至少在有任何適用的氣象條件的情況下;否則,回圈將執行零次并且冬天無關緊要)。但是你能想象證明這一點的復雜性嗎?
編譯器甚至沒有嘗試。當你告訴它a是一個Animal時,它會說,“好吧,它可以容納任何型別的動物。” 它只允許你呼叫對所有動物都有效的方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/453142.html
下一篇:繼承的靜態變數
