覆盖java中的方法,然后将对象转换为父类行为
我有一个父类A和一个子类,B和B覆盖了一个方法f,来自A.
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(bf()); //prints: B } }
我创建了一个类型为B,b的对象,并将其转换为类型A并将其分配给类型为A的变量a,然后在a上调用方法f。 现在我希望调用父类的方法,因为我正在处理类型A的对象,但事实并非如此,它调用方法的b版本(打印“B”而不是“A”)下面的代码)。
为什么会这样? 这是设计决策还是技术限制?
这是多态性的基础
它应该像那样工作。
根据对象的实际类型而不是引用它的类型动态地调度(选择/调用)任何方法。
将对象转换为其他类型时,只需使用其他类型引用它。 对象的实际类型不会更改。 (它永远不会改变)。
因此,您正在观察的行为符合预期,并且它的设计就是这样。 这绝对不是限制。
希望这可以帮助。
这是一个设计决定。 你已经创建了一个类型为“B”的对象,这就是它的本质。
当你把它强制转换为A时,你只是告诉解释器,预期在类型A的类中找到的方法可用于B,但由于你有一个B的@Override方法,它将使用它。
A a =(A)b;
通过转换变量a
,引用没有改变,因此仍然调用方法f
因为方法调用是多态的
当您转换实例时,您只是暗示它可能是来自超类的实例,但该实例的内部实现不会改变,这就是您获得该结果的原因!
比喻说,如果你在英国人(演员)上使用美国人的面具,那个人仍然是英语(inheritance),但如果你要求那个人说话(称呼一种方法),你仍会听到英国口音,而不是美国人(内部实施最终是重要的):-)
这就是它应该如何工作。 它在B
上调用方法,因为这是变量被实例化的方式。 它所分配的变量的类型不会改变a
实际上是B
类的事实。 大多数语言都是这样的,包括C#。