重複の可能性:
Javaの継承-説明してください
私はJavaを学んでいて、2つの質問があります。
違いは何ですか:
A x = new A();
と
A x = new B();
それを考慮して:
class A class B extends A
違いは何ですか:
A x = new B(); (A)x.run_function();
AとBの両方に関数が
run_function
あり、どちらが実行されるとしましょう。
重複の可能性:
Javaの継承-説明してください
私はJavaを学んでいて、2つの質問があります。
違いは何ですか:
A x = new A();
と
A x = new B();
それを考慮して:
class A
class B extends A
違いは何ですか:
A x = new B();
(A)x.run_function();
AとBの両方に関数がrun_function
あり、どちらが実行されるとしましょう。
最も重要な違いは、オブジェクトとオブジェクトへの参照の静的タイプと動的タイプの違いです。
B が A を拡張し、C が B を拡張するとします。
オブジェクトの動的型 (new で使用される型) は、その実際のランタイム型です。オブジェクトに存在する実際のメソッドを定義します。
オブジェクト参照 (変数) の静的型はコンパイル時の型です。変数が参照するオブジェクトでどのメソッドを呼び出すことができるかを定義、または宣言します。
変数の静的型は常に、参照するオブジェクトの動的型と同じ型またはスーパータイプである必要があります。
したがって、この例では、静的型 A の変数は動的型 A、B、および C のオブジェクトを参照できます。静的型 B の変数は、動的型 B および C のオブジェクトを参照できます。静的型 C の変数は、動的型 B および C のオブジェクトのみを参照できます。動的タイプ C。
最後に、オブジェクト参照でのメソッドの呼び出しは、静的型と動的型の間の微妙で複雑な相互作用です。(信じられない場合は、メソッド呼び出しに関する Java 言語仕様を読んでください。)
たとえば、A と B の両方がメソッド f() を実装し、静的型が A で、メソッド呼び出しに関連する動的型が C である場合、Bf() が呼び出されます。
B extends A, C extends B
public A.f() {}
public B.f() {}
A x = new C(); // static type A, dynamic type C
x.f(); // B.f() invoked
大幅に単純化: 最初に、受信側 (型 A) と引数 (引数なし) の両方の静的型を使用して、その特定の呼び出しに最適な (最も具体的な) メソッド署名を決定します。これはコンパイル時に行われます。ここでは、これは明らかに Af() です。
次に、実行時の 2 番目のステップで、動的型を使用して、メソッド シグネチャの実際の実装を特定します。タイプ C から始めますが、f() の実装が見つからないため、B に移動すると、Af() のシグネチャに一致するメソッド Bf() があります。したがって、Bf() が呼び出されます。
この例では、メソッド Bf() がメソッド Af() をオーバーライドすると言います。型階層でメソッドをオーバーライドするメカニズムは、サブタイプ ポリモーフィズムと呼ばれます。
1.で
A x = new A();
x
A
タイプ とのインスタンス化ですA
。
一方、
A x = new B();
x
B
タイプ とのインスタンス化ですA
。
2.ここで注意すべき重要なことは、(2 番目のケースで) を呼び出すとx.someMethod()
、 のメソッドでB
はなく のメソッドが呼び出されることですA
(これは、静的バインディングではなく動的バインディングと呼ばれます)。なお、キャストはタイプのみ変更するので、
A x = new B();
((A)x).run_function(); // Need extra parenthesis!
B
は引き続きのメソッドを呼び出します。
上で述べたように、余分な括弧を含める必要があります。
(A)x.run_function();
と同等です
(A)(x.run_function());
ケース1:
AにないメソッドがBにある場合、違いがわかります。
参照'x'を使用してそのメソッドを呼び出そうとすると、表示されません。
ケース2:
すべてのメソッド呼び出しは、ポリモーフィズムのために参照型ではなくオブジェクト型に基づいて行われます(静的メソッドを除く)
A x = new B();
この場合、B
クラスrun_function
が実行されます。
A x = new A();
この場合、A
クラスrun_function
が実行されます。
さらに:
A x = new B()
B
で定義されているメソッドと で定義されていないメソッドを実行することはできませんA
。ただし、前に示したように、Java のポリモーフィズムにより、何らかのメソッドを実行し、B'
これらのメソッドをオーバーライドした場合、B
の実装が使用されます。
1.What is the difference between: A x = new A();and A x = new B();
違いは、最初のケースでは、タイプAのクラスをインスタンス化することです。したがって、Aで定義されたメソッドのみを呼び出すことができます。2番目のケースでは、同じ名前のメソッドがAとBの両方に存在する場合、 B実装は実行時に呼び出されます。
ただし、2番目のケースでは、リフレクションを使用して、クラスAではなくクラスBで定義されているメソッドを呼び出すこともできます。
A x = new B(); (A)x.run_function();
AとBの両方に関数run_functionがあり、どちらが実行されるとしましょう。
覚えておいてください-オーバーライドは実行時に決定されますが、オーバーロードはコンパイル時に決定されます。
したがって、クラスBのメソッドは、動的バインディングに基づいて実行時に呼び出されます。
実際の違いはありません。実際、2番目のケースでは、AはBオブジェクトを古いものにしますが、BはAなので問題ありません。この場合、B は A のように動作します。
B の run_function() を呼び出します