我遇到了以下代码:
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。
希望这可以帮助!