我很难理解编译器如何在函数之间进行选择,可以说我们有一个示例:
A级:
public class A {
public void foo(A a,B b){
System.out.println("#1");
goo(a,b);
}
public void goo(A a1,A a2){
System.out.println("#2");
}
B级:
public class B extends A {
public void foo(C c,A a){
System.out.println("#3");
goo(a,c);
}
public void goo(C c,B b){
System.out.println("#4");
}
C类:
public class C extends B {
public void foo(C c,B b){
System.out.println("#5");
goo(c,b);
}
public void goo(A a,B b){
System.out.println("#6");
goo(b,a);
}
public void goo(B b,C c){
System.out.println("#7");
goo(c,b);
}
主要:
public static void main(String[] args){
A a=new C();
B b= new C();
C c = new C();
c.foo(c, c);//output #5 #4
b.foo(c, c);//compilation error
b.goo(null, null);//output #4
c.goo(a,c);//output #6 #2
为什么我们在“ b.foo(c,c);”中收到编译错误并在“ c.foo(c,c);”中我们打印#5#4吗?
这两个电话之间有什么区别?
在“ b.goo(null,null); //输出#4”中为什么输出不是#2?
c.goo(a,c); //输出#6#2 为什么我们打印#6而不是#7, 然后我们打印#2。
答案 0 :(得分:0)
这里有两个概念:重载和重载。
覆盖
覆盖的好处是:定义行为的能力 特定于子类类型,这意味着子类可以实现 父类方法根据其要求。在面向对象 术语,覆盖是指覆盖现有功能 方法。
用简单的话来说:如果一个子类的父类的方法具有相同的签名,则它告诉JVM:“当调用此方法时,不用我的父类方法!”
超载
重载允许不同的方法具有相同的名称,但名称不同 签名,签名可能因输入参数或 输入参数的类型或两者兼有。重载与编译有关 时间(或静态)多态性。
用简单的话来说,具有相同名称但参数数目或类型不同的方法是不同的方法,是否扩展该类都没有关系。
调用重载方法时,JVM会在编译时尝试使调用适合该方法的每个定义,如果调用不符合任何可能的定义,则会遇到编译问题METHOD NOT FOUND(如果适合更多方法)定义不止一个AMBIGUOS定义
尝试研究您的案例:
public static void main(String[] args){
A a=new C();
B b= new C();
C c = new C();
c.foo(c, c);//output #5 #4
b.foo(c, c);//compilation error
b.goo(null, null);//output #4
c.goo(a,c);//output #6 #2
}
您将所有对象实例化为C
,但是对于JVM,=
右侧的内容无关紧要,您的调用将处理左侧类型的方法断言的一面
答案 1 :(得分:0)
您可以参考下面的示例以更好地理解:
abstract class C1
{
abstract void f1 ();
abstract void f2 ();
};
abstract class C2 extends C1
{
void f1 ()
{
System.out.println("f1-C2-original");
}
};
class C3 extends C2
{
void f1 ()
{
super.f1 ();
System.out.println ("f1-C3-OVERRIDDEN");
}
void f2 (){
System.out.println ("f2-C3");
}
void f3 ()
{
System.out.println ("f3-C3-SPECIALLY DEFINED");
}
};
class AbDemo1
{
public static void main (String k [])
{
C3 o3=new C3 ();
o3.f1 ();
o3.f2 ();
o3.f3 ();
// C2 o2=new C2 (); invalid
C2 o2=new C3 ();
o2.f1 ();
o2.f2 ();
// o2.f3 (); invalid
C1 o1=new C3 (); // or o2
o1.f1 ();
o1.f2 ();
// o1.f3 ();
}
};
输出:
关于具体类别:
C3 o3 =新的C3();
o3.f1(); // f1-覆盖-C3
o3.f2(); // f2-C3
o3.f3(); // f3-在-C3中定义
关于抽象派生类:
C2 o2 =新的C2(); //无效
C2 o2 = new C3();
o2.f1(); // f1-覆盖-C3
o2.f2(); // f2-C3
o2.f3(); //无效
关于抽象基类:
C1 o1;
o1 = o2; //表示新C3()
o1.f1(); // f1-覆盖-C3
o1.f2(); // f2-C3
o1.f3(); //无效