私は単純な基本クラスを持っていますが、これは後で多くの個別のクラスによって拡張され、新しいフィールドを導入する可能性があります。私は基底クラスでequalsメソッドを定義しましたが、いくつかのサブクラスではそれをオーバーライドしました。定義をベース/サブクラスに混在させても問題ありませんか?私の場合は、同じフィールドをチェックするコードの重複を避けることでした。基本クラスとサブクラスのJava等価メソッド
答えて
Angelika Langerの"Implementing equals() To Allow Mixed-Type Comparison"をご覧ください。ここ
はいくつかの問題と可能な解決策の簡単な説明である:
それが対称である:null以外の参照値xとyについて
ザ契約は(とりわけ)と言うに等しいですy.equals(x)がtrueを返す場合に限り、x.equals(y)はtrueを返す必要があります。あなたのサブクラスは、新しいフィールドを導入されていて、このサブクラスのオブジェクトへの基底クラス(または等号をオーバーライドしていない別のサブクラス)のオブジェクトを比較している場合は、問題を得るかもしれない意味
。
は、クラスの比較でinstanceof
-checkを交換してください:あなたは
BaseClass baseClass = new BaseClass();
BadSubClass subClass = new BadSubClass();
System.out.println(baseClass.equals(subClass)); // prints 'true'
System.out.println(subClass.equals(baseClass)); // prints 'false'
が可能な解決策を得るため
class BaseClass {
private int field1 = 0;
@Override
public boolean equals(Object obj) {
if (obj instanceof BaseClass) {
return field1 == ((BaseClass) obj).field1;
}
return false;
}
}
class BadSubClass extends BaseClass {
private int field2 = 0;
@Override
public boolean equals(Object obj) {
if (obj instanceof BadSubClass) {
return super.equals(obj)
&& field2 == ((BadSubClass) obj).field2;
}
return false;
}
}
:
はは、次の手順を実行しないでください
をobj != null && obj.getClass() == getClass()
BaseClass
のオブジェクトは、どのサブクラスのオブジェクトとも決して等しくありません。あなたがequals
方法の@Override
せずに別のを作成した場合
は、2-objectsは(BaseClass.equals
チェックが決定した場合そう)箱から出して、しかしに等しくなることはありません-object互いに等しくすることができますBaseClass
-オブジェクト。
class BaseClass {
private int field1 = 0;
@Override
public boolean equals(Object obj) {
if (obj != null && obj.getClass() == getClass()) {
return field1 == ((BaseClass) obj).field1;
}
return false;
}
}
class GoodSubClass extends BaseClass {
private int field2 = 0;
@Override
public boolean equals(Object obj) {
if (obj instanceof GoodSubClass) {
return super.equals(obj) && field2 == ((GoodSubClass) obj).field2;
}
return false;
}
}
より高度な問題とその解決策のために、上記の記事を参照してください:次のように
良い実装がある可能性があります。
Angelika Langerの記事リンクありがとう。これはLiskov置換原則に違反しますが、AFAIK。 Joshua Blockの "Effective Java"をもう一度見てください。 (私はまだ完全な記事を読んでいない。) – Puce
o.getClass()の何が問題なの?= this.getClass()? – Mukul
@Mukul実際には、追加のチェックをしなくても、すべてを壊すことなく 'super.equals()'を呼び出すことができれば、equalsメソッドをオーバーライドする必要がなくなるので、もっと良いと思います。私はちょうど編集に従ってそれを提出した – Qw3ry
eqauls()とhashcode()の契約に従う限り、完璧に問題はないと思います。
は、あなたがコードの重複
public class BaseClass {
public boolean equals(BaseClass other) {
return (other.getBlahblah() == this.Blahblah && .....);
}
}
public class DerivedClass extends BaseClass {
public boolean equals(DerivedClass other) {
return (super(other) && other.getNewAttribute() == this.NewAttribute.....);
}
}
+1を定義すると言っていた。 1つのノート - それは有効なJavaコードではない、それを修正するためにクールだろう(私はそれが例として擬似コードかもしれないことを理解する)。 –
ありがとうございます。私はちょうどほとんどのものをチェックすることなくそれをマッシュアウトした。私はJavaをやっていて、内部で他の構文や呼び出しをしていたにちがいありません。 – Grambot
オブジェクトの等価をオーバーライドするのではなく、ブロッキへの逆参照のために –
かなり有効なアプローチの必要性を防ぐために拡張しているクラスのメソッドを呼び出すためにsuper()
メソッドを使用することができます。問題はサブクラスの1つにありますは、その親によってバインドされているequalsの定義を保持する必要があります。そうでなければ、実行時にいくつかの非常にユニークなシナリオが発生する可能性のある関数equalsが壊れています。
は、それはJava
がしたsuper
class
ようにequals(Object obj)
とhashCode()
メソッドの実装を提供するために最適です。我々はJavaが基本クラスjava.lang.ObjectのhashCode() and equals(Object obj)
メソッドの実装を提供していることを知っており、必要なときはoverride
をclass
に入れています。
以下はすべてのケースを処理するわけではありませんが、かなり実用的であることがわかりました。私はSuperClassとSubClassの両方を使っているときにこれを何度も使ってきました。私はそれらを相互比較したくないですが、SubClassのためにすべてのSuperClass equals()を再実装したくありません。これは、ハンドル:
-
==偽
- Superclass.equals(サブクラス)==偽
コード例
// implement both strict and asymmetric equality
class SuperClass {
public int f1;
public boolean looseEquals(Object o) {
if (!(o instanceof SuperClass)) return false;
SuperClass other = (SuperClass)o;
return f1 == other.f1;
}
@Override public boolean equals(Object o) {
return looseEquals(o) && this.getClass() == o.getClass();
}
}
class SubClass extends SuperClass {
public int f2;
@Override public boolean looseEquals(Object o) {
if (!super.looseEquals(o)) return false;
if (!(o instanceof SubClass)) return false;
SubClass other = (SubClass)o;
return f2 == other.f2;
}
// no need to override equals()
}
- 1. OWLの等価クラスとサブクラスの混合
- 2. Pythonクラス:基本クラスのメソッドでの変数サブクラスの作成
- 3. 基本クラスのみのメソッド?
- 4. ListViewのサブクラス:基本的なJavaのQ
- 5. Cで基本クラスのメソッド
- 6. サブクラス 'プロパティから基本クラス'コンストラクタにアクセス
- 7. opencv Javaビルドでのimshowの等価メソッド
- 8. 抽象基本クラスとそのサブクラスのWCF DataContract
- 9. データベースの抽象基本クラスとサブクラスをモデル化します
- 10. ブラウザ間での等価性のための基本ブロック?
- 11. Pythonのクラスの継承:はAttributeError:「[サブクラス]」オブジェクトは、私は、次の基本クラスとサブクラス持って何の属性「XXX」
- 12. 基本クラスモジュールの任意のメソッドを使用するサブクラスには?
- 13. メソッド "moveFirst()" ADODB、PDO等価
- 14. 基本クラスでより一般的なメソッドがある場合、基本クラスのメソッドをオーバーライドする方法は?
- 15. 基本的なJava再帰メソッド
- 16. テンプレートの基本クラスを基本クラスの引数として使用するクラス
- 17. 推移閉包と等価クラス
- 18. 基本クラスのオブジェクトの派生クラスの呼び出しメソッド
- 19. サブクラスは基本クラスのプロパティの情報を必要とします
- 20. 継承:サブクラスの基本クラスフィールドへのアクセス
- 21. アクティビティ基本クラス?
- 22. は、基本クラス
- 23. どのように基底クラスのメソッドをオーバーライドして、私の基本クラスで
- 24. 基本クラスのイベント
- 25. Pythonのクラス(基本)
- 26. Java:等価性を判断するための外部クラス?
- 27. Java - 基本マルチスレッド
- 28. 基本ディープコピー、Java
- 29. Javaの基本タイミング
- 30. C#基本クラスのメソッド呼び出しで使用される汎用パラメータは、基本クラス - 非導出です。(
ミキシング定義の意味を説明できますか?ありがとう。 – tjg184
基本クラスに1つの定義があります。これはオーバーライドされる場合とされない場合があります。私は "基本クラスの混合アプローチは、スーパークラスを定義するためのアドバイスのためにサブクラス対" – Bober02