[英]Is this still polymorphism?
編碼時,我對多態性有一個有趣的疑問,我無法理解這個問題的解決方案。
public class Animal {
public void getLegs() {
SOP("4 legs");
}
}
public class Kangaroo extends Animal {
public void getLegs() {
SOP("2 legs");
}
public static void main(String[] args) {
Animal a = new Kangaroo(); // without changing this how can I get Animal getLegs
SOP(a.getLegs()); // Important Line
}
}
現在如果我想調用Animal
的getLegs
方法,我該怎么辦? 可能嗎? 它仍然是多態的嗎?
是的,它是展示多態性的最基本形式。
基本上你正在處理一個名為a
的Animal
。 當你調用a.getLegs()
你的代碼不會綁定到Animal
的getLegs()
實現,而是綁定到getLegs()
中最低的子類實現Kangraoo()
。
如果Animal
有一個實現,它被稱為子類實現隱藏 。 如果Animal
沒有實現,那么就不可能構建Animal
的獨立類,因為它們缺少所有必需方法的實現,並且在這種情況下, Animal
被認為是一個抽象類(一個無法構造的類)直接,但只能由它的子類構造。
如果你真的想為Animal調用你的方法,並且你可以使用靜態方法,你可以使用隱藏而不是覆蓋。
它的工作原理如下:僅對於靜態方法,被調用的方法是與聲明的類型相關的方法,而不是對象實例。 換句話說,它遵循類,因為該方法是類方法,而不是實例方法。
一個例子,改編自這個頁面 :
public class Animal {
public static void testClassMethod() {
System.out.println("The class" + " method in Animal.");
}
public void testInstanceMethod() {
System.out.println("The instance " + " method in Animal.");
}
}
public class Kangaroo extends Animal {
public static void testClassMethod() {
System.out.println("The class method" + " in Kangaroo.");
}
public void testInstanceMethod() {
System.out.println("The instance method" + " in Kangaroo.");
}
public static void main(String[] args) {
Kangaroo myRoo = new Kangaroo();
Animal myAnimal = myRoo;
myRoo.testInstanceMethod();
myAnimal.testInstanceMethod();
Kangaroo.testClassMethod();
Animal.testClassMethod();
}
}
結果將是(注意第3和第4行,而不是第1和第2行):
The instance method in Kangaroo.
The instance method in Kangaroo.
The class method in Kangaroo.
The class method in Animal.
在Java中,無法訪問Animal的實現。 它將永遠返回袋鼠的版本。
(注意在C# 中可以通過用“new”標記重寫方法,但它是一個相當專業的用例)。
訪問似乎是Animal的東西,但獲得Kangaroo指定的行為正是多態性的原因 - 子對象在父對象所在的任何地方被替換的能力。
通常,您不希望讓調用代碼知道繼承層次結構,因為這會將代碼緊密地耦合在一起。 如果你真的需要訪問Animal的這種方法的實現,它表明你的設計可能是錯誤的。
現在如果我想調用Animal的getLegs方法,我該怎么辦? 可能嗎?
如果要訪問被覆蓋的方法 - 這與多態性相矛盾 - 您可以使用反射。 從Animal
的類中獲取getLegs
方法,然后在Kangaroo對象上調用它。 但是,這是一個黑客,而不是你在常規程序中做的事情。
SOP( Animal.class.getMethod("getLegs").invoke(a) );
多態性的精神是執行在運行時決定的不同代碼。 為了更清楚,我會稍微修改你的代碼。
public class Animal {
public void getLegs(){
SOP('4 legs');
}
}
public class Kangaroo extends Animal{
public void getLegs(){
SOP('2 legs');
}
public static void main(String[] args){
Animal a = new Kangaroo(); //without changing this how can I get Animal getLegs
Kangaroo kng= new Kangaroo ();
Animal an = new Animal();
SOP(a.getLegs()); // Kangaroo's version is called
SOP(kng.getLegs()); //Again, Kangaroo's version is called
SOP(an.getLegs()); //Animal version is called
}
}
是的,正如所有人說你不能從你的行中調用動物Animal a = new Kangaroo();
..as none都不想這樣做。 相反,他會直接寫。 Animal a = new Animal();
..
所以最后是決定調用哪種方法的對象而不是referance
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.