Java类问题

时间:2009-04-23 09:27:59

标签: java class

class One {
public One foo() { return this; }
}

class Two extends One {
public One foo() { return this; }
}

class Three extends Two {
public Object foo() { return this; }
}

public Object foo() { return this; }抛出编译错误。这是为什么?有人可以解释为什么“对象”类型不可能吗?对象是Class One,Two的基类吗?如果那么为什么会抛出错误?

请更改问题的标题,因为我无法找到合适的标题。

4 个答案:

答案 0 :(得分:16)

Three.foo正在尝试覆盖Two.foo(),但它没有正确执行。假设我要写:

One f = new Three();
One other = f.foo();

忽略实际 Three.foo() 的事实返回OneThree.foo()的签名并不能保证。因此,对于 必须返回One的方法,它不是一个合适的覆盖。

请注意,您可以更改返回类型并仍然覆盖,但必须更多特定而不是 less 。换句话说,这没关系:

class Three extends Two {
    public Three foo() { return this; }
}

因为ThreeOne更具体。

答案 1 :(得分:5)

您正在以不支持的方式更改foo方法的签名。多态性仅适用于不同的参数列表,不适用于仅由返回类型不同的相同方法。

如果你考虑一下,这很自然......如果它有效并且只知道两个超类之一的人会调用Three.foo()他会期望它返回一个(因为那个)它是如何在One和Two中工作的)但在Three中你实际上可以返回一个HashMap并且仍能正常运行。

Jon(在下面的评论中)是正确的,你可以缩小范围但是你仍然会遵循你将返回“One”的协议(你应该从Three.foo()返回一个三)因为子类将都实现了超类接口。 但是,返回类型仍然不是多态的一部分,因此您不能有三种不同的方法,只有不同的返回类型。

答案 2 :(得分:2)

它将启用:

class Four extends Three {
public Object foo() { return "This String is not an instance of One"; }
}

答案 3 :(得分:2)

覆盖方法并尝试返回不太具体的类型违反了Liskov substitution principle,它表示子类必须满足其超类的所有合同。你的第三类违反了超类合同“foo()返回一个实例”。