重写java中的方法,然后将对象强制转换为父类行为
我有一个父类a和一个子类B,B从a重写了一个方法f重写java中的方法,然后将对象强制转换为父类行为,java,inheritance,Java,Inheritance,我有一个父类a和一个子类B,B从a重写了一个方法f public class A { public String f() { return "A"; } } public class B extends A { ... public String f() { return "B"; } public static void main(String[] args) { B b
public class A
{
public String f()
{
return "A";
}
}
public class B extends A
{
...
public String f()
{
return "B";
}
public static void main(String[] args)
{
B b = new B();
A a = (A) b;
System.out.println(b.f()); //prints: B
}
}
我创建了一个类型为B,B的对象,并将其转换为类型A,并将其分配给类型A,A的变量,然后对A调用方法f。现在我希望调用父类的方法,因为我正在处理类型为A的对象,但它没有,它调用方法的b版本(在下面的代码中打印“b”而不是“A”)
为什么是这样?这是设计决定还是技术限制?当您转换实例时,您只是暗示它可能是来自超类的实例,但该实例的内部实现不会改变,这就是为什么您会得到该结果 打个比方,如果你在英国人身上戴上美国人的面具(cast),那个人仍然是英国人(继承),但如果你让那个人说话(调用方法),你仍然会听到英国口音,而不是美国口音(最终重要的是内部实现):-) A=(A)b
通过强制转换变量
a
引用没有改变,因此方法f
仍然被调用,因为方法调用是多态的这是一个设计决策。您已经创建了一个类型为“B”的对象,所以它就是这样
当您将其强制转换为A时,您只是告诉解释器在类型A的类中预期会找到的方法可用于B,但由于您有一个@Override方法用于B,它将使用它。这就是它应该如何工作的。它在
B
上调用方法,因为变量就是这样被实例化的。分配给它的变量类型不会改变a
实际上是B
类型的事实。大多数语言都是这样的,包括C#。这是多态性的基础
它应该是这样工作的。
根据对象的实际类型动态调度(选择/调用)任何方法,而不是根据引用它的类型
将对象强制转换为其他类型时,只需使用其他类型引用它。对象的实际类型不会更改。(它永远不会改变)
所以你所观察到的行为和预期的一样,它就是这样设计的。这绝对不是限制
希望这能有所帮助。如果要在a
中执行f
的实现,您需要一个新的a()
。或的可能重复