为什么两个代码段中的“ @Override”注释都可以正常工作?

时间:2018-07-08 05:07:02

标签: java inheritance interface override abstract-class

尽管类B实现了接口A,但是它没有提供方法show()的实现。同样,D扩展了C,但在类D中,displayNothing()的实现与其父类displayNothing()C方法的实现相同。

但是在两种情况下,@Override注释都可以正常工作,为什么?

//code snippet 1
interface A
{
    void show();
}
abstract class B implements A
{
    @Override        
    abstract public void show(); 
}

//code snippet 2
class C
{
    void displayNothing()
    {
    }
}
class D extends C
{
    @Override
    void displayNothing()
    {
    }
}

4 个答案:

答案 0 :(得分:0)

B是抽象的。抽象类不需要提供实现。如果抽象类未实现必需的方法,则无关紧要。如果类不是抽象的,则所有抽象方法的 then 实现都必须存在。

D提供了C语言中displayNothing方法的替代。编译器不会检查替代版本是否与替代版本相同,并且不关心替代实现是否为空。 Override注释所做的全部工作就是确认在类层次结构中,被注释的方法上方有一个具有相同签名的方法。

注释的目的是确认您实际上是在覆盖现有方法,并且没有通过拼写错误的方法名称或与您要覆盖的方法的签名不匹配而引入错误。看到Java Language Specification, 9.6.4.4,上面写着:

  

程序员在打算覆盖方法声明时,有时会重载它们,从而导致一些细微的问题。注释类型的“覆盖”支持及早发现此类问题。

     

经典示例涉及equals方法。程序员在Foo类中编写了以下内容:

public boolean equals(Foo that) { ... }
  

当他们打算写的时候:

public boolean equals(Object that) { ... }
  

这是完全合法的,但是Foo类从Object继承了equals实现,这可能会导致一些非常微妙的错误。

(请注意,当我描述@Override是什么时,我跳过了override-equivalence,因为您没有询问它,并且已经有perfectly good answers对此进行了介绍。

答案 1 :(得分:0)

@Override只会困扰您的函数名称以及数据类型是否与您的超类中的方法相同(没有字母错误)。您的情况是相同的。尝试在类D中将 void 更改为 int 。这会显示编译错误。至于您的抽象类方法,它不需要定义任何东西,因为名称可以说明一切,它是抽象

答案 2 :(得分:0)

@Override注释的目的是防止错误。它的存在通知编译器必须必须是一个继承的方法,该方法具有与该类相同的确切签名。是否有方法的实现并不重要。

不包含@Override注释是完全合法的。但是,您可能会遇到的潜在问题是,如果您不小心遇到了错字或无意中更改了方法签名,那么您将使方法过载,而不是覆盖它。编译器将无法捕获此错误。该程序可能崩溃,甚至可能运行,但是运行不正确。

因为这可能是一个很难发现的错误,尤其是对于包含多个参数的方法,所以创建了@Override注释。 @Override注释告知编译器此方法是重写,而不是重载,如果编译器未能找到要重写的方法,则返回编译错误。

所有这些方法都可以编译并可以运行,但是没有一个方法可以覆盖displayNothing()方法。

void displayNothng();
void displaynothing();
void displayNothing(String value);

答案 3 :(得分:0)

在上述两种情况下,@Override批注都可以“正常工作”,因为java将该批注重新用于接口和类,即使您觉得第一和第二段代码做了一些不同的事情,它也没有那么重要引入单独的关键字/注释,以区分是在接口的覆盖还是从类的覆盖。即使是抽象类也不会改变这里的情况。

@Override表示给定的方法在超类/接口中具有兼容的表示形式,用于确保定义中不存在任何语法问题。