【问题标题】:Should we @Override an interface's method implementation?我们应该@Override 接口的方法实现吗?
【发布时间】:2010-09-17 18:38:59
【问题描述】:

实现接口方法的方法是否应该用@Override注解?

javadoc of the Override annotation 说:

表示方法声明旨在覆盖超类中的方法声明。如果一个方法被这个注解类型注解但没有覆盖超类方法,编译器需要生成一个错误信息。

我不认为接口在技术上是超类。还是这样?

Question Elaboration

【问题讨论】:

  • 我找不到 @Override 文章的替代品(Oracle 最近移动了旧的 Sun 博客)。你知道怎么找到吗?
  • 到现在(2015 年)我们应该有一个 @Implement(s) 注释。这会让事情变得清晰!
  • 现在(2015 年)我们应该在 java 8 中使用 @Override 吗?

标签: java oop interface annotations


【解决方案1】:

您应该尽可能使用@Override。它可以防止犯简单的错误。示例:

class C {
    @Override
    public boolean equals(SomeClass obj){
        // code ...
    }
}

这不会编译,因为它没有正确覆盖public boolean equals(Object obj)

同样适用于实现接口(仅限 1.6 及更高版本)或覆盖 Super 类的方法的方法。

【讨论】:

  • 请注意,您不能将@Override 注解添加到在Java 5 中实现接口的方法中——它会产生错误。它在 Java 6 中是允许的。
  • 嗯,不,它没有。事实上,Eclipse 在填充实现接口的方法时会自动插入@Override。
  • -1 直到答案包括提到从 Java 1.5 到 1.6 在实现接口方法方面的不同行为。只是因为我已经看到它对人们来说是一个令人困惑的方面,它确实值得一提。
  • 如果 eclipse 抱怨然后将你的 jdk 升级到 > 1.5 并将编译器合规级别更改为 1.6 或 1.7。为此,请右键单击您的项目-> 属性-> Java 编译器并选择高于 1.5 的编译器。
  • 谁能想到一个实际证明答案合理的示例(实现接口而不是覆盖基本方法)?对我来说,一个很大的优点是它有助于设定读者对特定方法的使用方式和使用方式的期望。
【解决方案2】:

我相信 javac 的行为已经改变——在 1.5 中它禁止注释,在 1.6 中它没有。注释提供了额外的编译时检查,所以如果你使用的是 1.6,我会选择它。

【讨论】:

  • @Michael 你可以注意到是否有接口被删除。
【解决方案3】:

如果可用,您应该始终使用 @Override 注释方法。

在 JDK 5 中,这意味着覆盖超类的方法,在 JDK 6 和 7 中,这意味着覆盖超类的方法,并实现接口的方法。如前所述,原因是它允许编译器在您认为您正在覆盖(或实现)一个方法,但实际上是在定义一个新方法(不同的签名)时捕获错误。

equals(Object)equals(YourObject) 的例子是一个标准的例子,但同样的论点可以用于接口实现。

我想注释接口的实现方法不是强制性的原因是 JDK 5 将其标记为编译错误。如果 JDK 6 强制使用此注释,它将破坏向后兼容性。

我不是Eclipse用户,但是在其他IDE(IntelliJ)中,如果项目设置为JDK 6+项目,则只有在实现接口方法时才会添加@Override注解。我想 Eclipse 是类似的。

但是,我更希望看到针对此用法的不同注释,可能是 @Implements 注释。

【讨论】:

    【解决方案4】:

    我会一有机会就使用它。见When do you use Java's @Override annotation and why?

    【讨论】:

      【解决方案5】:

      如果你正在实现接口中声明的方法(其编译错误),JDK 5.0 不允许你使用 @Override 注释,但 JDK 6.0 允许它。因此,您可能可以根据您的要求配置您的项目偏好。

      【讨论】:

        【解决方案6】:

        如果一个具体类没有覆盖抽象方法,使用@Override进行实现是一个开放的问题,因为编译器总是警告您任何未实现的方法。在这些情况下,可以提出一个论点,即它会降低可读性——在您的代码上阅读更多内容,在较小程度上,它被称为@Override 而不是@Implement

        【讨论】:

          【解决方案7】:

          通过阅读java8中的javadoc,可以在interface Override的声明处发现如下内容:

          如果使用此注解类型对方法进行注解,编译器必须生成错误消息,除非至少满足以下条件之一:

          • 该方法确实覆盖或实现了在超类型中声明的方法。
          • 该方法的签名与 {@linkplain Object} 中声明的任何公共方法的签名等效。

          因此,至少在 java8 中,您应该在接口方法的实现上使用 @Override。

          【讨论】:

            【解决方案8】:

            覆盖从您自己的类继承的您自己的方法通常不会在使用 ide 进行重构时中断。但是,如果您覆盖从库继承的方法,建议使用它。如果你不这样做,你通常不会在以后的库更改中得到任何错误,而是一个隐藏得很好的错误。

            【讨论】:

              【解决方案9】:

              这不是 JDK 的问题。在 Eclipse Helios 中,它允许对实现的接口方法使用 @Override 注解,无论是 JDK 5 还是 6。对于 Eclipse Galileo,@Override 注解是不允许的,无论是 JDK 5 还是 6。

              【讨论】:

                【解决方案10】:

                如果实现interface 的类是abstract 类,则@Override 有助于确保实现是针对interface 方法的;如果没有@Override,即使实现方法签名与interface 中声明的方法不匹配,abstract 类也可以正常编译;不匹配的interface 方法将保持未实现状态。 @Zhao 引用的 Java 文档

                该方法确实覆盖或实现了在超类型中声明的方法

                显然是指abstract 超类; interface 不能称为超类型。 因此,@Override 是多余的,对于具体类中的 interface 方法实现是不明智的。

                【讨论】:

                  【解决方案11】:

                  对我来说,通常这是某些代码需要 Java 6 编译的唯一原因。不确定是否值得。

                  【讨论】:

                    【解决方案12】:

                    包含@Override 的问题在于它会让您认为您忘记调用super.theOverridenMethod() 方法,这非常令人困惑。这应该是非常清楚的。也许 Java 应该提供一个@Interface 供在这里使用。哦,好吧,又是一个半途而废的 Java 特性……

                    【讨论】:

                    • 在不实现接口时调用 super 并不是您总是需要或想要做的事情。有时,您正在添加功能——所以您称之为。其他时候,你正在替换功能,所以你不调用它。 API 作者应该记录它是否依赖于内部功能,并就如何正确扩展类创建书面合同。
                    【解决方案13】:

                    在 java 6 及更高版本中,您可以将@Override 用于实现接口的方法。

                    但是,我认为它没有意义:覆盖意味着您在超类中拥有一个方法,并且您正在子类中实现它。

                    如果你正在实现一个接口,我认为我们应该使用@Implement 或其他东西,而不是@Override

                    【讨论】:

                    • 我同意,没有其他答案能真正证明为什么 @override 应该用于接口实现。我说它可能有用的唯一原因是,如果您将一个类更改为一个抽象类,那么合理地说,这不应该发生。
                    【解决方案14】:

                    当您在创建实现接口的类期间告诉它“生成未实现的方法”时,Eclipse 本身会添加 @Override 注释。

                    【讨论】:

                      【解决方案15】:

                      对于接口,使用@Override 导致编译错误。 所以,我不得不删除它。

                      错误消息为“The method getAllProducts() of type InMemoryProductRepository must override a superclass method”。

                      它还写着“One quick fix available: Remove @Override annotation.

                      它在 Eclipse 4.6.3、JDK 1.8.0_144 上。

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2016-08-13
                        • 1970-01-01
                        • 2021-10-13
                        相关资源
                        最近更新 更多