簡體   English   中英

這還是多態嗎?

[英]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
  }
}

現在如果我想調用AnimalgetLegs方法,我該怎么辦? 可能嗎? 它仍然是多態的嗎?

是的,它是展示多態性的最基本形式。

基本上你正在處理一個名為aAnimal 當你調用a.getLegs()你的代碼不會綁定到AnimalgetLegs()實現,而是綁定到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.

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