ChatGPT解决这个技术问题 Extra ChatGPT

我们应该@Override 接口的方法实现吗?

实现接口方法的方法应该用 @Override 注释吗?

javadoc of the Override annotation 说:

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

我不认为接口在技术上是超类。或者是吗?

Question Elaboration

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

M
Matthias

您应该尽可能使用@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 在实现接口方法方面的不同行为。仅仅因为我已经看到它对人们来说是一个令人困惑的方面,它确实值得一提。
+1 后 1.5 位。我花了大约 20 分钟才弄清楚为什么 eclipse 给了我错误,我意识到我的新项目使用的是 java 1.5
如果 eclipse 抱怨然后将你的 jdk 升级到 > 1.5 并将编译器合规级别更改为 1.6 或 1.7。为此,请右键单击您的项目-> 属性-> Java 编译器并选择高于 1.5 的编译器。
J
Jon Skeet

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


@Michael您可以注意到是否删除了任何界面。
F
Flat Eric

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

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

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

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

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

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


C
Community

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


j
jpaugh

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


j
juanchito

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


Z
Zhao Pengfei

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

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

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

该方法的签名与 {@linkplain Object} 中声明的任何公共方法的签名等效。

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


A
Arne Burmeister

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


J
Jackie

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


M
Madhu

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

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

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


这不仅仅是多余的。在 STS4 中,当实现接口方法的类方法用 @Override 修饰时,编译器错误消息会显示“...必须覆盖超类方法”。
F
Fabian Steeg

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


j
jpaugh

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


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

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

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

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


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

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


s
smilyface

这可能为时已晚。但我希望这个例子能帮助人们理解为什么 @override 如此重要(对于这样的场景)

public interface Restaurant(){
    public boolean getBill();
    public BigDecimal payAmount();
}

public interface Food() extends Restaurant{
    public boolean haveSomeFood();
    public boolean drinkWater();
}

public class Hungry() implements Food{
    public boolean haveSomeFood(){}
    public boolean drinkWater(){}
    public boolean getBill(){}
    public BigDecimal payAmount(){}
}

在上面的示例中,如果我是 Hungry,我可以从 Restaurant 获得 Food。但是如果我拿出Restaurant的实施,我就不用拿账单也不需要付金额了!!!!

如何?

接口 Food 有关键字 extends Restaurant - 这意味着 Hungry 类也是从接口 Restaurant 实现的。

从接口实际覆盖的方法没有关键字@override

因此,如果我删除关键字 extends Restaurant(或者说如果我删除接口 Restaurant,它不会显示任何错误。

如果有 @override,每当我尝试删除 Restaurant 界面时,它都会显示编译错误。

注意:当您实现一个接口时,您可能不知道该接口是否扩展为另一个接口或是否可以扩展或者继承可能被删除。所以最好使用 @override 关键字


首先使用 inheritance 来模拟食物和餐馆之间的关系不是一个非常糟糕的设计吗?还有另一种方法称为 composition。我们永远不会依靠语言的强大力量来克服无能设计带来的挑战
@RuiZheng - OP询问覆盖的设计无关紧要 - Should we @Override an interface's method implementation?。我只是想描述为什么 @Override 很重要。当然,您是对的,food 可以来自 restaurant 或来自 home 或来自任何地方!。在我的例子中,食物和食物之间的紧密耦合餐厅错了。感谢您注意到它(但我已经考虑过这种情况,不想在这里混淆描述)