2

コーディング中に、ポリモーフィズムについて興味深い疑問を抱きましたが、これに対する解決策を理解できませんでした。

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
  }
}

getLegsのメソッドを呼び出したい場合Animal、どうすればよいですか? 出来ますか?それはまだポリモーフィズムですか?

4

5 に答える 5

3

はい、これはポリモーフィズムを示す最も基本的な形式です。

Animal基本的に、名前付きを扱っていますaa.getLegs()コードを呼び出すと、 getLegs()inの実装にバインドされずAnimal、最下位のサブクラスの実装であるgetLegs()inにバインドされKangraoo()ます。

に実装がある場合、それはサブクラスの実装によって隠さAnimalれていると言われます。実装がない場合、必要なすべてのメソッドの実装がないため、のスタンドアロン クラスを構築することはできません。このような状況では、抽象クラス (直接構築することはできませんが、そのサブクラスによってのみ構築できます)。AnimalAnimalAnimal

于 2012-06-19T15:57:51.743 に答える
2

Animal のメソッドを本当に呼び出したい場合で、静的メソッドを使用できる場合は、オーバーライドの代わりに非表示を使用できます。

次のように動作します: 静的メソッドの場合のみ、呼び出されるメソッドは、オブジェクト インスタンスではなく、宣言された typeに関連するメソッドです。つまり、メソッドはインスタンス メソッドではなくクラス メソッドであるため、クラスに従います。

このページから改作された例:

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();
  }
}

結果は次のようになります (1 行目と 2 行目ではなく、3 行目と 4 行目に注意してください)。

The instance method in Kangaroo.
The instance method in Kangaroo.
The class method in Kangaroo.
The class method in Animal.
于 2012-06-19T16:15:38.353 に答える
1

Java では、Animal の実装にアクセスすることはできません。常にカンガルーのバージョンを返します。

(C# では、オーバーライド メソッドに「new」のタグを付けることで可能ですが、これはかなり特殊なユース ケースです)。

Animal のように見えるものにアクセスし、Kangaroo によって指定された動作を取得することは、まさにポリモーフィズムです。つまり、子オブジェクトが、その親が期待される場所であればどこでも置き換えられる能力です。

一般に、呼び出し元のコードに継承階層を認識させたくないでしょう。これは、コードを密結合するためです。このメソッドのアニマルの実装に本当にアクセスする必要がある場合は、設計がおそらく間違っていることを示唆しています。

于 2012-06-19T16:01:43.030 に答える
1

Animal の getLegs メソッドを呼び出すにはどうすればよいでしょうか? 出来ますか?

オーバーライドされたメソッド (ポリモーフィズムと矛盾する) にアクセスする場合は、リフレクションを使用できます。getLegsのクラスからメソッドを取得Animalし、Kangaroo オブジェクトで呼び出します。ただし、これはハックであり、通常のプログラムで行うことではありません。

SOP( Animal.class.getMethod("getLegs").invoke(a) );
于 2012-06-19T16:04:00.220 に答える
1

ポリモーフィズムの精神は、実行時に決定された異なるコードを実行することです。より明確にするために、コードを少し変更します。

    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();..誰もやりたくないからです。むしろ彼は直接書くでしょう。Animal a = new Animal();..

したがって、最終的にどのメソッドが呼び出されるかを決定するのは参照ではなくオブジェクトです

于 2012-06-19T16:18:33.827 に答える