[解決済み] Java8: java.lang.Objectのメソッドにデフォルトメソッドを定義することはなぜ禁じられているのでしょうか?
質問
デフォルト・メソッドは、Javaのツールボックスの中の素晴らしい新しいツールです。しかし、私は、このメソッドを定義するインターフェイスを書こうとしました。
default
のバージョンです。
toString
メソッドを使用します。で宣言されたメソッドは、Javaはこれが禁じられていると教えてくれました。
java.lang.Object
は
default
編です。なぜこのようなことが起こるのでしょうか?
ベースクラスが常に勝つというルールがあることは知っています。
default
の実装は
Object
のメソッドで上書きされてしまいます。
Object
ということです。しかし、私は、このように
Object
を仕様に追加しました。特に
toString
は、デフォルトの実装があると非常に便利かもしれません。
では、なぜJavaの設計者が
default
のメソッドをオーバーライドします。
Object
?
解決方法は?
これは、言語設計の問題の1つで、明らかに良いアイデアと思われるものですが、調査を始めると、実は悪いアイデアであることに気づきます。
このメール このテーマについては、他のテーマも含めて、多くのことが書かれています。
- 継承モデルをシンプルにしたい。
-
明らかな例を見ても、(たとえば
AbstractList
equal/hashCode/toStringの継承は単一継承とステートに強く結びついており、インターフェースは多重継承とステートレスであることに気付きます。 - 意外な動作への扉を開く可能性があること。
継承と衝突解決のルールは非常にシンプルに設計されています(クラスはインターフェースに勝ち、派生インターフェースはスーパーインターフェースに勝ち、その他の衝突は実装クラスが解決する)。 もちろん、これらのルールは例外を作るために微調整することができますが、その糸を引っ張り始めると、増加する複雑さはあなたが考えるほど小さくはないことに気づくと思います。
もちろん、より複雑であることを正当化できるようなメリットがあればいいのですが、この場合はそれがありません。 ここで話題にしているのは、equals、hashCode、toStringの3つのメソッドです。 これらのメソッドはすべて本質的にオブジェクトの状態についてであり、そのクラスにとって平等が何を意味するかを決定するのに最適な立場にあるのは、インターフェースではなく、その状態を所有するクラスです(特に平等に関する契約は非常に強いので、いくつかの驚くべき結果については Effective Java を参照してください);インターフェース作成者はあまりにも遠く離れすぎているのです。
を引っ張り出すのは簡単です。
AbstractList
を取り除くことができれば、それは素晴らしいことです。
AbstractList
の中に入れて、その動作を
List
インターフェイスを使用します。 しかし、この分かりやすい例から一歩踏み出すと、他に良い例はあまり見当たりません。 根底には
AbstractList
は単一継承のために設計されています。 しかし、インターフェースは多重継承のために設計されなければなりません。
さらに、このクラスを書くとします。
class Foo implements com.libraryA.Bar, com.libraryB.Moo {
// Implementation of Foo, that does NOT override equals
}
は
Foo
の作者は、スーパータイプを見て、equals の実装がないことを知り、参照等式を得るために必要なことは、equals を
Object
. そして来週、Bar のライブラリメンテナーは、 "親切にも" に、デフォルトの
equals
を実装しています。 おっと! これで
Foo
は、別のメンテナンス・ドメインのインターフェイスによって、共通のメソッドのデフォルトを追加することで、壊れてしまったのです。
デフォルトはデフォルトであることが前提です。 デフォルトがないインターフェースにデフォルトを追加しても、(階層のどこにいても)具体的な実装クラスのセマンティクスに影響を及ぼすべきではないのです。 しかし、もしデフォルトがオブジェクトのメソッドをオーバーライドすることができるのであれば、それは真実ではありません。
そのため、一見無害な機能のように見えますが、実際には非常に有害です。わずかな表現力の増加のために多くの複雑さを追加し、個別にコンパイルされたインターフェースに対する善意の無害に見える変更が、実装クラスの意図したセマンティクスを損なうことがあまりにも容易になってしまうのです。
関連
-
スレッド "main" で例外発生 java.lang.ArrayIndexOutOfBoundsException: 0 at One1.main(One1.java:3)
-
スレッド "main" で例外発生 java.net.BindException: アドレスは既に使用中です。NET_Bind
-
SocketTimeoutExceptionの解決方法です。読み込みがタイムアウトした
-
[解決済み] なぜパスワードにはStringではなくchar[]が好まれるのですか?
-
[解決済み] いつ使うか。Java 8+のインターフェイスのデフォルトメソッドと、抽象的なメソッドの比較
-
[解決済み] なぜJava 8のOptionalは引数で使ってはいけないのか
-
[解決済み] Javaインターフェースでスタティックメソッドを定義できないのはなぜですか?
-
[解決済み] Java 8のインターフェイスメソッドで "final "が使えないのはなぜですか?
-
[解決済み】Javaでデフォルトのメソッドを明示的に呼び出す
-
[解決済み】Java 8のインターフェースメソッドで "synchronized "が使えない理由は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
スタイルが読み込まれず、ブラウザコンソールでエラーが報告される。リソースはスタイルシートとして解釈されますが、MIMEタイプtext/htmlで転送されます。
-
Java のエラーです。未解決のコンパイル問題 解決方法
-
Java Exceptionが発生しました エラー解決
-
eclipse で「アクセス制限: タイプ 'HttpServer' は API ではありません」というプロンプトが表示される。
-
this()の呼び出しはコンストラクタ本体の最初の文でなければならない 例外解決と原因分析
-
java Mail send email smtp is not authenticated by TLS encryption solution.
-
Eclipseプロンプトを実行する java仮想マシンを使用しない
-
xxx:jarのアーティファクトディスクリプタの読み込みに失敗した問題は解決しました。
-
アイデア Springboot Web プロジェクトを jar にパッケージ化する場合、Error: 無効または破損した jarfile x.jar 解決策
-
Exception: java.util.NoSuchElementException: 行が見つかりません