彼の本有効なJavaで、Joshua Blochは、派生クラスがチェックにフィールドを追加するときにequals()
の契約で発生する落とし穴について書いています。通常、これは対称性を破るでしょうが、 "はの場合、equals規約に違反することなく抽象クラスのサブクラスに値コンポーネントを追加します"と述べています。抽象クラスから派生した場合のequals()の継承方法
明示的には抽象クラスのインスタンスが存在しない可能性があるので、これは当てはまります。したがって、違反する対称性はありません。しかし、他のサブクラスはどうですか?私は、同じ色の列と、各クラスの1つのインスタンスを作成すると、equals()
の対称性が破壊され
public abstract class Vehicle {
private final String color;
public Vehicle(String color) {
this.color = color;
}
public String getColor() {
return color;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Vehicle)) return false;
Vehicle that = (Vehicle) o;
return color.equals(that.color);
}
}
public class Bicycle extends Vehicle {
public Bicycle(String color) {
super(color);
}
}
public class Car extends Vehicle {
private final String model;
public Car(String color, String model) {
super(color);
this.model = model;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Car)) return false;
Car that = (Car) o;
return getColor().equals(that.getColor()) && model.equals(that.model);
}
}
:私は意図的に短いコードを維持するためにハッシュコードの実装及びヌルチェックを省略し、本実施例を書い
Bicycle bicycle = new Bicycle("blue");
Car car = new Car("blue", "Mercedes");
bicycle.equals(car) <- true
car.equals(bicycle) <- false
これを処理する方法がわかりません。 equals()
を抽象クラスの抽象クラスとして宣言して、サブクラスでの実装を強制しますか?しかし、抽象クラスではequals()
をまったく宣言しないと同じ効果が得られます。
「o」が「o instanceof Car」の「自転車」のインスタンスである場合はどうなりますか? – Hannes
これは誤りです。問題は、抽象スーパークラスの 'equals()'メソッドで 'Car'インスタンスがチェックされるときのもう一つの方向です。 –
「あなたが同じ色の文字列を持つ各クラスのインスタンスを1つ作成すると、equals()の対称性が壊れます。」 – wero