【发布时间】:2017-01-10 03:49:42
【问题描述】:
///Example code here
Superclass{
method1(){
print(do1);
}
method2(){}
}
Subclass extends Superclass{
///override method1
method1(){
print(do2);
}
method3(){}
}
我对java中的多态性有一个疑问,就是Superclass s =new Subclass()。 “s”对象总是调用超类中的方法,但是当覆盖方法发生时,“s”将指向覆盖方法。
更新: 所以,问题是谁来为引用“s”创建一个堆地址,如果它最终可以编译和运行。如果超类创建了它,为什么是 new Subclass() 而不是 new Superclass()。如果子类创建了它,为什么不能使用 s.method3()。
【问题讨论】:
-
真的不清楚你在这里问什么。您能否提供一个不符合您预期的minimal reproducible example? (除此之外,我会忽略任何堆栈/堆的区别——专注于“引用”与“对象”和“编译时类型”与“执行时类型”。这些与讨论更相关。)
-
@fabian,当然,s 被声明为超类,但堆地址是为子类创建的,对吧?并且“s”指向 HEAP
-
@JonSkeet,这让我很困惑,因为我一直认为 new Object() 实际上在堆中创建了一个新地址,所以无论如何引用都应该指向真实地址
-
再一次,您将注意力集中在堆栈与堆上,而没有明确解释什么让您感到困惑。
-
s在运行时指向什么并不重要。 编译器 不允许您在Superclass类型的表达式上调用method3。这发生在使用该代码的程序中存在堆栈/堆之前。您可以通过强制转换访问s中的method3,但如果该对象实际上不是Subclass的Subclass子类,您将在运行时获得ClassCastException:((Subclass) s).method3()。
标签: java polymorphism overriding heap-memory stack-memory