Java Polymorphicオブジェクトのタイプ変換<br />ここに記載されているオブジェクトタイプ変換は、どのタイプのオブジェクトではなく、継承関係を持つオブジェクトを指します。相続関係がないオブジェクトをキャストするとき、JavaランタイムはJava.lang.classcastexceptionの例外を投げます。
継承チェーンでは、親クラスへのサブクラス変換「上向き変換」と子クラスへの変換「下向き変換」を呼び出します。
多くの場合、変数を親クラスのタイプとして定義しますが、このプロセスのオブジェクトは上向きの変換です。プログラムが実行されると、動的バインディングを使用して、サブクラスメソッド、つまり多型への呼び出しを実現します。
ただし、一部の親クラスが持たない機能を完了するためには、上向きに変換されたサブクラスオブジェクトをサブクラスに変換し、下向きの変換であるサブクラスメソッドを呼び出す必要があります。
注:親クラスのオブジェクトは、サブクラスタイプに直接キャストすることはできません。上向きの変換後のサブクラスオブジェクトは、再びサブクラスタイプにのみ変換できます。言い換えれば、サブクラスオブジェクトは、下向きに変換する前に上方に変換する必要があります。次のコードをご覧ください。
Public Class demo {public static void main(string args []){superclass superobj = new superclass();親はサブクラスタイプです。7行目のコメントを削除すると、実行時に例外がスローされますが、コンピレーションは渡すことができます。
親クラスへの参照を受信する場合、オブジェクトが必要なサブクラスであるかどうかを確認するには、親クラスへの参照を受信するリスクがあるため、次のコードをご覧ください。
パブリッククラスデモ{public static void main(string args []){superclass superclass(); =(superobj; system.out.println( "superobj); )superobj; else {system.out.println( "inclase for converted")実行結果:
convert変換できません
概要:プログラムが実行されると、オブジェクトのタイプがチェックされます。
Java多型と動的結合<br /> Javaでは、親クラスの変数は、親クラスのインスタンスまたは子クラスのインスタンスを参照できます。
最初にコードを読んでください:
Public Class Demo {String [] Args = new Animal(); .cry();クラス動物{// public void cry(){system.out.println( "私は何を呼ぶべきか}} Call of Cat Public void Cry(){System.out.println( "Meow〜"); }}実行結果:
Meow〜ウールを呼ぶ方法がわかりません〜
上記のコードは、動物、猫、犬のクラス、つまり動物のクラスから継承されている3つのクラスを定義しています。 OBJ変数には、動物のクラスのインスタンスや猫や犬のクラスのインスタンスを指すことができるタイプの動物があります。つまり、親クラスの変数は、親クラスのインスタンスまたは子クラスのインスタンスを参照できます。すべての猫は動物であるが、すべての動物が猫ではないため、逆の方法は間違っていることに注意してください。
OBJは、人間、猫、または犬のいずれかであることがわかります。多型とは、異なる形や形を持つものを指します。
たとえば、「人間」には、さまざまな表現や実装もあります。 、教師、または次の人生で医師。
多型が存在するために必要な3つの条件があります:継承、書き換え、および親変数は、サブクラスオブジェクトを参照しています。
多型方法を使用してメソッドを呼び出すとき:
最初に、親クラスにメソッドが存在するかどうかを確認します。
サブクラスがメソッドをオーバーライドすると、サブクラスのメソッドが呼び出されます。そうしないと、親クラスメソッドが呼び出されます。
上記の例から、多型の利点の1つは、多くのサブクラスがある場合、複数の変数を定義する必要がないことがわかります。次の例をご覧ください。
Public Class Demo {public static void main(string [] args){//ポリ型の助けを借りて、飼い主は多くの動物を養うことができます。 )Ma.Feed()、New fied(); ){system.out.println(「私は小動物です、食べています」 + f.getfood());小さな猫が食べています " + f.getfood());}}授業犬は動物{public void eat(food f){system.out.println("私は犬、食べている " +f。getfood())) ; //そのサブクラスクラスの食べ物{return "shings"; string getFood(){return "Bone";実行結果:
私は小さな動物で、物を食べています、私は小さな猫で、魚を食べています、私は犬です、骨を食べています
マスタークラスのフィード方法には、動物の種類と食品タイプの2つのパラメーターがあります。別の動物。
動的バインディング
多型の性質を理解するために、以下のJava呼び出し方法の詳細なプロセスについて話しましょう。
1)コンパイラは、オブジェクトの宣言タイプとメソッド名をチェックします。
obj.func(param)と呼ばれると仮定すると、objは猫のクラスのオブジェクトです。 FUNCを持つ名前が異なるパラメーターが異なる複数のメソッドが存在する場合があることに注意する必要があります。たとえば、Method func(int)およびfunc(string)が存在する場合があります。コンパイラは、CATクラスのFUNCという名前のすべての方法をリストし、属性パブリックと名前付きFUNCにアクセスする方法を親クラスアニマルにリストします。
このようにして、コンパイラは、呼び出されるすべての可能な候補方法のリストを取得します。
2)次に、エディターは、メソッドを呼び出すときに提供されるパラメーター署名を確認します。
提供されたパラメーター署名と正確に一致するFUNCという名前のすべてのメソッドにメソッドがある場合は、この方法を選択します。このプロセスは、過負荷解像度と呼ばれます。たとえば、func( "hello")と呼ばれる場合、コンパイラはfunc(int)の代わりにfunc(string)を選択します。たとえば、自動型変換のため、Methodパラメーターの署名と同じ署名を使用しては、型に変換できます終了または複数のメソッドはそれと一致し、エラーをコンパイルします。
このようにして、コンパイラは呼び出される必要があるメソッド名とパラメーターの署名を取得します。
3)Method Modifierがプライベート、静的、最終的なものが後で説明される場合、またはコンストラクターである場合、コンパイラはこの方法を正確に呼び出すことができます。
それに対応して、呼び出された方法はオブジェクトの実際のタイプに依存し、実行時に動的結合を実装します。たとえば、FUNC( "Hello")を呼び出す場合、エディターは動的バインディングを使用して、FUNC(String)を呼び出す指令を生成します。
4)プログラムが動的バインディングを実行して使用してメソッドを呼び出すと、JVMは、OBJが参照するオブジェクトの実際のタイプに最も適したクラスのメソッドを間違いなく呼び出します。 OBJの実際のタイプは動物のサブクラスであるCATであると想定しており、FUNC(String)がCATで定義されている場合に呼ばれます。そうしないと、動物クラスとその親クラスで検索されます。
メソッドへの各呼び出しには、非常に高価な検索が必要です。したがって、JVMは各クラスのメソッドテーブル(メソッドlable)を作成します。このようにして、メソッドが実際に呼び出された場合、仮想マシンはこのテーブルのみを調べることができます。上記の例では、JVMはCATクラスのメソッドテーブルを検索して、FUNC( "Hello")の呼び出しに一致するメソッドを見つけます。この方法は、cat.func(string)またはanimal.func(string)のいずれかです。 Super.func( "Hello")が呼び出された場合、コンパイラは親クラスのメソッドテーブルを検索することに注意してください。
動物のクラスには3つの方法が含まれていると仮定します。Cry()、getName()、およびgetage()、そのメソッドテーブルは次のとおりです。
cry() - > animal.cry()
getname() - > animal.getname()
getage() - > animal.getage()
実際、動物にはデフォルトの親クラスオブジェクト(後で説明される)もあり、オブジェクトメソッドを継承するため、上記の方法は完全ではありません。
猫のクラスが動物クラスのcry()メソッドをオーバーライドし、新しい方法Climbtree()を追加すると仮定すると、そのパラメーターリストは次のとおりです。
cry() - > cat.cry()
getname() - > animal.getname()
getage() - > animal.getage()
climbtree() - > cat.climbtree()
実行するとき、obj.cry()メソッドを呼び出すプロセスは次のとおりです。
JVMは最初に、動物クラスのメソッドテーブル、またはCATクラスとそのサブクラスのメソッドテーブルである可能性がある、実際のタイプのOBJのメソッドテーブルにアクセスします。
JVMは、メソッドテーブルでcry()に一致するメソッドを検索し、それを見つけた後、どのクラスに属するかがわかります。
JVMはこの方法を呼び出します。