2

継承、インターフェース、ポリモーフィズムを概念的に理解するために、物事をテストするためのクラスをいくつか作成しました。私が得ている結果は、私が期待したものではありません。コードは次のとおりです。

public class Animal implements Comparable{
//Animal constructor & methods
public int compareTo(Object arg0){System.out.println("Animal.compareTo");}
}

public class Bear extends Animal{
//Bear constructor & methods
}

public class PolarBear extends Bear implements Comparable{
//PolarBear constructor & methods
public int compareTo(Object arg0) {System.out.println("PolarBear.compareTo");

Comparableを再度実装できないというエラーは発生しません。しかし、私のテストでは、PolarBearがAnimalのcompareToを継承する必要がある場合でも、PolarBearを作成するとAnimalのcompareToメソッドに戻ることができません。私は以下をテストしました:

Animal bobo = new PolarBear();
bobo.compareTo(null);
((PolarBear) bobo).compareTo(null);
((Animal)bobo).compareTo(null);
((Comparable) bobo).compareTo(null);    

そしてそれらのそれぞれは印刷しました:

 PolarBear.compareTo

にアクセスする方法はありますAnimalcompareToPolarBear論理的には、動物の品質と品質を比較できるようにしたいと思いませんPolarBearか?

4

4 に答える 4

7

boboオブジェクトをPolarBear、、、Animalまたはにキャストするかどうかは関係ありません。オブジェクトComparableの実行時型は、次のPolarBearようにインスタンス化してから常になります。

Animal bobo = new PolarBear();

したがって、呼び出すたび.compareTo(wtv)に実装が呼び出されますPolarBear

これがポリモーフィズムです。遅延バインディングについて読んでください。これが、Javaでpolymorphishmを実装する方法です。

compareTo(wtv)親クラスのメソッドを呼び出したい場合はsuper.compareTo(wtv)、他のサブクラスのメソッド内で行う必要があります。

于 2013-01-09T16:47:12.860 に答える
2

compareTo と継承は、一般的に扱いにくいビジネスです。理論的には、Comparable 具象スーパークラスのサブクラスを持つと、Comparable 契約が破られます。たとえば、フィールド a1 と a1 をチェックして他の A と比較するスーパークラス A があるとします。次に、追加のフィールド b1 を持つサブクラス B を追加します。 あなたの質問と同じことをしませんが、anA.compareTo(aB)a1とa2で比較します-次のようなことを行うことにより、サブクラス自体からのみcompareToの動物バージョンを呼び出すことができます((A)aB).compareTo(anA)

super.compareTo(<something>)

メソッドをオーバーライドしたため、「外部」からではありません。オーバーライドしたばかりのメソッドと同じ「コントラクト」を外部に対して維持するのは、ユーザーの責任です。

于 2013-01-09T16:46:13.473 に答える
1

PolarBear 内からいつでもsuper.compareTo(arg0)を呼び出して、Animal.compareTo に配置されたロジックを呼び出すことができます。

于 2013-01-09T16:43:50.503 に答える
0

とても簡単です。基になるオブジェクトはPolarBearクラスであり、オブジェクトのインターフェイス(オブジェクトの参照を保持するために使用されるクラス)を毎回変更しています。

JVMは、コンパイル時にインターフェイス(オブジェクトの参照を保持するために使用されるクラス)のメソッドが存在するかどうかをチェックしますが、Child(PolearBear)にはそのメソッドがあるため、実行時にバインドが行われるため、常にそれが実行されます。

親メソッドを呼び出すには、super.compareTo()を使用します。

于 2013-01-09T16:58:46.510 に答える