class Person { void f() {} }
class Student extends Person { void f() {} }
所以当我执行以下代码时:
Person p = new Student();
((Person) p).f();
为什么f()
将变量转换为 Person 时调用 Student 类中的函数?我理解为什么f()
在它只是 时调用该函数p.f()
,但我想我只是对演员表的确切作用感到困惑。
您始终可以将子类型转换为类型,但是在 java 中始终允许这种转换,因为实例是子类型的子类型方法将被执行。
您可以在此处查看更多信息在 Java 中有两种类型的引用变量转换:
是的,您需要直接或间接地实现接口,以便将您的类对象引用分配给接口类型。
调用方法时,由于 ploymorphsim,它将始终在对象类型上执行,而不是在引用类型上执行。
这是面向对象的基石之一:多态性。您有各种 Person 实体,每个实体都以自己的方式执行 f()!它是对象的实际实例,而不是 f() 所转换的对象。
无论您是否将 Student 转换为 Person,都会调用相同的方法——Student 中的方法。
向上转换引用(从子类到超类)没有真正的功能(实际上通常在内部是无操作的)。另一方面,向下转换告诉 JVM,您认为超类属于指定的子类,如果不是,则会引发转换错误。
(我会感谢 gefei 指出上面的一个遗漏:强制转换 ALSO 告诉编译器类型,编译器使用此信息来了解对象(假定)具有哪些方法和字段。这对于编译Java 程序到字节码,但它确实允许编译器进行通常的编译时有效性检查。)
向上转型在这里是无关紧要的。如果存在,将始终调用被覆盖的方法。
你的例子中的演员是完全没用的。编译器知道它p
是 type Person
。更有趣的是缩小范围:
Person p = getPerson();
if (p instanceof Student) {
Student s = (Student) p;
// do something Student-specific with s
}
在 Java 中强制转换引用类型不会改变对象的性质;它只告诉编译器可以对对象做出哪些假设。在运行时,对象的实际类型用于确定调用什么方法。(请注意,原始类型并非如此;将 anint
转换为 abyte
将更改数据。)