我遇到了以下代码:

public class B extends A
{....}

public class C extends A
{...
 public boolean f(A a)
   {...}
}
//driver
...
A y1=new B();
B y2=new B();
A z1=new C();
C z2=new C();
//1 System.out.println(z1.f(z2));
//2 y1.dosmth()==((B)(z1).dosmth());

我最初以为#1是不正确的,因为f只能接收定义为A 的对象,但是显然,它也可以与A 的子代的对象一起使用(z2定义为C且是C的对象)。
继承不限于使用方法来接收与方法中定义的方法相同的参数吗?

关于#2:我知道只有对象具有任何继承关系,才可以进行强制转换。即我无法执行(Animal)table,但是它似乎在这里有效。
是因为B像C一样扩展了A吗?虽然在我看来,它仍然像(Dog)cat或类似的东西。

感谢您的输入!

最佳答案

好问题!

a表示a是A类型的。由于C是A的子代,因此System.out.println(z1.f(z2))有效。就像在说:

A a =新的C()

f(z2)-> f(a)

如果dosmth()位于A中,或者位于B和C中,则语句#2也应运行。我在下面的解释应有助于解释原因:

如果B和C扩展了A,则它们都具有A的所有非私有属性。

例如,如果A有一个公共方法getMe(),则B和C将有一个公共方法getMe(),无论您是否在B和C中都放置了getMe()方法。

但是,如果您在B和C类中都有一个getMe(),则覆盖可能会发生。发生覆盖时,子类的getMe()方法中的属性将优先于父类的getMe()方法。如果子类getMe()的属性与父类getMe()的属性不同,则覆盖可能会影响在对象上调用getMe()时发生的情况。如果您没有在B和C类中放置getMe(),则B和C将自动接收A的getMe()。

将子类对象设置为父类类型的变量,并在父类中未找到的父类变量上调用子类方法时,需要将父类转换为其子类。

动物var1 =新Dog()

动物var2 =新的Cat()

(狗)var1.bark()//因为不是所有的动物都吠叫!

通过强制转换,您告诉编译器:“相信我!我知道这是一只狗。随它去吧!”,因为编译器不知道您使用的是哪种Animal类型。编译器仅知道它正在处理Animal。由于Animal类没有bark()方法,因此编译器会认为不进行强制转换时会发生错误。通过将Animal投放到Dog,您是在告诉编译器假定Animal的此特定实例是Dog。

希望这可以帮助!

09-25 20:43