ホームページ >Java >&#&チュートリアル >JAVAポリモーフィズムを浅いところから深いところまで導入

JAVAポリモーフィズムを浅いところから深いところまで導入

高洛峰
高洛峰オリジナル
2017-01-21 16:59:421183ブラウズ

ポリモーフィズムとは何ですか?

ポリモーフィズムは 2 つのタイプに分類されます:

(1) コンパイル時ポリモーフィズム (デザイン時ポリモーフィズム): メソッドのオーバーロード。

(2) 実行時ポリモーフィズム: JAVA ランタイム システムは、メソッドを呼び出すインスタンスのタイプに基づいて、どのメソッドを呼び出すかを決定します。これをランタイム ポリモーフィズムと呼びます。 (私たちは通常、ランタイムポリモーフィズムについてよく話します。そのため、ポリモーフィズムは主にランタイムポリモーフィズムを指します)

ランタイムポリモーフィズムの存在には 3 つの必要な条件があります。
1. 継承 (インターフェイスの実装を含む) が存在する必要があります。 、書き換えが必要です。
3 つ目は、親クラスの参照がサブクラスのオブジェクトを指していることです。

------------------------------------------------ --------------------------------

詳細な説明:

ランタイムポリモーフィズムの説明: ランタイムポリモーフィズムとは、次のことを指します。 b. プログラム内で定義された参照変数が指す特定の型、および b. 参照変数を通じて発行されるメソッド呼び出しは、プログラミング中には決定されませんが、プログラムの実行中に決定されます。つまり、参照変数は、どのクラスのインスタンス オブジェクト、および参照変数によって発行されるメソッド呼び出しがどのクラスに実装されるメソッドであるかは、プログラムの実行中に決定する必要があります。

1。は不確実です (つまり、参照変数がどのクラス インスタンス オブジェクトを指すか)。

例:

driver クラスの drive メソッド (Vehicle クラス vehicle) {}

•oneDriver.drive( new car() )

•oneDriver.drive( newbus() )
vehicle 変数はどれを使用するかを決定できませんサブクラスのインスタンス。

1. 参照変数によって発行されるメソッド呼び出しは、プログラミング時に決定されません (参照変数によって発行されるメソッド呼び出しが、どのクラスに実装されたメソッドであるか)。

例: シェフ、庭師、理髪師の Cut メソッドは .persion.cut() を呼び出します。

------------------------------------- -------------------------------------------------- ---

ポリモーフィズムの利点:

1.ポリモーフィズムにより、既存のコードの置き換えが可能になります。たとえば、ポリモーフィズムは Circle クラスで機能しますが、トーラスなどの他の円形ジオメトリでも機能します。

2. 拡張性。ポリモーフィズムによりコードが拡張可能になります。新しいサブクラスを追加しても、ポリモーフィズム、継承、および既存のクラスの他の機能の操作や操作には影響しません。実際、新しいサブクラスを追加して多態性関数を取得する方が簡単です。たとえば、円錐、半円錐、半球の多態性を実現した後、球クラスの多態性を追加するのは簡単です。

3. インターフェース能力。ポリモーフィズムは、スーパークラスがメソッド シグネチャを通じてサブクラスに共通のインターフェイスを提供し、サブクラスがそれを完了またはオーバーライドすることによって実現されます。図 8.3 に示すように。図のスーパー クラス Shape は、ポリモーフィズムを実装する 2 つのインターフェイス メソッド、computeArea() と computeVolume() を指定します。 Circle や Sphere などのサブクラスは、ポリモーフィズムを実現するために、これら 2 つのインターフェイス メソッドを改善またはオーバーライドします。

4. 柔軟性。柔軟で多様な運用をアプリケーションに実現し、利用効率を向上させます。

5. シンプルさ。ポリモーフィズムは、アプリケーション ソフトウェアのコード作成および変更プロセスを簡素化します。この機能は、多数のオブジェクトの計算や操作を扱う場合に特に顕著で重要です。

実用的なアプリケーション:

構成ファイルの使用と組み合わせて、Springフレームワークに接続し、リフレクションを使用し、ソースコードを変更せずにクラスを動的に呼び出し、新しいクラスを直接追加して構成ファイルを変更し、再起動せずにプログラムを拡張できます。サーバー。

------------------------------------------------ --------------------------------

概要:

親クラス型の参照を使用して、サブクラスのオブジェクト。この参照によって呼び出されるマスター クラスで定義されたメソッドと変数はオーバーライド (上書き) できません。親クラスのメソッドがサブクラスでオーバーライドされると、このメソッドが呼び出されるときにサブクラスのメソッドがオーバーライドされます。このメソッドは呼び出されます。

親クラスによって呼び出されるメソッドのパラメーター リストが定義されていない場合、特定の優先順位が高いものから低いものまで呼び出されます。次のように:

this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

------------------------------------------------ --------------------------------

古典的な筆記試験の問題 (リロードとリライトの混合):

(1 )関連クラス

class A {
         public String show(D obj)...{
                return ("A and D");
         } 
         public String show(A obj)...{
                return ("A and A");
         } 
} 
class B extends A{
         public String show(B obj)...{
                return ("B and B");
         }
         public String show(A obj)...{
                return ("B and A");
         } 
}
class C extends B...{} 
class D extends B...{}

(2) 質問: 次の出力結果は何ですか?

A a1 = 新しい A();
A a2 = 新しい B();
B b = 新しい B();
C c = 新しい C(); 
D d = 新しい D(); 
System.out.println(a1.show(b));   ①
System.out.println(a1.show(c));   ②
System.out.println(a1.show(d));   ③
System.out.println(a2.show(b));   ④
System.out.println(a2.show(c));   ⑤
System.out.println(a2.show(d));   ⑥
System.out.println(b.show(b));     ⑦
System.out.println(b.show(c));     ⑧
System.out.println(b.show(d));     ⑨

(三)答案

① AとA
② AとA
③ AとD
④ BとA
⑤ BとA
⑥ AとD
⑦ BとB
⑧ BとB
⑨ A と D

(四)分析

①②③ 比較よく理解しましたが、一般的に問題は発生しません。実行時間多重性は、オブジェクトに対してコードを設定するための最も強力な仕組みであり、Java の動作時間の概念は、「単一のインターフェイス、複数のメソッド」とみなすこともできます。これは、実行中にメソッドを重畳する機構の 1 つであり、実行中にメソッドを重畳する仕組みです。多価性の 1 つの表現として、オーバーロードのオーバーロードがあります。子クラス内で特定のメソッドがその親クラスと同じ名前とパラメーターを持つ場合、そのメソッドは上書きされると考えています (オーバーライド)。子クラスのオブジェクトがこの方法を使用する場合、子クラス内の定義が使用され、同様に、親クラス内の定義は「シールド」されます。オーバーロードされたメソッドは、返される値の型を変更できますが、同時にパラメータのリストも異なります。参照量が子クラスのオブジェクトを参照する場合、参照量の型ではなく参照されるオブジェクトの型が使用する方法を決定しますが、この使用される方法は必ず超クラス内で定義されている必要があり、つまり、子クラスで覆われる方法です。 (ただし、子タイプを超過的に変換する方法があれば、子クラスに新たに追加することを制限することができます。)優先順位は高い順に次のようになります:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。

例えば④、a2.show(b)、a2 は参照変数、タイプは A、これは a2、b は B の一例です、その後、クラス A に進みます。show( B obj) 方法、未到達、次に A の super(超級) 、ただし A に超級がない、したがって 3 番目の優先順位 this.show((super)O) に遷移、これは確かに a2、この里 O はB、(super)O、つまり(super)B、A、したがって、クラスAの面にshow(A obj)のメソッドがあり、クラスAはこのメソッドを持っていますが、a2の参照はクラスBの1つのオブジェクトであるため、BはカバーされていますA の show(A obj) メソッドは、最終的にクラス B の show(A obj) に固定され、「B and A」として出力されます。

別の例は、⑧、b.show(c)、bは型Bの参照変数、次にこれはb、cはCのインスタンスなので、show(C obj)メソッドを見つけるためにクラスBに行きます。が見つかりません。B のスーパー クラス A を探します。A には誰もいないので、3 番目の優先順位の this.show((super)O) に進みます。これは b、O はです。 C、(super)O は (super) C は B であるため、B で show(B obj) メソッドを探し、それを見つけます。 b はクラス B のオブジェクトを参照しているため、show(B) に直接ロックされます。 obj) のクラス B。出力は「B および B 」です。 , 上記の方法によれば、他の結果も正しく取得できます。

質問は続きます。では、上記の分析プロセスが青いフォントの文の含意をどのように反映しているかを見てみましょう。スーパークラスのオブジェクト参照変数がサブクラス オブジェクトを参照する場合、参照変数の型ではなく、参照されるオブジェクトの型によって、どのメンバー メソッドが呼び出されるかが決まりますが、呼び出されるメソッドはスーパークラスで定義されている必要があります。 、サブクラスによってオーバーライドされるメソッド。 a2.show(b) を例として考えてみましょう。用 A2 は参照変数、型は A で、B のオブジェクトを引用します。したがって、この文の意味は、B によってどのメソッドが呼び出されるかを決定することです。したがって、「B と B」を出力するには、B の show(B obj) を呼び出す必要があります。しかし、なぜそれが以前の分析から得られた結果と一致しないのでしょうか? !問題は、青いフォントの後半を無視すべきではないということです。この部分には、具体的に次のことが示されています。呼び出されるメソッドは、スーパークラスで定義されている必要があります。つまり、サブクラスによってオーバーライドされるメソッドです。 B の show(B obj) はスーパークラス A で定義されていますか?いいえ!カバーされることは言うまでもありません。実際、この文にはメッセージが隠されています。メッセージは依然としてメソッド呼び出しの優先順位に従って決定されます。クラス A で show(A obj) を見つけます。サブクラス B が show(A obj) メソッドをオーバーライドしない場合は、A の show(A obj) を呼び出します (B は A を継承しているため、このメソッドはオーバーライドされていませんが、このメソッドはある意味では、呼び出されるメソッドは B によって決定されますが、そのメソッドは A に実装されます。サブクラス B は show(A obj) をオーバーライドするため、最終的に B の show(A obj) にロックされます。それがその発言の意味です。

浅いものから深いものまで紹介されたその他の JAVA ポリモーフィズム関連の記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。