多态性不能按预期工作,为什么?

时间:2015-06-18 14:43:52

标签: java types polymorphism override

我的java程序中有这两个类:

public class A {
    private final static A five = new A(5);
    public final int x;
    public A(int x) {
        this.x = x;
    }
    public boolean equals(Object o) {
        return x == ((A) o).x;
    }
    public String toString() {
        return equals(five) ? "five" : (x + "");
    }
}

public class B extends A {
    public final int x;
    public B(int x) {
        super(x);
        this.x = x + 1;
    }
    public boolean equals(A o) {
        return x == o.x;
    }
    public String toString() {
        return "B: " + super.toString();
    }
}

现在我的主要是做这两个简单的动作:

public static void main(String[] args) {
    System.out.println(new A(5));
    System.out.println(new B(5));
}

关于第一行,正如我预期的那样,它将创建一个A对象 - >转到A的toString功能 - >获取True函数的equals,最后打印“5”。

关于B,我的预期和实际发生的事情是不同的...... 我以为它会转到B的构造函数 - >转到构造函数并将数字5分配给x - >返回B构造函数并将数字6分配给B的x - >转到B的toString方法并打印“B:”(直到这一点我是对的) - >转到A的toString - >转到B的equals,因为对象类型是B,这就是你关于方法激活的看法(*这是我错的地方) - >返回False,因为B中的x是6 - >打印数字5,因为我们在A toString

相反,在它调用A类toString而不是转到B equals方法的部分中,它停留在A中并激活A equals ...

我不知道为什么会发生这种情况,我所知道的是激活的方法是由对象类型决定的。

希望有人能在这里解释一下有什么不同......谢谢!

2 个答案:

答案 0 :(得分:2)

为了扩展你的答案,为未来的读者:

A.toString()中,您拨打this.equals(five),其中five的类型为A

在A的上下文中,匹配equals()的唯一A方法是A.equals(Object o)。这就是JVM调用的方法。

如果有一个重写方法B.equals(Object o) 那么就会调用它。仅使用较窄类型的B.equals()方法是不够的。

您可以通过提供A.equals(A a)方法,或通过扩展B.equals()的广度来获取Object来获得您期望的行为。

几点说明:

  • 只有几行,你在这里创造了一些非常复杂的东西。我希望它只是进行实验:真正的代码应该更直接。
  • 如果您要实施equals(),请接受Object,这样您就会覆盖标准方法。

答案 1 :(得分:0)

正如所给出的评论所解释的那样,我没有覆盖这个函数,我用该方法的全新签名重载了该函数。