Java覆盖,与示例不明确

时间:2018-08-01 04:05:27

标签: java inheritance multiple-inheritance ambiguous

我很难理解编译器如何在函数之间进行选择,可以说我们有一个示例:

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。

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(); //无效