实现接口方法的方法应该用 @Override
注释吗?
javadoc of the Override
annotation 说:
表示方法声明旨在覆盖超类中的方法声明。如果一个方法被这个注解类型注解但没有覆盖超类方法,编译器需要生成一个错误信息。
我不认为接口在技术上是超类。或者是吗?
您应该尽可能使用@Override。它可以防止犯简单的错误。例子:
class C {
@Override
public boolean equals(SomeClass obj){
// code ...
}
}
这不会编译,因为它没有正确覆盖 public boolean equals(Object obj)
。
实现接口(仅限 1.6 及更高版本)或覆盖 Super 类方法的方法也是如此。
我相信 javac 的行为已经改变 - 1.5 它禁止注释,1.6 它没有。注释提供了额外的编译时检查,因此如果您使用的是 1.6,我会选择它。
如果可用,您应该始终使用 @Override
注释方法。
在 JDK 5 中,这意味着覆盖超类的方法,在 JDK 6 和 7 中,这意味着覆盖超类的方法,并实现接口的方法。如前所述,原因是它允许编译器在您认为您正在覆盖(或实现)一个方法,但实际上是在定义一个新方法(不同的签名)时捕获错误。
equals(Object)
与 equals(YourObject)
的例子是一个标准的例子,但同样的论点可以用于接口实现。
我想注释接口的实现方法不是强制性的原因是JDK 5将此标记为编译错误。如果 JDK 6 强制使用此注释,它将破坏向后兼容性。
我不是 Eclipse 用户,但在其他 IDE(IntelliJ)中,如果项目设置为 JDK 6+ 项目,则仅在实现接口方法时才添加 @Override
注释。我想Eclipse是相似的。
但是,我更希望看到此用法的不同注释,可能是 @Implements
注释。
如果您正在实现接口中声明的方法(其编译错误),JDK 5.0 不允许您使用 @Override
注释,但 JDK 6.0 允许它。因此,您可能可以根据您的要求配置您的项目偏好。
如果具体类没有覆盖抽象方法,则使用 @Override
进行实现是一个开放的问题,因为编译器总是会警告您任何未实现的方法。在这些情况下,可以提出一个论点,即它会降低可读性 - 在您的代码上需要阅读更多内容,并且在较小程度上,它被称为 @Override
而不是 @Implement
。
通过阅读java8中的javadoc,可以在interface Override的声明处找到如下内容:
如果使用此注解类型对方法进行注解,编译器需要生成错误消息,除非至少满足以下条件之一:
该方法确实覆盖或实现了在超类型中声明的方法。
该方法的签名与 {@linkplain Object} 中声明的任何公共方法的签名等效。
因此,至少在 java8 中,您应该在接口方法的实现上使用 @Override。
覆盖从您自己的类继承的您自己的方法通常不会在使用 ide 进行重构时中断。但是,如果您覆盖从库继承的方法,建议使用它。如果你不这样做,你通常不会在以后的库更改中得到错误,而是一个隐藏得很好的错误。
这不是JDK的问题。在 Eclipse Helios 中,它允许对实现的接口方法使用 @Override 注解,无论是 JDK 5 还是 6。 至于 Eclipse Galileo,不允许使用 @Override 注解,无论是 JDK 5 还是 6。
如果实现 interface
的类是 abstract
类,则 @Override
可用于确保实现是针对 interface
方法的;如果没有 @Override
,即使实现方法签名与 interface
中声明的方法不匹配,abstract
类也可以正常编译;不匹配的 interface
方法将保持未实现状态。 @Zhao 引用的 Java 文档
该方法确实覆盖或实现了在超类型中声明的方法
显然是指 abstract
超类; interface
不能称为超类型。因此,@Override
是多余的,对于具体类中的 interface
方法实现是不明智的。
对我来说,通常这是某些代码需要 Java 6 编译的唯一原因。不确定是否值得。
包含 @Override
的问题在于它会让您认为自己忘记调用 super.theOverridenMethod()
方法,这非常令人困惑。这应该是非常清楚的。也许 Java 应该提供一个 @Interface
以供在这里使用。哦,好吧,又是一个半途而废的 Java 特性......
在 java 6 及更高版本中,您可以将 @Override
用于实现接口的方法。
但是,我认为它没有意义:覆盖意味着您在超类中有一个方法,并且您正在子类中实现它。
如果您正在实现一个接口,我认为我们应该使用 @Implement
或其他东西,而不是 @Override
。
当您告诉 Eclipse 在创建实现接口的类期间“生成未实现的方法”时,Eclipse 本身将添加 @Override
注释。
这可能为时已晚。但我希望这个例子能帮助人们理解为什么 @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
。我们永远不会依靠语言的强大力量来克服无能设计带来的挑战
Should we @Override an interface's method implementation?
。我只是想描述为什么 @Override
很重要。当然,您是对的,food
可以来自 restaurant
或来自 home
或来自任何地方!。在我的例子中,食物和食物之间的紧密耦合餐厅错了。感谢您注意到它(但我已经考虑过这种情况,不想在这里混淆描述)