我试图理解 Java 中的多态性,但我无法理解 App.java
中的某些内容。
Q1) 为什么我们能够做到 p2=tree;
即使 p2
是对类 Plant
和 tree< 的引用
是类 Tree
的对象?
Q2)当我尝试执行此操作时,为什么会显示类型不匹配:无法从植物转换为树
:
tree=new Plant();
Q3) 为什么即使b2 的输出为 true
,p2.shed()
也会导致错误?如果p2
是tree
的实例,它应该能够访问Tree
方法。
App.java
public class App {
public static void main(String[]args){
Plant p1 = new Plant();;
Plant p2 = p1;
Tree tree = new Tree();
boolean b1= tree instanceof Plant;
p2=tree;
boolean b2= p2 instanceof Tree;
System.out.println(b1+" "+b2);
p2.grow();
tree.shed();
//p2.shed(); ---- Why is this an error?
}
}
Plant.java
public class Plant {
public void grow(){
System.out.println("Plant growing");
}
}
树.java
public class Tree extends Plant {
@Override
public void grow() {
System.out.println("Tree growing");
}
public void shed(){
System.out.println("Tree shedding");
}
}
最佳答案
答案:
1) Plant 是 Tree 的父类。
我希望你知道,当我们执行 Plant p = new Plant();
p 时,p 是引用。
new Plant()
是实际的对象。
因此,父引用可以指向子对象。因此您可以执行 p2=tree
或
Plant p2 = new Tree()
2)现在记住我上面写的观点。父引用可以指向子对象。 但是 子引用不能指向父对象
即你不能这样做 Tree t = new Plant();
3) 即使 p2 实际上指向 Tree 对象而不是 Plant 对象,你也不能执行 p2.shed()
。由于引用限制。
请参阅引用变量“p2”的类型为Plant,并且指向Tree的对象类型。 但是引用 p2 并不知道它指向的是 Tree 类型的对象。它认为它仅指向 Plant 类型的对象。
所以当你执行 p2.grow(
) 时,它认为它正在调用 Plant 类的 Growth() 方法,因为 p2 是 Plant 类型的引用。
但是当CPU(代码的执行器)转到p2指向的对象时,CPU发现这实际上是一个Tree对象并调用Tree的grow()方法而不是Plant类,并且因此它打印“树正在生长”而不是“植物正在生长”。
当你执行p2.shed()
时,你会得到编译器错误。 因为在 Plant 类中没有名为 shed() 的方法。即使 p2 指向的实际对象可能有一个带有 shed() 方法的 Tree 对象。编译不会发生。
因为引用 (p2) 不知道子对象中存在的新方法 shed()。
阅读:: Herbert Schildt - Java 完整引用。语言非常简单。
获得一些 Java 经验后,请阅读 Kathy Sierra SCJP 6 以深入了解 Java。
关于java - 关于Java多态性的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31040797/