我正在学习Java,并且正在做此练习,我必须说一下主要方法输出的内容。其目标是更好地理解Java继承。

interface X extends Remote{
    A m(B bb) throws RemoteException;
}

class A implements Serializable{
     int a;
     A m(A aa){
         aa.a = 3;
         System.out.println("A.m");
         return aa;
     }
}

class B extends A{
     int b;
     A m(B bb){
        bb.b = 7;
        System.out.println("B.m");
        return bb;
     }
}

class C extends A implements X{
    public B m(B bb){
        if(bb.b == 7) bb.b = 9; else bb.b = 1;
        System.out.println("C.m");
        return bb;
    }
}


现在,我有一个主要方法可以调用:

X x = new C();
B b = new B();
(x.m(b)).m(b);   // prints C.m() A.m()


我的主要方法的第三行显示“ C.m()A.m()”,但我不明白为什么它显示A.m()。 x.m(b)返回具有静态和动态类型== B的对象;在此对象上调用m(b)方法;那么为什么它不被称为B类的m()方法呢?

我已经看到B类中的m()方法不是A类中的m()方法的重写,因为它们具有不同的显式参数。

提前致谢

最佳答案

b实例中的B,该实例扩展了A。因此,B具有2个m方法。

要知道哪个被调用,重要的是调用该方法的对象的类型。

(x.m(b))


是从m接口调用X方法的结果,因为x的声明类型为X

因此,(x.m(b))是类型为A的对象(即使实际实现是B)。

这是类型A,将调用m类中的A方法。

如果更改方法的名称,将会更清楚地看到mA中的B方法实际上是不同的对象。

你的错误是假设


  x.m(b)返回具有静态和动态类型== B的对象;


这是错误的,因为x声明为X类型,从而使x.m的结果成为A类型。

10-05 19:38