JAVA随堂筆記課【九】:多態、抽象

3644 ワード

マルチステートpolymorphism
マルチステート3要素:
  • 継承環境では、サブクラスは親メソッドを書き換えます.Public Son extends Dad;
  • 汎用親参照変数は、子オブジェクトを指します.Dad p = new Son();
  • は、サブクラスの書き換え方法を適切に呼び出す.

  • マルチステートを前提として、親変数は任意のサブクラスを指すことができます.親がサブクラスの書き換え方法を呼び出すと、親ではなくサブクラスの書き換えコードが実行されます.この方法では、親がすべての子クラスの同名メソッドを柔軟に運用し、変数の使用率を向上させることができます.さらに工場モデルに拡張できる.
    こんなにたくさん話したので、画像で説明したほうが理解できるかもしれません.次に、図の中ですべてのsound方法を見つけます.
    図のように、3つのsoundメソッドは、それぞれAnimal、Tiger、ChineseTigerの3つのクラスに存在する.
    Animal a = new Animal();
    a.sound();
    a = new Tiger();
    a.sound();
    a = new ChineseTiger();
    a.sound();

    問:3回のsoundはそれぞれどのsoundを実行しますか.答えは:Animal.sound,Tiger.义齿sound.
    メモリ内のクラス変数を継承する指向性の問題(http://blog.csdn.net/sqrt31/article/details/50378686)によると、親は子を指すと同時に親とみなされ、子の部分は呼び出せません.
    さっきのコードでは、親が子を指して親と見なし、子部分が呼び出せないのは当然ですが、なぜ2、3番目のa.soundが子の関数を実行しているのでしょうか.
    矛盾の原因
    実は原因は複雑ではありません.親は子を親と見なしますが.しかし、方法を実行するとき、プログラムは依然として外から内へです.図から明らかなように,親としてロードする方法は,Animal下のsoundとrunのみである.しかし、このAnimalクラスは無数のサブクラスにネストされている.今、Animalのsoundを呼び出す必要があります.
    8時間目の授業で言ったのを覚えていますか.呼び出すときは、外から内へ1階ずつ探して、見つけたら実行を開始します.この言葉はわざわざ太くなった.
    では、今回呼び出したとき、私たちが探していたのは何ですか?soundです.
    だからあなたは外から内へ探して、出会った最初のsound方法は、子類が書き直したとしても、父類が持ってきて使います.
    このようなやり方は有名な--多態である.
    たじょうたいさよう
    见たところ気にしないで、外から内へ探して、见つけたら、自分のかどうかにかかわらず......どうせ私はあなたを使ってどのようにしましょう.前のことが分かったとき、私はいつも「多態はベテランプログラマーたちが陰で陽差を間違えて作ったもの」という感じがしましたが...メモリの中では理不尽なやり方のようで、JAVAでは拳と足を戦うことができます.
    さっきのAnimalクラスについて言えば--私はこのAnimalクラスを持っています.私はAnimalタイプの変数を使って、Animalのサブクラスを盛ることができる空間を開くことができますか?
    このようにして、1つの親の変数を譲って、すべての子の同名の方法の中で滞りなく通じることができて、こんなに多くの子の類はすべて親の重名の方法(例えば、さっきのsound)があって、それは親として、老子は誰を使いたいのかを使います.スーパー万金油.
    マルチステートでtoStringを書き換える
    toStringはObjectクラスの変数です.Objectはどのクラスでも継承できるクラスです.これは何を意味しますか?あなたの任意の変数xxxは、どんなクラスでもxxxを行うことができます.toString()操作.このトーチカだ.どのタイプの変数pに対しても、次のような出力テストを行ってみてください.
    System.out.println(p.toString());
    

    コマンドラインウィンドウには、次のような出力が表示されます.
    work.Polymorphism.Tester.Son@1be847c
    

    もちろん違うかもしれませんが、フォーマットは同じで、精神を理解しています.
    ObjectのtoStringクラスを見てみましょう.
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
    

    わかりましたね.現在のクラス名を取得し、hashCodeを取得します.hashCode、今は初心者として、一応メモリアドレスにしておきましょう.
    では,多態の理論によれば,外部のサブクラス,すなわちObjectクラスを任意に呼び出したクラス,すなわち任意のクラスで書き換えることができる.
    抽象abstract
    抽象クラスとは
    まず,抽象クラスは継承されることを渇望する.なぜなら、抽象クラスはインスタンスを構築できないからです.
    理由は簡単で、抽象クラスは未完成クラスです.完成していないクラスがどうして使用できるのでしょうか.もちろんできません.うーん...あの使えないクラスはどう使いますか?使い方は一つしかありません.継承してもいいですよ.そしてそれを完成させなかった方法を、あなたのサブクラスで完成させます^^;これで抽象類が機能するのではないでしょうか.
    実際、抽象クラスは継承されることを望んでいる.サブクラス継承のない抽象クラスは、構築できず、誰も呼び出さず、プログラム実行における役割はゼロです.
    次のコードは抽象クラスAを新規作成し,未完了の抽象メソッドA.m 3()をサブクラスBに渡して完了する.
    abstract class A{
        void m1(){
            ...;
        }
        void m2(){} //          ,          。
        abstract void m(); //    ,      。
    }
    
    class B extends A{
        void m3(){}
    }
    

    一般クラス、Finalクラス、abstractクラスの違い
    操作
    一般クラス
    Finalクラス
    abstractクラス
    インスタンスの作成
    yes
    yes
    no
    サブクラスの作成(継承)
    yes
    no
    yes
    参照変数としてのデータ型
    yes
    yes
    yes
    注意:抽象クラスは参照変数データ型として使用できますが、newオブジェクトは出ません.サブクラスが継承し、newサブオブジェクトが必要です.
    アクティブ抽象クラスとパッシブ抽象クラス
    パッシブ抽象クラス(A)には未完成の抽象メソッド(m 3)が存在するため,抽象クラスとなることを余儀なくされる.
    アクティブ抽象クラスのすべての方法はすでに完了しているが,故意にabstract接頭辞を先頭に付け,自発的に使用を開始する権利を剥奪し,サブクラスの継承を待つ抽象クラスとなり,このクラスをアクティブ抽象クラスと呼ぶ.
    たとえば,親クラスAnimalからTiger,Wolf,Lionなどの子クラスが派生すると,Animalクラスはアクティブ抽象クラスとして作成し,コード実装を子クラスに渡すことが考えられる.