为什么向上转型不显示运行时多态性?
我写了一段代码来理解运行时多态性...
I wrote a code to understand runtime polymorphism...
class S{
int i=1;
void m(){
System.out.println("sssssssssssssssssssss");
}
}
public class A extends S{
int i=2;
void m(){
System.out.println("aaaaaaaaaaaaaaaaaaaaaaaa");
}
public static void main(String[] args) {
S a=(S)new A();
System.out.println(a.i);
a.m();
}
}
实例变量受编译时绑定,但是为什么A
的对象向下转换在这里没有意义?意味着它调用的是 A's
方法而不是 S's
方法?
Instance variable are subject to compile time binding, but why down casting of object of A
does not meaning here? Means it's invoking A's
method not S's
method?
推荐答案
S a = (S)new A();
让我们看看你有什么:
- 变量
a
,引用类型S
; - 产生
A
类型对象的实例创建表达式,其中A extends S
; - 一个引用向上转换表达式,将上面的表达式向上转换成
S
类型; - 将3.的结果赋值给变量
a
.
- variable
a
, of the reference typeS
; - an instance creation expression yielding an object of type
A
, whereA extends S
; - a reference upcast expression, upcasting the above expression into type
S
; - the assignment of the result of 3. into the variable
a
.
阅读Java的时候一定要牢记在心的是:
What you must keep clear in your mind when reading Java is the distinction between:
- 对象的类型:一个对象永远不能改变它的类型.在您的示例中,该对象的类型为
A
; - 引用的类型:在您的示例中,您将最初类型为
A
的引用转换为类型为S
的引用.您将该引用分配给a
.
- the type of the object: an object can never change its type. In your example, the object is of type
A
; - the type of the reference: in your example, you converted a reference initially of type
A
into a reference of typeS
. You assigned that reference toa
.
当你调用一个对象的方法时,实际调用的方法根本不依赖于reference的类型,而只依赖于object的类型本身.您的对象的类型是 A
因此调用类型为 A
的方法.
When you invoke a method on an object, the actual method invoked does not at all depend on the type of the reference, but only on the type of the object itself. The type of your object is A
therefore the method in type A
is invoked.
另一方面,当您访问实例变量时,多态性不适用,并且引用的类型变得至关重要.使用 ai
您可以访问在超类型 S
中声明的 i
,使用 ((A)a).i
您可以访问从 A
访问 i
.请注意,类 A
拥有 两个 实例变量,都名为 i
,您可以分别引用每个变量.
On the other hand, when you access an instance variable, polymorphism does not apply and the type of the reference becomes essential. With a.i
you access i
declared in the supertype S
, and with ((A)a).i
you access i
from A
. Note that the class A
posseses two instance variables, both named i
, and you can refer to each individually.
术语参考类型"实际上是更正确的产生引用的表达式类型"的简写.它是一个纯粹的编译时工件:在运行时没有与引用关联的类型信息,它只是一个位模式.将此与对象的类型进行对比,对象的类型纯粹是 runtime 工件:编译器通常不知道表达式中涉及的对象的类型,它只会产生 assertions 关于它.当此类断言在运行时失败时,结果是 ClassCastException.
The term "type of a reference" is actually a shorthand for the more correct "type of the expression yielding the reference." It is a purely compile-time artifact: there is no type information associated with a reference at runtime, it's just a bit pattern. Contrast this with the type of the object, which is a purely runtime artifact: the compiler doesn't in general know the type of the object involved in an expression, it only makes assertions about it. When such an assertion fails at runtime, the result is a ClassCastException.
相关文章