Javaのインターフェースはクラスに似ていますが、インターフェースの本体には抽象メソッドのみおよび
final
フィールド(定数)を含めることができます。
最近、このような質問がありました
interface AnInterface {
public default void myMethod() {
System.out.println("D");
}
}
インターフェース定義によると、抽象メソッドのみが許可されています。上記のコードをコンパイルできるのはなぜですか? default
キーワードとは何ですか?
一方、以下のコードを記述しようとすると、modifier default not allowed here
と表示されます
default class MyClass{
}
の代わりに
class MyClass {
}
default
キーワードの目的を教えてもらえますか?インターフェイス内でのみ許可されますか? default
(アクセス修飾子なし)との違いは何ですか?
これはJava 8の新機能で、interface
が実装を提供できるようにします。 Java 8で説明 JLS-13.5.6。インターフェイスメソッド宣言 読み取り(一部)
default
メソッドを追加するか、メソッドをabstract
からdefault
に変更しても、既存のバイナリとの互換性は損なわれませんが、既存のバイナリがメソッドを呼び出そうとするとIncompatibleClassChangeError
が発生する可能性があります。このエラーは、修飾型T
がI
とJ
の2つのインターフェイスのサブタイプである場合に発生します。ここで、I
とJ
の両方が同じシグネチャと結果でdefault
メソッドを宣言し、I
もJ
も他方のサブインターフェイスではありません。
JDK 8の新機能 と言う(一部)
デフォルトのメソッドにより、ライブラリのインターフェースに新しい機能を追加でき、それらのインターフェースの古いバージョン用に記述されたコードとのバイナリ互換性を確保できます。
主にラムダ式をサポートするために、Java 8にデフォルトのメソッドが追加されました。デザイナー(私の考えでは賢いことに)は、インターフェースの匿名実装を作成するためのラムダ構文を作成することにしました。しかし、ラムダが単一のメソッドしか実装できない場合、単一のメソッドを持つインターフェースに制限され、かなり厳しい制限になります。代わりに、デフォルトのメソッドが追加され、より複雑なインターフェースを使用できるようになりました。
default
がラムダのために導入されたという主張を納得させる必要がある場合、2009年のMark ReinholdによるProject Lambdaの straw manプロポーザル は、「拡張メソッド」としてラムダをサポートするために追加される必須機能。
概念を示す例を次に示します。
interface Operator {
int operate(int n);
default int inverse(int n) {
return -operate(n);
}
}
public int applyInverse(int n, Operator operator) {
return operator.inverse(n);
}
applyInverse(3, n -> n * n + 7);
非常に不思議に思いますが、default
がラムダをどのようにサポートするかを説明する必要があります。 inverse
はデフォルトであるため、必要に応じて実装クラスによって簡単にオーバーライドできます。
Java 8には、デフォルトメソッドと呼ばれる新しい概念が導入されています。デフォルトのメソッドは、デフォルトの実装がいくつかあり、既存のコードを壊すことなくインターフェースを進化させるのに役立つメソッドです。例を見てみましょう:
public interface SimpleInterface {
public void doSomeWork();
//A default method in the interface created using "default" keyword
default public void doSomeOtherWork(){
System.out.println("DoSomeOtherWork implementation in the interface");
}
}
class SimpleInterfaceImpl implements SimpleInterface{
@Override
public void doSomeWork() {
System.out.println("Do Some Work implementation in the class");
}
/*
* Not required to override to provide an implementation
* for doSomeOtherWork.
*/
public static void main(String[] args) {
SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
simpObj.doSomeWork();
simpObj.doSomeOtherWork();
}
}
出力は次のとおりです。
クラスでいくつかの作業の実装を行う
インターフェースでのDoSomeOtherWorkの実装
他の回答で見落とされていたのは、アノテーションでの役割でした。 Java 1.5までさかのぼると、default
キーワードは、注釈フィールドの デフォルト値を提供する の手段として登場しました。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Processor {
String value() default "AMD";
}
使用法はoverloadedであり、Java 8の導入により、インターフェースでデフォルトのメソッドを定義できるようになりました。
見落とされた他の何か:default class MyClass {}
宣言が無効である理由は、 クラスがまったく宣言されている の方法によるものです。そのキーワードをそこに表示することを許可する言語の規定はありません。ただし、 インターフェイスメソッドの宣言 の場合は、doesが表示されます。
新しいJava 8機能( デフォルトメソッド )を使用すると、default
キーワードでラベル付けされたときに、インターフェイスで実装を提供できます。
例:
interface Test {
default double getAvg(int avg) {
return avg;
}
}
class Tester implements Test{
//compiles just fine
}
インターフェーステストは、デフォルトのキーワードを使用します。これにより、インターフェースを使用するクラスにメソッドを実装する必要なく、インターフェースがメソッドのデフォルト実装を提供できます。
後方互換性:インターフェイスが何百ものクラスで実装されていることを想像してください。インターフェイスを実装する他の多くのクラスには不可欠ではありません。
事実と制限:
1-クラス内または抽象クラス内ではなく、インターフェイス内でのみ宣言できます。
2-体を提供する必要があります
3-インターフェイスで使用される他の通常のメソッドのように、パブリックまたは抽象であるとは想定されていません。
非常に良い説明は The Java™Tutorials にあります。説明の一部は次のとおりです。
自動車を操作するためにどのメソッドを呼び出すことができるかを説明する業界標準のインターフェイスを公開するコンピューター制御自動車のメーカーが関係する例を考えてみましょう。コンピューター制御の自動車メーカーが、フライトなどの新しい機能を車に追加するとどうなりますか?これらのメーカーは、他の企業(電子誘導機器メーカーなど)が飛行中の車にソフトウェアを適合させるための新しい方法を指定する必要があります。これらの自動車メーカーは、これらの新しい飛行関連の方法をどこで宣言しますか?元のインターフェイスに追加した場合、それらのインターフェイスを実装したプログラマは、実装を書き直す必要があります。それらを静的メソッドとして追加する場合、プログラマはそれらを必須のコアメソッドではなくユーティリティメソッドと見なします。
デフォルトのメソッドを使用すると、ライブラリのインターフェイスに新しい機能を追加し、それらのインターフェイスの古いバージョン用に記述されたコードとのバイナリ互換性を確保できます。
デフォルトのメソッドを使用すると、アプリのインターフェースに新しい機能を追加できます。また、多重継承を使用することもできます。デフォルトのメソッドに加えて、インターフェースで静的メソッドを定義できます。これにより、ヘルパーメソッドを整理しやすくなります。
インターフェイスのデフォルトのメソッドにより、古いコードを壊すことなく新しい機能を追加できます。
Java 8より前は、新しいメソッドがインターフェイスに追加された場合、そのインターフェイスのすべての実装クラスは、新しい機能を使用していなくても、その新しいメソッドをオーバーライドするようバインドされました。
Java 8を使用すると、メソッド実装の前にdefault
キーワードを使用して、新しいメソッドのデフォルト実装を追加できます。
匿名のクラスや機能的なインターフェースを使用しても、一部のコードが再利用可能であり、コード内のすべての場所で同じロジックを定義したくない場合、それらのデフォルト実装を記述して再利用できます。
例
public interface YourInterface {
public void doSomeWork();
//A default method in the interface created using "default" keyword
default public void doSomeOtherWork(){
System.out.println("DoSomeOtherWork implementation in the interface");
}
}
class SimpleInterfaceImpl implements YourInterface{
/*
* Not required to override to provide an implementation
* for doSomeOtherWork.
*/
@Override
public void doSomeWork() {
System.out.println("Do Some Work implementation in the class");
}
/*
* Main method
*/
public static void main(String[] args) {
SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
simpObj.doSomeWork();
simpObj.doSomeOtherWork();
}
}