default method
Java には に代わる 計画がありAbstract Class
ますか? Abstract の代わりにデフォルト メソッドを使用する実際のケースが見つかりませんでしたか?
4 に答える
そのような計画はありません。これは、すでに文書化されている意図を比較することから導き出すことができ、そのような計画の含意とは異なります。
主な目標は、インターフェースの進化、つまり新しいメソッドの追加を可能にすることです。新しいメソッドがインターフェイスに追加されると、インターフェイスを実装する既存のクラスに実装がなくなり、互換性がなくなります。互換性を保つには、実装をどこかから取得する必要があるため、デフォルトのメソッドで提供されます。
…</p>
Java インターフェースの主な目的は、クラス階層内の位置を変更することなく、どのクラスでも実装できるコントラクトを指定することです。確かに、Java 8 より前のインターフェースは純粋に抽象的でした。ただし、これはインターフェイスの本質的なプロパティではありません。デフォルトのメソッドが含まれている場合でも、その中心にあるインターフェースは、実装するクラスのコントラクトを指定します。実装クラスはデフォルトのメソッドをオーバーライドできるため、クラスはその実装を完全に制御できます。(また、デフォルトのメソッドを final にすることはできないことに注意してください。)
Brian Goetz は次のように書いています。
インターフェイスにデフォルト メソッドを追加する最も近い理由は、インターフェイスの進化をサポートすることでした。</p>
以下に、設計目標の範囲内にある使用例をいくつか示します。
インターフェイスの進化。ここでは、新しいメソッドを既存のインターフェースに追加しています。これは、そのインターフェースの既存のメソッドに関して適切なデフォルト実装を持っています。例として、
forEach
メソッドをに追加するCollection
場合があります。この場合、デフォルトの実装はiterator()
メソッドに関して記述されます。「オプション」メソッド。ここで、インターフェースの設計者は、「必要な機能の制限を受け入れる意思がある場合、実装者はこのメソッドを実装する必要はありません」と言っています。たとえば、;
Iterator.remove
をスローするデフォルトが与えられました。UnsupportedOperationException
の実装の大部分はIterator
とにかくこの動作をするため、デフォルトではこのメソッドは本質的にオプションになっています。( の動作AbstractCollection
が のデフォルトとして表現されている場合Collection
、可変メソッドに対して同じことを行う可能性があります。)便利な方法。これらは厳密に便宜上のメソッドであり、通常はクラスのデフォルト以外のメソッドに関して実装されます。最初の例の
logger()
方法は、これの合理的な例です。コンビネーター。これらは、現在のインスタンスに基づいてインターフェイスの新しいインスタンスをインスタンス化する合成メソッドです。たとえば、メソッド
Predicate.and()
やメソッドComparator.thenComparing()
はコンビネータの例です。
これらは、スケルトン実装を提供するなど、抽象クラスのプライマリ ドメインを対象としないことに注意してください。技術的な違いに加えて、抽象クラスは、機能を実装する方法に関する設計上の決定を行うため、意味的に異なります。メソッドを使用する場合でも、インターフェイスdefault
はそうすべきではありません。たとえば、よく知られている例は、List
2 つの根本的に異なる抽象クラスが存在するインターフェイスでありAbstractList
、AbstractSequentialList
サブクラスの選択または完全に異なる実装のいずれかList
が、インターフェイスによって排除されるべきではありません。したがって、List
インターフェイスはコントラクトを定義し、特定の基本実装を提供する抽象クラスの代わりにはなりません。
抽象クラスはフィールドを持つことができる (そしてしばしばそうする) ため、既定のメソッドは抽象クラスを置き換えることはできません。インターフェースには動作のみを含めることができ、状態は含めることができません。これは、Java での状態の多重継承が (正しいか間違っているかに関わらず) 悪と見なされるため、将来変更される可能性は低いです。
メソッドを持つこともできfinal
ますが、これはメソッドで模倣できないもう 1 つのことですdefault
。
どちらかといえば、デフォルト メソッドを持つインターフェイスは、抽象クラスというよりもトレイトに似ていますが、完全に一致するわけではありません。インターフェイスをトレイトとして使用することは、非常に慎重に行う必要があり、インターフェイスに伴う制限を理解する必要があります。(たとえば、実装クラスはメソッドをオーバーライドdefault
して、特性を台無しにする可能性があります。)
詳細はこちら。