1

此代码无效:

interface Foo
{
    public void foo(final String string);
}

public class Bar implements Foo
{
    // Error: does not override.
    @Override public void foo(final Object object)
    {
    }
}

因为 everyString显然是 an ,Object所以我希望这段代码非常好:任何依赖于在实际使用.foo()Stringfoo()Object

但是,似乎方法签名必须与它们覆盖的方法的签名相同。为什么?

4

4 回答 4

4

如果什么

interface Foo
{
    void foo(String string);
    void foo(Object string);
}

那么哪个方法被 Bar 覆盖了呢?

于 2012-04-09T01:01:10.827 回答
0

正如您所说,“松动”不应影响期望以特定方式使用您的接口定义方法的人,因为您在该对象上调用的任何方法理论上都应该可以在指定对象上调用,但 Eugene 的观点是站得住脚的,因为会有如果您只是模糊地想要坚持接口规范,那么在确定您实际打算覆盖的方法时可能会有点编译器头痛。此外,如果您要坚持向上移动继承层次结构,为什么这会是可取的,因为您肯定能够对层次结构更靠下的事物做所有您想做的事情,例如“对象”?可能在您的方法中进行投射会解决您的问题吗?如果可以做自己想做的事,

于 2012-04-09T01:23:17.433 回答
0

我认为这是一个经典的逆变问题。您的接口需要一个字符串作为参数传递,您需要一个接受对象的实现(因为毕竟字符串也是对象)。

问题是,如果您允许这样做,那么您将无法再保证接口所需的参数是字符串或其任何一个祖先。您也可以将任何对象传递给您的实现,这样您就会违反接口的约定,从而危及您设计的类型安全和类型一致性。

但是,您确实有选择:

public class Bar implements Foo
{

    @Override public void foo(final String object)
    {
    }

    public void foo(final Object object)
    {
       foo((String) object);
    }
}

这样,您将确保对象实际上是一个字符串,从而使类型系统可以检查您是否真正遵守方法签名中建立的接口契约。

是否存在特定情况下您会认为逆变示例是必需的?

于 2012-04-09T01:27:34.667 回答
0

它只是 Java 编程语言的结构。Java 程序的结构会随着你的成长而发展。所以现在只是尝试调整。

于 2012-04-09T01:58:12.893 回答