Java 8インタフェース:静的メソッドとデフォルトメソッド

5563 ワード

Java 8インタフェース:静的メソッドとデフォルトメソッド
過去の記事一覧
  • なぜOptionalを使うのですか?
  • なぜ配列の下でいつも0から始まるのですか?
  • この方式はもっと優雅で、ストップウォッチは時間を計ります!

  • Java 8インタフェースの変更には、インタフェース内の静的メソッドとデフォルトメソッドが含まれます.Java 8以前はインタフェースにメソッド宣言しかありませんでしたが、Java 8からデフォルトメソッドと静的メソッドをインタフェースで使用できます.
    Java 8インタフェース
    インタフェースの設計は、インタフェースに他のメソッドを追加するには、すべてのインプリメンテーションクラスで変更する必要があるため、困難な作業です.インタフェースが老朽化するにつれて、そのクラスの数はインタフェースを拡張できないほど増加する可能性があります.これは、アプリケーションを設計する際に、ほとんどのフレームワークが基本的な実装クラスを提供し、それを拡張し、アプリケーションに適した方法を書き換えるためです.
    デフォルトのインタフェースメソッドと静的インタフェースメソッド、およびJava 8インタフェースの変更に導入された理由を見てみましょう.
    Javaインタフェースのデフォルトメソッド
    Javaインタフェースでデフォルトのメソッドを作成するには、メソッド署名に「default」キーを使用する必要があります.例:
    package com.journaldev.java8.defaultmethod;
    
    public interface Interface1 {
    
        void method1(String str);
    
        default void log(String str){
            System.out.println("I1 logging::"+str);
        }
    }
    

    なお、log(String str)はInterface 1のデフォルトメソッドである.クラスがInterface 1を実装する場合、インタフェースのデフォルトメソッドを実装する必要はありません.このプロパティは、インタフェースを追加の方法で拡張するのに役立ち、デフォルトの実装を提供するだけです.
    次の方法を持つ別のインタフェースがあるとします.
    package com.journaldev.java8.defaultmethod;
    
    public interface Interface2 {
    
        void method2();
    
        default void log(String str){
            System.out.println("I2 logging::"+str);
        }
    }
    

    Javaは、「菱形の問題」を引き起こすため、コンパイラがどのスーパークラスメソッドを使用するかを決定できないため、複数のクラスを継承できないことを知っています.既定の方法を使用すると、インタフェースにも菱形の問題が発生します.クラスがInterface 1とInterface 2を同時に実装し、共通のデフォルトメソッドが実装されていない場合、コンパイラはどのメソッドを選択するかを決定できません.
    拡張された複数のインタフェースはJavaの不可欠な一部であり、コアJavaクラスおよびほとんどのエンタープライズアプリケーションおよびフレームワークで見つけることができます.したがって、この問題がインタフェースに現れないことを確認するには、インタフェースの一般的なデフォルトメソッドを実装する必要があります.したがって、クラスが上記の2つのインタフェースを同時に実装する場合は、log()メソッドに実装を提供する必要があります.そうしないと、コンパイラはコンパイル時にエラーを投げ出します.
    Interface 1とInterface 2を実装する簡単なクラスは、次のとおりです.
    package com.journaldev.java8.defaultmethod;
    
    public class MyClass implements Interface1, Interface2 {
    
        @Override
        public void method2() {
        }
    
        @Override
        public void method1(String str) {
        }
    
        @Override
        public void log(String str){
            System.out.println("MyClass logging::"+str);
            Interface1.print("abc");
        }
    }
    
    

    Javaインタフェースのデフォルトメソッドのポイントについて:
  • Javaインタフェースのデフォルトメソッドは、実装クラスの破壊を心配することなく、インタフェースを拡張するのに役立ちます.
  • Javaインタフェースのデフォルトメソッドは、インタフェースと抽象クラスの違いを補います.
  • Java 8インタフェースのデフォルトメソッドは、すべてのCollectionsクラスメソッドがインタフェース自体で提供されるなど、ツールクラスの使用を回避するのに役立ちます.
  • Javaインタフェースのデフォルトメソッドは、基本インプリメンテーションクラスを削除するのに役立ちます.インプリメンテーションクラスは、どちらを書き換えるかを選択できます.
  • がインタフェースにデフォルトメソッドを導入した主な理由は、Java 8のCollections APIを強化してlambda式をサポートするためである.
  • 階層内の任意のクラスが同じ署名を持つメソッドを持っている場合、デフォルトのメソッドは関連付けられません.デフォルトのメソッドではjava.lang.Objectのメソッドは書き換えられません.Objectはすべてのjavaクラスのベースクラスであるため、推理は非常に簡単です.したがって、インタフェースでObjectクラスメソッドをデフォルトメソッドとして定義しても、Objectクラスメソッドは常に使用されるため、無駄になります.これは,混同を避けるために,Objectクラスメソッドを上書きするデフォルトメソッドがないためである.
  • Javaインタフェースのデフォルトメソッドは、Defenderメソッドまたは仮想拡張メソッドとも呼ばれます.

  • Javaインタフェースの静的メソッド
    Javaインタフェースの静的メソッドはデフォルトのメソッドと似ていますが、実装クラスでは書き換えることはできません.この特性は、クラス内の悪い実装がもたらす望ましくない結果を回避するのに役立ちます.簡単な例でこの問題を研究しましょう.
    package com.journaldev.java8.staticmethod;
    
    public interface MyData {
    
        default void print(String str) {
            if (!isNull(str))
                System.out.println("MyData Print::" + str);
        }
    
        static boolean isNull(String str) {
            System.out.println("Interface Null Check");
    
            return str == null ? true : "".equals(str) ? true : false;
        }
    }
    

    実装クラスを見てみましょう.isNull()メソッドの実装は悪いです.
    package com.journaldev.java8.staticmethod;
    
    public class MyDataImpl implements MyData {
    
        public boolean isNull(String str) {
            System.out.println("Impl Null Check");
            return str == null ? true : false;
        }
    
        public static void main(String args[]){
            MyDataImpl obj = new MyDataImpl();
            obj.print("");
            obj.isNull("abc");
        }
    }
    

    注記isNull(String str)は、インタフェースメソッドを書き換えていない簡単なクラスメソッドです.たとえば、isNull()メソッドに@Overrideコメントを追加すると、コンパイラエラーが発生します.これで、アプリケーションを実行すると、次の出力が得られます.
    Interface Null Check
    Impl Null Check
    

    インタフェースメソッドをstaticからdefaultに設定すると、次の出力が得られます.
    Impl Null Check
    MyData Print::
    Impl Null Check
    

    Javaインタフェース静的メソッドはインタフェースメソッドのみに表示され、MyDataImplクラスからisNull()メソッドを削除すると、MyDataImplオブジェクトに使用できません.しかし,他の静的手法と同様に,クラス名を用いてインタフェース静的手法を用いることができる.たとえば、有効な文は次のようになります.
    boolean result = MyData.isNull("abc");
    

    JAvaインタフェースの静的メソッドのポイント:
  • Javaインタフェース静的メソッドはインタフェースの一部であり、クラスオブジェクトを実装するために使用できません.
  • Javaインタフェース静的方法は、空チェック、集合ソートなどの実用的な方法を提供するのに適している.
  • Javaインタフェースの静的メソッドは、クラスの書き換えを許可しないことによって、セキュリティを提供するのに役立ちます.
  • Objectクラスメソッドのインタフェース静的メソッドを定義することはできません.コンパイラは「この静的メソッドはObjectからインスタンスメソッドを隠すことはできません」とエラーを取得します.これはjavaでは許可されていないためです.Objectはすべてのクラスのベースクラスであるため、クラスレベルの静的メソッドと同じ署名を持つインスタンスメソッドを持つことはできません.
  • javaインタフェース静的メソッドを使用して、セットなどのユーティリティクラスを削除し、すべての静的メソッドを対応するインタフェースに移動することで、簡単に見つけることができ、使用することができます.

  • Java関数インタフェース
    本稿を終了する前に、機能インタフェースについて簡単に紹介したいと思います.抽象的なメソッドが1つしかないインタフェースを関数インタフェースと呼ぶ.
    新しいコメント@functionainterfaceを導入し、インタフェースをFunctionalインタフェースとしてマークします.@functionainterface注釈は、機能インタフェースの意図外に抽象的な方法を追加することを避けるツールです.これはオプションですが、それを使うのは良い実践です.
    Java 8の機能インタフェースは、lambda式を使用してインスタンス化できるため、長い間期待されていた注目されている特性です.新しいパッケージjava.util.functionと関数インタフェースが追加され、lambda式とメソッドリファレンスにターゲットタイプが提供されます.関数インタフェースとlambda式を今後の論文で検討する.