Java中的强制转换
如果我有一个类Java中的强制转换,java,Java,如果我有一个类A,它有一个方法foo(),还有一个类B,它从A扩展并覆盖foo()。如果我写A A=newb()
A
,它有一个方法foo()
,还有一个类B
,它从A
扩展并覆盖foo()
。如果我写A A=newb()然后我写((A)A).foo()
-哪个foo
将被激活?一方面,动态类型是B
,并且foo()
被很好地覆盖,另一方面-此强制转换是否使a成为a
的动态类型?否,实例将始终保持B
。您使用new创建了B
,并且强制转换它不会更改对象的实际实例。请尝试并查看
(扰流板:B中的'foo'将覆盖'A'中的'foo',因此即使您执行((A)A).foo()
您也将执行B中的'foo'。这在OO语言中很常见。B.foo()
将被调用。如果B
没有覆盖/实现方法,将调用a.foo()
(如果定义了a.foo()
。考虑下面的代码。
通过将b
强制转换为A
可以将访问权限限制为仅在A
中声明的公共成员(或其任何继承的公共成员),但在涉及公共方法的实现时,将忽略强制转换或变量的声明方式。重要的只是变量的实际数据类型(不是如何声明它,而是如何创建它)
与其将b
转换为A
,不如像这样创建b
:ab=newb()
。它的行为方式与您将其声明为B
时相同,但将其转换为A
当涉及到调用方法时,对象的声明和/或强制转换只提供“接口”(即使声明/强制转换的类型是类,也可以将其视为只包含相应类声明或继承的公共方法的接口)。这些方法的实现是由实际数据类型提供的
public class Temp {
public static void main(String[] args) {
B b = new B();
((A) b).foo(); // real type is B
b.fooA();// real type is B, but B doesn't override fooA() so the implementation is inherited from A
// ((A) b).fooB(); error: `A` doesn't know about fooB
b.fooB();
C c = new C();
c.foo(); // real type is C, but C doesn't override foo() so the implementation is inherited from B
A b1 = new B();
b1.foo(); // real type is B
A a = new A();
a.foo(); // real type is A
}
}
class A {
public void foo() {
System.out.println("A");
}
public void fooA() {
System.out.println("fooA");
}
}
class B extends A {
@Override
public void foo() {
System.out.println("B");
}
public void fooB() {
System.out.println("fooB");
}
}
class C extends B {
}
产出:
B
B
fooA
fooA
fooB
B
B
A
为什么不编写一些非常简单的代码,自己看看呢?simple不能解释这种强制转换在这种情况下的真正含义。dynamic恰恰意味着a将是B的实例。为了证明,创建一个C类,它像B一样扩展a,并在运行时随机选择a=new B或new C。这是非常动态的!显式地将a转换为a不会在方法调用时执行任何操作。通常,当您不关心实现和/或您可能希望支持其他不同的实现者时,您会保留父对象类型中的子类(或接口)。把一个B对象放在一个a中,你只是把自己局限于a的方法。那么它到底做了什么呢?我从来没有真正明白过。@Nir对于你刚才在评论中提出的这个问题,最简单的答案并不是最好的答案。最好的答案是你翻出你的书,学习多态性的基础知识,然后你就可以自己回答这个问题了。例如,B有一个函数notInA()
,而你有一个对象a=new B()
然后必须强制转换到B:((B)a).notInA()
才能访问此函数。但是San Jacinto是对的,阅读多态性,什么都没有。在java中,向上转换是不可操作的。编辑:我说谎。它所起作用的一个地方是现场访问。如果A和B都声明了一个字段x,那么((A)obj).x和((B)obj).x不引用同一个位对象。我认为将值强制转换为A没有意义,因为在Java中方法总是虚拟的。对于C语言或C++语言来说,这并不常见。