簡単に言えば、安全に使用すれば安全です:)
卑劣な答え:あなたが特性によって何を意味するか教えてください、そして多分私はあなたにより良い答えを与えるでしょう:)
すべての真面目に、「特性」という用語は明確に定義されていません。多くのJava開発者は、Scalaで表現される特性に最も慣れていますが、Scalaは、特性または名前のいずれかを備えた最初の言語からはほど遠いです。
たとえば、Scalaでは、トレイトはステートフルです(var
変数を持つことができます)。要塞ではそれらは純粋な振る舞いです。デフォルトのメソッドを持つJavaのインターフェースはステートレスです。これは彼らが特性ではないことを意味しますか?(ヒント:それはトリックの質問でした。)
繰り返しますが、Scalaでは、特性は線形化によって構成されます。クラスは、IF A
特性を拡張するX
とY
、その後に注文X
とY
の間の競合方法を決定するで混合さX
とがY
解決されます。Javaでは、この線形化メカニズムは存在しません(「Javaに似ていない」ため、一部拒否されました)。
デフォルトのメソッドをインターフェースに追加するおおよその理由は、インターフェースの進化をサポートすることでしたが、私たちはそれを超えていることをよく知っていました。それを「インターフェイスの進化++」と見なすか「特性」と見なすかは、個人的な解釈の問題です。したがって、安全性についての質問に答えるには...メカニズムが実際にサポートしているものに固執する限り、サポートしていないものに伸ばそうとするのではなく、問題はありません。
主要な設計目標は、インターフェースのクライアントの観点からは、デフォルトのメソッドは「通常の」インターフェースメソッドと区別できないようにすることです。したがって、メソッドのデフォルト性は、インターフェースの設計者と実装者にとってのみ興味深いものです。
以下は、設計目標の範囲内にあるいくつかの使用例です。
インターフェイスの進化。ここでは、既存のインターフェースに新しいメソッドを追加します。既存のインターフェースには、そのインターフェースの既存のメソッドに関して適切なデフォルトの実装があります。例としては、forEach
メソッドをCollection
に追加する場合があり、デフォルトの実装はiterator()
メソッドの観点から記述されています。
「オプション」メソッド。ここで、インターフェイスの設計者は、「実装者が必要とする機能の制限に対処する意思がある場合、このメソッドを実装する必要はない」と述べています。たとえば、Iterator.remove
をスローするデフォルトが指定されましたUnsupportedOperationException
。の実装の大部分はIterator
とにかくこの動作をするため、デフォルトではこのメソッドは本質的にオプションになっています。(の動作AbstractCollection
がのデフォルトとして表現されている場合Collection
、変異メソッドに対しても同じことを行う可能性があります。)
便利なメソッド。これらは便宜上のものであり、クラスのデフォルト以外のメソッドに関して一般的に実装されているメソッドです。logger()
最初の例のメソッドは、これを合理的に示しています。
コンビネーター。これらは、現在のインスタンスに基づいてインターフェースの新しいインスタンスをインスタンス化する構成メソッドです。たとえば、メソッドPredicate.and()
またはComparator.thenComparing()
はコンビネータの例です。
デフォルトの実装を提供する場合は、デフォルトの仕様も指定する必要があります(JDKでは、@implSpec
このためにjavadocタグを使用します)。実装者がメソッドをオーバーライドするかどうかを理解するのに役立ちます。コンビニエンスメソッドやコンビネーターなどの一部のデフォルトは、ほとんどオーバーライドされません。オプションのメソッドのような他のものはしばしばオーバーライドされます。デフォルトが何を約束するかについて、十分な仕様(ドキュメントだけでなく)を提供する必要があります。これにより、実装者は、それをオーバーライドする必要があるかどうかについて賢明な決定を下すことができます。