Javaの研究ノート(7) - インタフェースおよび多型

前の発言Javaオブジェクト指向の継承は、連続しています:メンバーの方法および多型の存在を呼び出すことをするとき、呼び出しすることを決定するための基準の種類に応じて、メンバ変数のオブジェクトを呼び出すときには、具体的に呼ばれる人新しい方法は、これは主に多型及び多形体の使用Javaインタフェースに記載され、決定のうちのオブジェクトを必要とします

ポリモーフィズム

C ++を学ぶ当時、ポリモーフィック機能を使用すると、そのは、仮想関数である、仮想として定義する必要があります。クラスの仮想関数は、ヘッド・ポインタ・オブジェクトの仮想関数テーブルが存在し、存在するアドレステーブルは、仮想関数が仮想関数であるメソッドを呼び出すときに、親クラスへのポインタまたは参照を使用して仮想関数テーブル内のアドレスの関数であってもよいですこの関数は、多形体と呼ばれています。

異なる基底クラスの派生クラス、別の行動へのポインタポイント:当時マルチステートは、C ++を学ぶのは非常に洗練された定義があります。仮想関数で呼び出されたときにここでは異なる動作を意味し、派生クラスは、異なる機能を呼び出すことができます。ここでは、いくつかの基本的な条件を多形相を言う:1)のポインタまたは参照タイプは、基本クラスである; 2)派生クラスを指すように必要3)関数は、基本クラスの関数をオーバーライドする必要があり呼び出します。

public class Parent{
    public void sayHelllo(){
        System.out.println("Hello Parent");
    }

    public void sayHello(String name){
        System.out.println("Hello" + name);
    }
}

public class Child extends Parent{
    public void sayHello(){
        System.out.println("Hello Child");
    }
}

相続によると、私たちは次のコードのいくつかの例を見て、多型が何であるかを分析します

Parent obj = new  Child();
obj.sayHello();

この例では、3つの条件多型を満たす多型、構成Parentobjへの参照をnew行う子サブクラスとの両方に共通のメソッドを呼び出しています。

Parent obj = new  Child();
obj.sayHello("Tom");

それは、基本クラスの派生クラスへの参照点を満足することであるが、この例では、マルチステートを構成するものではないが、それは親クラスの特定のメソッドを呼び出します。

Parent obj = new  Parent();
obj.sayHello();

この例では、多状態を満たしていない、それは親クラスの親クラスに基準点を使用して、これは通常のクラスメソッドの呼び出しで、メソッドは、その親クラスを呼び出します

Child obj = new Child();
obj.sayHello();

この例では、マルチ状態を満たしていない、それはサブクラスサブクラス基準点を使用し、これは通常のクラスのメソッド呼び出しでは、この方法は、そのサブクラスを呼び出します

だから、ポリモーフィックそれが良い何ですか?多型は、基本的に、コードの重複を避けるために導入され、プログラムがよりスケーラブルされ、私たちはprintlnの機能によってこれを説明しましょう。

public void println(Object x) {
    String s = String.valueOf(x);
    synchronized (this) {
        print(s);
        newLine();
    }
}

//Class String
public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

println関数は、着信オブジェクト関数はStringクラスの静的メソッドを呼び出すオーバーロード実装しvalueOf、さらにこの方法は、単にクラスを呼び出しことが判明とStringクラスtoStringオブジェクトを継承する任意のクラスであってもよいOBJを通す、方法限りクラスがオーバーライドとして、(Javaであれば、オブジェクトとして、オブジェクトから継承されなければならない)toStringメソッドを直接印刷することができます。このような機能が実現され、再利用は、余分なヘビーデューティ人は後に比べて、それは非常に簡単であるべきのprintln機能を必要とします。

クラスの型変換

printlnの機能の上にサブクラスによって今度は、変換のタイプの必要性を、それはObjectクラスへの参照を渡す必要がありますが、メソッドが呼び出されたときに、変換のタイプではありませんでした、ダイレクトパスがあり、ここにありますとき、親クラスに、Javaは暗黙の型変換しました。ビッグターン小(ここでは、小さな大きなターンメモリオブジェクト間の関係が含まれている)安全でなければならない、サブクラスは親クラスのメンバーを含むことができるようになりますので、場合でも、親クラスを変換する問題はありません。メモリへの親クラスの基準点は、必ずしも安全ではない、最大オンにするので、少し、サブクラスのメンバーが含まれていません。

なぜ小さなビッグ有効にしてください?多型は、私たちに大きな利便性を与えたが、最大の問題は、親クラスのサブクラスのメンバーへの多型の参照が見ることができないですが、それは、サブクラスのメンバーを使用することではありません。あなたは、サブクラスのメンバーを使用したい場合は、この時間は、操作を上げるために小さくなければなりません。彼は、私たちが必要とするオブジェクトのサブクラスに渡されたパラメータを決定することはできません、複数の実装クラスを有することができるので、Javaキーワードの導入は、親のために、小回り大きな不安の前に言ったinstanceofセキュリティを変換することができるかどうかを判断します、オブジェクト参照がターゲットは、次の例のように、真を返すオブジェクト又は親オブジェクトのクラスに渡される限り

Object obj = "hello"
System.out.println(obj instanceof String); //true
System.out.println(obj instanceof Object); //true
System.out.println(obj instanceof StringBuffer); //false
System.out.println(obj instanceof CharSequence); //true

抽象メソッドとクラス

私たちは、後にポリモーフィックコードの再利用とそれを言うことができます。しかし、時には私たちはしばしば、このような教科書の例として、達成する方法がわからない、いくつかのクラスに共通してより高いレベルの抽象基本クラスを持っているが、いくつかの共通の基底クラスのコンテンツがありますがことがわかったが、いくつかの方法があります彼らは動物が何であるかを正確に知らないので、動物は、ので、動物は草食か肉食であるかどうかを判断することはできません。動物が一般的にeat抽象メソッドとして定義され、この方法は、抽象クラスは抽象基底クラスが持っている必要があり有します。

抽象メソッドは、それだけで関数プロトタイプを提供し、達成するために記述する必要はありません方法です。インスタンスを作成することができない抽象クラスは、抽象メソッドをオーバーライドする派生クラスが存在しなければなりません。なぜ抽象クラスのオブジェクトを作成していませんか?オブジェクトのメソッドを呼び出すことは、本質的に、コード、および抽象メソッドが実装されていない方法でメモリアドレスを見つけるために、関数テーブルに対応する機能である、当然、あなたがオブジェクトを作成した場合、我々は、メソッドのアドレスを与えることができない、と私は、このオブジェクトを呼び出したいです紛争にまだない抽象メソッド。そのため、規定は抽象クラスをインスタンス化することはできません。

使用して、キーワードの抽象メソッドを定義するabstractなど、

public abstract class Life{
    public abstract void happy();
}

public class Cat{
    public void happy(){
        System.out.println("猫吃鱼");
    }
}

public class Cat{
    public void happy(){
        System.out.println("狗吃肉");
    }
}

public class Altman{
    public void happy(){
        System.out.println("奥特曼打小怪兽");
    }
}

上記の抽象クラスの人生はあなたが幸せで、生物が何であるかを依頼する必要があり、生物学的な世界を表現定義し、誰もあなたに答えを与えることができなかった、異なる生物は、異なる答えを持っていますが、同じ生物に特有の、ここで答えを持っていること単純に答えを与える:幸福は猫の魚の犬の肉は、アルトマンは、小さな怪物を果たした大好きです。

以下の点に注意することは、抽象クラスを使用します。

  • あなたは、オブジェクトを作成するために使用されなければならない抽象クラスオブジェクトの直接実装クラスを作成することはできません。
  • 抽象クラスが実装しなければならないすべての抽象メソッドは、そうでない場合は、実装クラスは抽象クラスでなければなりません
  • 抽象クラスは、サブクラスのコンストラクタにのみ使用され、独自のコンストラクタメソッドを持つことができます
  • これは、抽象メソッドのない抽象クラス抽象クラスである必要がありますが、抽象メソッドがあります

インターフェース

インターフェイスは共通標準のセットである、彼らは限りUSBポートを使用するデバイスとして、一般的な基準は、例えば、USBインタフェースを満たすので、私のコンピュータに関係なく、あなたのデバイスがそれに接続されているものを使用すべきではありません。コード内のクラスの共通インタフェース仕様複数です。

Javaは、インターフェースは、参照型です。インターフェイスと抽象クラスが同じオブジェクト、メソッド、実装クラスを作成する必要がありますを作成することはできません、非常に似ています。インターフェイスと抽象クラスが、いくつかの異なるがあります。抽象クラスは、基本となるクラスから抽象化、より高いレベルのクラスであるクラスですが、インターフェースは、一般的に複数のクラスをリンクするために使用され、一般的な規格は複数のクラスを達成するために必要とされます。それは、トップ層から引き出されます。

一般的な使用シナリオは、一般的なウィンドウメッセージ処理関数としてコールバックインタフェースです。このシナリオは、一般的にC ++の関数ポインタが、主な使用のJavaインタフェースを使用しています。
interfaceキーワードはinterface、例えば、定義します

public interface USB{
    public final String deviceType = "USB"; 
    public abstract void open();
    public abstract void close();
}

共通のインターフェースが抽象メソッドのメンバーである、抽象メソッドも実装クラスによって実装され、また同じ抽象クラスの前に注意事項。抽象メソッドに加えて、インタフェースも一定であってもよいです。

抽象メソッド・インターフェースがないメソッドの本体ではなく、そのように実装クラスを達成するために、達成するためにクラスを達成する必要がある現象を書き換える際に呼び出されるクラスおよびインターフェースを発生するので、一定のそれ?

public class Mouse implements USB{
    public final String deviceType = "鼠标";
    public void open(){

    }

    public void close(){

    }
}

public class Demo{
    public static void main(String[] args){
        USB usb = new Mouse();
        System.out.println(usb.deviceType);
    }
}

ウェイ属性のメンバーは、一定のフォローをリロード呼び出す前に言って呼ばれます。参照の種類、メンバーのコールのタイプを使用してください。

抽象クラスのもう一つの重要な違いは、多重継承、競合がそれで多重継承インタフェースに表示されるかどうかの後、質問を実行するためのインタフェースであります

public interface Storage{
    public final String deviceType = "存储设备";
    public abstract void write();
    public abstract void read();
}

public class MobileHardDisk implements USB, Storage{
     public void open(){

    }

    public void close(){

    }

    public void write(){

    }

    public void read(){

    }
}

public class Demo{
    public static void main(String[] args){
        MobileHardDisk mhd = new MobileHardDisk();
        System.out.println(mhd.deviceType);
    }
}

あなたは上記のコードを示唆、エラーが見つかりますコンパイルするとUSB 中的变量 deviceType 和 Storage 中的变量 deviceType 都匹配Javaはまだ完全に競合を避けるためではないことを、。

デフォルトのインターフェイスメソッド

時には、このようなシナリオは、プロジェクトが完了すると、顧客のニーズをあなたは抽象メソッドを使用している場合、方法で追加することができるインターフェイスで、その結果、変更されている可能性が発生する可能性があり、その後、インタフェースの実装クラスのすべてのような、メソッドを実装繰り返していましたコード、USBインタフェース上に言った、あなたは、対応するドライブと一致するオペレーティングシステムにどのようなUSBデバイスの種類私のPC機器に通知するためにメソッドを追加する必要があります。それは、クラスを追加するために、重複コードの多数を導入可能性が、この問題に対処する、Javaの8から始める必要があるかもしれないUSBの実装では、デフォルトの方法を紹介します。

新しいデフォルトのインターフェイスメソッドの実装クラスの前に変更することなく、インタフェースのアップグレードの問題を解決するためのデフォルトの方法。

次のようにデフォルトのメソッドを使用すると、次のとおりです。

public interface USB{
    public final String deviceType = "USB"; 
    public abstract void open();
    public abstract void close();
    public default String getType(){
        return this.deviceType;
    }
}

デフォルトの方法は、すべての実装クラスで上書きすることができます。

インターフェイスの静的メソッド

Javaの8以降では、インタフェースの静的メソッドを定義することができ、静的メソッド呼び出しのオブジェクトクラスを達成するために使用することができ、あなたはインターフェイスダイレクトコール名を使用することができます

プライベートメソッドをインターフェース

インタフェースのJavaの9ランからプライベートメソッドを定義し、デフォルトの方法で重複コードの多数の存在に対処するため、民間の方法。

Javaはそんなに新しいインターフェイスと拡張属性ですが、私は最後の手段として考えて、これらのものを台無しにしないが、結局のところ、インターフェースではなく、これらの基準を達成しようとするよりも、達成すべき基準のセットを定義する必要があります。

インターフェースを使用するための考慮事項の一部を要約すると:

  • インターフェイスブロック、あるいはまったく静的コンストラクタ
  • 親クラスは一クラスであるが、複数のインタフェースを実装することができます
  • あなたが複数のインタフェースを実装するクラスのデフォルトのメソッドと同じ名前を持っている場合は、実装クラスを達成するために、このメソッドをオーバーライドする必要があります、または競合します。
  • インタフェースの実装クラスは、抽象メソッドをすべて実装していない場合、このクラスは抽象クラスである必要があります
  • 親クラスとインタフェースのメソッドは、同じ名前、親クラスの優先利用、より良い関係を達成するためのJavaインターフェースでの継承を持っています
  • 同じ名前のデフォルトの方法は、複数の親インターフェイスに存在する場合インターフェイスとインターフェイスとの間に多重継承が、である、サブインターフェースは、他の競合が存在するであろう、デフォルトのメソッドをオーバーライドする必要があります

    finalキーワード

    以前つまり、量はプログラムで変更することができない定数を表すために使用される最終的なキーワードを挙げます。この使用方法に加えて、それはまた、他の用途を持っています
  • クラスを表し修正クラスは、サブクラスを持つことができません。それは、クラスの性質を変更することができず、最終的な定数を変更できない表すので継承は、この種の変化として理解することができます
  • 修正方法:変更された最後のメソッドをオーバーライドすることはできません
  • 変更されたメンバ変数:メンバ変数が一定であり、変更することはできません
  • 修飾されたローカル変数:ローカル変数に一定である、対応する範囲で変更することができません


おすすめ

転載: www.cnblogs.com/lanuage/p/10959288.html