Java_構文ベース_仕様のインタフェースタイプの定義

6744 ワード

インタフェースは、完全に抽象的な設計であり、何の実現もありません.インタフェースには、次の3つの特徴があります.1.すべてのメンバー変数はpublic、static、finalタイプです.2.すべての方法はpublic、abstractタイプです.3.すべてのネストタイプ(クラスまたはインタフェース)はpublic、staticタイプです.4.上記3点に明示的な声明がなくても同様である.このことから、インタフェースのすべてのメンバーはpublicであり、インタフェースは抽象的であり、他のクラスによって実現されなければならないため、メンバーは十分なアクセス権限を備えなければならないことがわかる.
インタフェースに何がありますか
インタフェースが宣言され、インタフェースにメンバーが明示的に宣言されていない場合、そのインタフェースは空ですか?この問題の前に、簡単な例を見てみましょう.例:
package deep;

public class UpCast implements Graph {

    @Override
    public void draw() {
    }

    public void cast() {
    }

    public static void main(String[] args) {
        UpCast u = new UpCast();
        u.draw();
        u.cast();
        Graph g = u;
        g.draw();
        // g.cast();     cast  
    }

}

interface Graph {
    void draw();
}

クラスがインタフェースに移行すると、インタフェースで宣言されたメソッドのみが呼び出され、自分のクラスで宣言されたメソッドは呼び出されません.この例によれば、インタフェースタイプの参照によって、呼び出すことができる方法はインタフェースで宣言されるべきであり、そうでなければ呼び出すことができない.そこで、メンバーを宣言していないインタフェースをテストして、空かどうかを確認します.例:
package deep;

public class EmptyInterfaceTest implements EmptyInterface {

    public static void main(String[] args) throws InterruptedException {
        EmptyInterface e = new EmptyInterfaceTest();
        e.equals(null);
        e.getClass();
        e.hashCode();
        e.notify();
        e.notifyAll();
        e.toString();
        e.wait();
        e.wait(100L);
        e.wait(100L, 100);
    }

}

interface EmptyInterface {
}

このプログラムはコンパイルできます.EmptyInterfaceインタフェースにメンバーが宣言されていないのに、なぜインタフェースリファレンス(e)でこの一連のメソッドを呼び出すことができるのか不思議に思うかもしれません.これは,インタフェースが空ではないためであり,明示的にメソッドを宣言していなくても,インタフェースにはObjectクラスで宣言された9つのpublicメソッドに対応する9つのメソッドがデフォルトで存在する.これは、メンバーを明示的に宣言しない「空のインタフェース」であっても、少なくとも9つのメソッドメンバーが存在するため、実際には空ではないことを示しています.
インタフェースをインスタンス化できません
インタフェースは完全に抽象的な設計であり、インスタンス化できません.すなわち、インタフェースタイプのオブジェクトを作成することはできません.このようなオブジェクトは実装されていないので、意味がありません.しかし、次の手順はどのように説明しますか?例:
package deep;

public class Instantiated {
    public static void main(String[] args) {
        Bird b = new Bird() {
            @Override
            public void fly() {
                System.out.println("flying");

            }
        };
        b.fly();
    }
}

interface Bird {
    void fly();
}

オブジェクトを作成するようにnewを使用してインタフェースをインスタンス化することはできませんが、new Birdを使用してインタフェースのインスタンスを作成し、flyメソッドを実装しているようです.このプログラムはコンパイルでき、実行結果は以下の通りです:flying
すべてが正常に動作しています.これはインタフェースでもインスタンス化できるということですか?実は、これはすべて仮象です.インタフェースは完全に抽象的な設計であり,インスタンス化できない.注意深い読者も、インスタンティatedをコンパイルしていることに気づきます.JAva後、Instantiatedとなる3つのclassファイルが生成されます.class、Bird.class、Instantiated$1.class、最初の2つはおかしくありません.肝心なのは3番目のclassファイルがどこから来たのかです.プログラムの作成方式は,匿名クラスを用いて実現され,3番目のclassファイルはここから生成される.実際、プログラム内のnew Birdは、Birdタイプの「インタフェースオブジェクト」ではなく、匿名クラスを作成します.このクラスはBirdインターフェースを実現し,Birdインターフェースにおけるfly法を実現した.
インタフェースの継承
Javaでは、クラスは多重継承を許可しません.複数のクラスから継承されたメンバーと、混同や誤用を招きやすいため、Javaではこの特性が除去されます.ただし,インタフェースについては,その設計が完全に抽象的で,実装が含まれていないため,インタフェースの継承はクラスの継承に比べて相対的に問題が少ないため,Javaではインタフェースを多重に継承することができる.インタフェース内のメソッドはabstractタイプであり、インタフェースを実装するクラスにこれらの抽象メソッドを実装し、インタフェース参照によってインタフェースを実装するオブジェクトを指し示すことを目的とし、インタフェース内のメソッドを呼び出すことができる.したがって、インタフェースはインスタンスメソッドであり、static(静的)メソッドを宣言することは許されない.静的メソッドはオブジェクトに依存せずに存在するため、クラス名で直接呼び出すことも、オブジェクトを作成する必要もありません.子インタフェースが親インタフェースと同じ名前の変数を宣言すると、親インタフェースの同じ名前の変数が非表示になります.2つのインタフェースに同じ名前の変数が宣言されている場合、1つのクラスが2つのインタフェースを実装しているか、サブインタフェースが2つのインタフェースを多重に継承している場合、同じ名前の変数にアクセスする場合は、限定名を使用する必要があります.単純な名前を使用するとコンパイルエラーが発生します.例:
package deep;

interface Donkey {
    String kind = "donkey";
}

interface Horse {
    String kind = "horse";
}

interface Mule extends Donkey, Horse {
    // String des = kind; The field kind is ambiguous
    String des2 = Donkey.kind;
    String des3 = Horse.kind;
}

class MuleClass implements Mule {
    // String des = kind; The field kind is ambiguous
    String des2 = Donkey.kind;
    String des3 = Horse.kind;
}

class MuleClass2 implements Donkey, Horse {
    // String des = kind; The field kind is ambiguous
    String des2 = Donkey.kind;
    String des3 = Horse.kind;
}