7

如果我有两个班级,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 的一个怪癖,还是这种行为有某种原因?

4

8 回答 8

5

这称为多态性。在运行时,将根据“真实”类型调用正确的方法a1B在这种情况下。

正如维基百科所说:

多态性在工业中的主要用途(面向对象编程理论)是属于不同类型的对象能够响应同名的方法、字段或属性调用,每个调用都根据适当的特定于类型的行为。程序员(和程序)不必事先知道对象的确切类型,因此确切的行为是在运行时确定的(这称为后期绑定或动态绑定)。

于 2012-09-04T15:31:22.213 回答
4

不,这是正确的(这是由于多态性)。所有方法调用都对对象进行操作,而不是引用类型。

在这里,您的对象是类型,因此将调用B,测试方法。class B

于 2012-09-04T15:30:51.767 回答
2

这是多态性,更具体地说是在 Java覆盖中。如果要从 B 类调用 A 类的测试方法,则需要使用super来调用超类方法。例如:

public class B extends A{
   public int test() {
       return super.test();
}
于 2012-09-04T15:37:23.547 回答
0

这是预期的行为。B 类中的方法test()覆盖test()A 类的方法。

于 2012-09-04T15:31:50.207 回答
0

为了

A a1 = new B();

a1指向 B 的对象,它是运行时的真实类型。因此值是从对象 B 打印的。

于 2012-09-04T15:33:03.773 回答
0
A obj = new A();
obj.test()

将返回 1

A obj = new B();
obj.test()

将返回 2

B obj = new B();
obj.test()

将返回 2

如其他答案所述,这就是多态性的工作方式。

这篇文章可能会让事情变得更清楚

于 2012-09-04T15:33:47.497 回答
0

Java 使用动态绑定(或后期绑定),所以B调用 的方法,而不是A。这与静态绑定相反。这里有一个很好的例子。

于 2012-09-04T15:34:01.327 回答
0

您将对象声明为 A,但您的实例是 B。因此,将调用的方法来自 B 类。B 扩展了 A(我们可以说 A 是 B 的父级),如果您将在 B 中注释方法测试然后回想一下方法,在这种情况下,调用的方法将从 A 类测试并返回 1。

于 2012-09-04T15:35:22.253 回答