表題の通り、lombokの@EqualsAndHashCode
で実装されるequals()
メソッドはリスコフの置換原則を満たしていないと思い質問させていただきました。
特に、equals()
メソッドの中でも、canEqual()
がリスコフの置換原則を完全に破棄していると思います。例えば、@EqualsAndHashCode
が使われた、下記のようなName
クラスとこのクラスを継承したFullName
クラスがあるとします。
@EqualsAndHashCode @RequiredArgsConstructor @Getter public class Name { private final String firstName; } @Getter @RequiredArgsConstructor public class FullName extends Name { private final String LastName; }
また、この場合のequals()
メソッドとcanEqual()
メソッドは下記のようになると思います。
public class Name { ... @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Name)) return false; Name other = (Name) o; if (!other.canEqual((Object)this)) return false; if (this.getFirstName() == null ? other.getFirstName() != null : !this.getFirstName().equals(other.getFirstName())) return false; return true; } protected boolean canEqual(Object other) { return other instanceof Name; } }
このとき、equalsメソッドで成り立たなければならない推移性や対称性等など条件は満たすと思います。
しかしながら、下記のようにHashSetを使う場合ではリスコフの置換原則は成り立たない気がします。(親クラスと子クラスが別々の挙動をする)
public static void main(String[] args) { Name name1 = new Name("山田"); Name name2 = new FullName("山田", "太郎"); Set<Name> set = new HashSet(); set.add(new Name("山田")); System.out.println(set.contain(name1)); // true System.out.println(set.contain(name2)); //false(trueとなることが、リスコフの置換原則を満たしている) }
これは、推移性や対称性とリスコフの置換原則を上記のようなケースでは両立させることは不可能なので、lombokは諦めているという認識であっているでしょうか?
回答2件
あなたの回答
tips
プレビュー