回答編集履歴

3

追記2

2018/02/21 00:41

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -126,7 +126,7 @@
126
126
 
127
127
  こうしておけば
128
128
 
129
- `new Name("太郎").equlas(new FullName("太郎", "")`
129
+ `new FullName("太郎", "").equlas(new Name("太郎"))`
130
130
 
131
131
  といったことを成立させられます。つまりequalsの機能を「変更」するのではなく「拡張」できます。しかしlombokの@EqualsAndHashCodeではそのような「拡張」にはならないとおっしゃりたいのかも知れません。
132
132
 
@@ -141,3 +141,13 @@
141
141
 
142
142
 
143
143
  equalsに期待する機能は普通「インスタンスの値の同一性のチェック」であり前述のように「アプリケーション設計者の設計如何によって独自に決めるもの」のため、フレームワークや言語仕様としてのデフォルトは「派生クラスで拡張するのではなく変更するもの」すなわち「リスコフの置換原則を満たすかどうかの観点には入れないもの」と捉えるのが普通ではないかと思います。
144
+
145
+
146
+
147
+ ---
148
+
149
+ 追記2:上記のコード例はかなりヘンテコです。自然な拡張とは言えませんね。
150
+
151
+ `new Name("太郎").equlas(new FullName("太郎", "日本"))`
152
+
153
+ なんてやると常に成立してしまうからです。equalsは交換則を満たすべきなので、上の例は「中途半端に拡張しようとしたがダメだった例」として捉えてください。equalsを派生で「変更」せずに「拡張」するのはそもそも無理があるということだと思います。おかしな例を挙げてしまいすみませんでした。

2

誤記訂正

2018/02/21 00:41

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -140,4 +140,4 @@
140
140
 
141
141
 
142
142
 
143
- equalsに期待する機能は普通「インスタンスの値の同一性のチェック」であり前述のように派生クラスで意味を拡張するのは「アプリケーション設計者の設計如何によって独自に決めるものであり」フレームワークや言語仕様としてのデフォルトは「派生クラスで拡張するのではなく変更するもの」すなわち「リスコフの置換原則を満たすかどうかの観点には入れないもの」と捉えるのが普通えるとうのが自分の最初の回答の主張です。
143
+ equalsに期待する機能は普通「インスタンスの値の同一性のチェック」であり前述のように「アプリケーション設計者の設計如何によって独自に決めるもの」のため、フレームワークや言語仕様としてのデフォルトは「派生クラスで拡張するのではなく変更するもの」すなわち「リスコフの置換原則を満たすかどうかの観点には入れないもの」と捉えるのが普通ではないかと思いす。

1

追記

2018/02/21 00:30

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -17,3 +17,127 @@
17
17
 
18
18
 
19
19
  普段何気なく感じていることをコメントしただけですので厳密な解釈でもなんでもありません。もし間違ってたらスミマセン。
20
+
21
+
22
+
23
+ ---
24
+
25
+ 追記:回答コメントを受けて
26
+
27
+
28
+
29
+ 質問者さんの主張を正しくとらえることができているかちょっと自信ないですがコメントから以下のように思いました。
30
+
31
+
32
+
33
+ 例えばNameのequalsを派生クラスで「拡張」することも可能で
34
+
35
+
36
+
37
+ ```java
38
+
39
+ class Name {
40
+
41
+ String name;
42
+
43
+
44
+
45
+ Name(String name) { this.name = Objects.requireNonNull(name); }
46
+
47
+
48
+
49
+ @Override public int hashCode() { return name.hashCode(); }
50
+
51
+
52
+
53
+ @Override public boolean equals(Object o) {
54
+
55
+ if (o instanceof Name)
56
+
57
+ return name.equals(((Name)o).name);
58
+
59
+ else
60
+
61
+ return false;
62
+
63
+ }
64
+
65
+ }
66
+
67
+
68
+
69
+ class FullName {
70
+
71
+ String lastName;
72
+
73
+
74
+
75
+ FullName(String firstName, String lastName) {
76
+
77
+ super(firstName);
78
+
79
+ this.lastName = Objects.requireNonNull(lastName);
80
+
81
+ }
82
+
83
+
84
+
85
+ @Override
86
+
87
+ public int hashCode() {
88
+
89
+ if (lastName == null || lastName.isEmpty()) {
90
+
91
+ return super.hashCode();
92
+
93
+ } else {
94
+
95
+ return super.hashCode() ^ lastName.hashCode();
96
+
97
+ }
98
+
99
+ }
100
+
101
+
102
+
103
+ @Override
104
+
105
+ public boolean equals(Object o) {
106
+
107
+ if (lastName.isEmpty())
108
+
109
+ return super.equals(o);
110
+
111
+ else if (o instanceof FullName)
112
+
113
+ return lastName.equals(((FullName)o).lastName) && super.equals(o);
114
+
115
+ else
116
+
117
+ return false;
118
+
119
+ }
120
+
121
+ }
122
+
123
+ ```
124
+
125
+
126
+
127
+ こうしておけば
128
+
129
+ `new Name("太郎").equlas(new FullName("太郎", "")`
130
+
131
+ といったことを成立させられます。つまりequalsの機能を「変更」するのではなく「拡張」できます。しかしlombokの@EqualsAndHashCodeではそのような「拡張」にはならないとおっしゃりたいのかも知れません。
132
+
133
+
134
+
135
+ もしそういう主張ならば「そのとおり」だと思います。
136
+
137
+
138
+
139
+ ただ派生クラスで基底クラスのequals(値の同一性)という性質を拡張したいなら、派生クラスで追加した属性群の状態が「どんな状態の場合に派生クラス独自の状態を持たないと考えるか」を規定せねばなりませんが、それはフレームワークや言語仕様で規定できるような性質のものではなく「アプリケーション設計者の考えによる」と思います。それを例えば「派生クラスの全ての属性値がデフォルトの値を持つ場合」なんて意味付けをしてしまうと「意味があまりないきつすぎる制約」になるのではないでしょうか?
140
+
141
+
142
+
143
+ equalsに期待する機能は普通「インスタンスの値の同一性のチェック」であり前述のように派生クラスで意味を拡張するのは「アプリケーション設計者の設計如何によって独自に決めるものであり」フレームワークや言語仕様としてのデフォルトは「派生クラスで拡張するのではなく変更するもの」すなわち「リスコフの置換原則を満たすかどうかの観点には入れないもの」と捉えるのが普通に思えるというのが自分の最初の回答の主張です。