私はこの問題についていくつかの研究開発を行い、あなたの混乱を取り除くための解決策を考え出しました。うまくいけば、それはあなたが理解するのに役立つでしょう。
以下のコードを探してください。
class A {
public void func(Number obj){
System.out.println("In a func");
}
public void func(Integer obj){
System.out.println("In b func");
}
}
class B extends A {
}
public class X {
public static void main(String s[]){
B b = new B();
b.func(3);
A a = new B();
a.func(3);
}
}
このコードを実行すると、次の出力が得られます:
"In b func"
"Inbfunc"。
この場合、次の4つの方法があります。
- クラスAには、オーバーロードされたメソッドfunc(Number)[say method 1]とfunc(Integer)[saymethod2]の両方があります。
- クラスBにも、継承のために2つのメソッドがあります。つまり、func(Number)[say method 3]とfunc(Integer)[say method4]があります。
ここで、Bを参照してb.func(3)を呼び出すと、「メソッド3」と「メソッド4」が表示されます。これらは、派生クラスに最も適合するパラメーターを持っています。ここでは、NumberクラスとIntegerクラスの両方が引数3に適合していますが、IntegerはNumberから派生しているため、func(Integer)[method3]が呼び出されます。したがって、出力は「Inbfunc」です。
同じロジックのため、2番目の出力も「Inbメソッド」です。まず、クラスAが持っていないクラスA参照のメソッドを呼び出すことはできないことを覚えておいてください。したがって、それらのメソッドは、それが持つクラスAを参照する場合にのみ呼び出すことができます。インスタンスがクラスAであるか、サブクラスのインスタンスであるかに関係なく。
コンパイルとリンクと実行の2つの用語でそれを理解する必要があります。
現在、クラスAは両方のメソッドを持っているので、コンパイラがクラスAの参照でa.func(3)を調べると、コンパイラはクラスAの「メソッド1」と「メソッド2」を調べ、引数を持つメソッドシグネチャをバインドします。最も適合する派生クラス。「func(Integer)」もそうです。
これで、実行時にfunc(Integer)が実行され、インスタンスがクラスBであるため、クラスBから呼び出されます(実行時に、メソッドは、インスタンスがメソッドを呼び出しているクラスから実行されます)。したがって、メソッド4が呼び出されます。したがって、出力。
確かに、メソッド2が呼び出されず、メソッド4が呼び出される理由について混乱が生じるでしょう。
以下のコードを実行する場合:
class A {
public void func(Number obj){
System.out.println("In a func");
}
public void func(Integer obj){
System.out.println("In b func");
}
}
class B extends A {
public void func(Number obj){
System.out.println("In a func of class B");
}
public void func(Integer obj){
System.out.println("In b func of class B");
}
}
public class X {
public static void main(String s[]){
B b = new B();
b.func(3);
A a = new B();
a.func(3);
}
}
出力は次のようになります。
クラスBの
InbfuncクラスBのInbfunc
これで、上記の説明でこのコードを理解できます。クラスAまたはクラスBを参照してfun(3)を呼び出しました。クラスBのメソッドが呼び出されるたびに(メソッド4)。インスタンスがクラスBであるためです。ただし、クラスAにない場合(メソッド2)。メソッド4は「a.func(3)」では呼び出されません
以下のコードを見てみましょう。
class A {
public void func(Number obj){
System.out.println("In a func");
}
}
class B extends A {
public void func(Integer obj){
System.out.println("In b func");
}
}
public class X {
public static void main(String s[]){
B b = new B();
b.func(3);
A a = new B();
a.func(3);
}
}
このプログラムの出力は次のとおりです
。InbfuncIn
afunc
今、あなたは混乱するかもしれませんが、なぜそれが異なる出力なのですか?
ここに4つの方法がないことを忘れないでください。ここに3つの方法だけがあります:
- クラスAのfunc(Number)
- クラスAから継承されたクラスBのfunc(Number)
- クラスBのfunc(整数)
ここで、a.fun(3)を呼び出すと、クラスAにはfunc(Integer)がなく、クラスにないクラスAを参照してメソッドを呼び出すことはできません。したがって、クラスAにはそのようなメソッドがないため、コンパイラはfunc(Integer)をバインドしません。ただし、同じコードで呼び出すことができる別のメソッドfunc(Number)があります。a.func(3)Javaのオートボクシングの概念。
したがって、a.func(3)が呼び出されると、基本的にfunc(Number)が呼び出されます。インスタンスがクラスBであるため、クラスBのメソッドfunc(Number)が呼び出されます。したがって、出力は「機能中」です。
これは非常に大きな答えですが、深く説明したので、さまざまなユースケースでの出力のさまざまな可能性を簡単に理解できます。
コーディングをお楽しみください!