Java转换为超类的多态性不改变对象类型?
我不明白为什么这个代码输出为false。Java使用对象类型(非引用)来选择要执行的[instance]方法,在本例中,初始对象类型为Owl(方法返回false),无论如何,我们将该类型转换为“夜间”(不必,但我们确实需要)。我在接口和类中有isBlind()方法
为什么我们的Owl
转换为Nocturnal
使用显式强制转换打印false,如果对象类型现在是夜间的,而夜间方法打印true
interface Nocturnal {
default boolean isBlind() {
return true;
}
}
public class Owl implements Nocturnal {
public boolean isBlind() {
return false;
}
public static void main(String[] args) {
Nocturnal nocturnal = (Nocturnal) new Owl();
System.out.println(nocturnal.isBlind());
}
}
# 1 楼答案
当子类重写其基类的方法时,每次从子类(包括基类)外部调用重写的方法都会导致调用重写的方法
铸件对方法的行为没有影响。如果它凌驾于外部世界之上
根据基类提供的行为调用方法的唯一方法是从子类的实例方法内部使用
super
关键字和.
(点运算符)# 2 楼答案
考虑OO编程的一种强大方式是将方法调用视为消息传递。您向对象发送一条消息“请给我
isBlind()
方法的结果”。对象会说“好的,我知道怎么做isBlind()
,做了,然后向调用者发送一条包含结果的消息您的
Owl
对象收到请求运行isBlind()
的消息。它不在乎它从哪里来。它不知道打电话的人知道什么。它只运行自己版本的isBlind()
并将结果发送回当您在调用者中强制转换到超类(或接口)时,调用者“忘记”它正在与
Owl
对话,但Owl
不知道这一点。它只是一如既往地处理消息这就是多态性如此强大的核心。这意味着您可以将
Owl
放入Nocturnal
的集合中,并对每个集合调用isBlind()
,得到正确的结果:随着面向对象编程的发展,您将遇到很多情况,这些情况非常宝贵。尤其是单元测试,在单元测试中,您可以用一个测试双重(有时是一个模拟)来替换与您正在测试的对象协作的对象
请注意,现代Java程序员往往不那么频繁地进行子类化,大多数时候更喜欢实现
interface
s。“更喜欢构图而不是继承”。同样的原则也适用于多态性