如果我有两个班级,A 和 B,
public class A {
public int test() {
return 1;
}
}
public class B extends A{
public int test() {
return 2;
}
}
如果我这样做:A a1 = new B()
,则a1.test()
根据需要返回 2 而不是 1。这只是 Java 的一个怪癖,还是这种行为有某种原因?
如果我有两个班级,A 和 B,
public class A {
public int test() {
return 1;
}
}
public class B extends A{
public int test() {
return 2;
}
}
如果我这样做:A a1 = new B()
,则a1.test()
根据需要返回 2 而不是 1。这只是 Java 的一个怪癖,还是这种行为有某种原因?
这称为多态性。在运行时,将根据“真实”类型调用正确的方法a1
,B
在这种情况下。
正如维基百科所说:
多态性在工业中的主要用途(面向对象编程理论)是属于不同类型的对象能够响应同名的方法、字段或属性调用,每个调用都根据适当的特定于类型的行为。程序员(和程序)不必事先知道对象的确切类型,因此确切的行为是在运行时确定的(这称为后期绑定或动态绑定)。
不,这是正确的(这是由于多态性)。所有方法调用都对对象进行操作,而不是引用类型。
在这里,您的对象是类型,因此将调用B,
测试方法。class B
这是预期的行为。B 类中的方法test()
覆盖test()
A 类的方法。
为了
A a1 = new B();
a1
指向 B 的对象,它是运行时的真实类型。因此值是从对象 B 打印的。
A obj = new A();
obj.test()
将返回 1
A obj = new B();
obj.test()
将返回 2
B obj = new B();
obj.test()
将返回 2
如其他答案所述,这就是多态性的工作方式。
这篇文章可能会让事情变得更清楚
Java 使用动态绑定(或后期绑定),所以B
调用 的方法,而不是A
。这与静态绑定相反。这里有一个很好的例子。
您将对象声明为 A,但您的实例是 B。因此,将调用的方法来自 B 类。B 扩展了 A(我们可以说 A 是 B 的父级),如果您将在 B 中注释方法测试然后回想一下方法,在这种情况下,调用的方法将从 A 类测试并返回 1。