繁体   English   中英

在 Java 中的接口中覆盖 Object 类方法

[英]Overriding Object class methods within an interface in Java

让我们考虑以下 Java 中的简单代码。

package temppkg;

interface Interface
{
    @Override
    public abstract boolean equals(java.lang.Object arg);

    @Override
    public abstract String toString();

    public void show();
}

final class Demo implements Interface
{
    public void show()
    {
        System.out.println("Method invoked.");
    }
}

final public class Main
{
    public static void main(String...args)
    {
        new Demo().show();
    }
}

在上面的代码片段中,名为Interface有一些来自 JDK 的 Object 类方法,即使它们是抽象的,它们也带有@Override注释。 现在,类Demo已经实现了Interface ,还没有实现equals()toString(); 方法。 编译器仍然没有抱怨并且程序运行成功。 为什么? Java中接口和对象类的关系是什么?

Java 语言规范明确指出,接口的成员是在接口中声明的成员和从直接超接口继承的成员。 如果一个接口没有直接的超接口,则该接口隐式声明了一个与 Object 类中声明的每个公共实例方法相对应的公共抽象成员方法,除非具有相同签名、相同返回类型和兼容 throws 子句的方法被显式声明为那个界面。 这就是编译器可以使用 Object 方法的签名并且代码编译时没有任何错误的原因。 请记住,如果接口试图在 Object 类中声明一个声明为“final”的公共实例方法,那么它将导致编译时错误。 例如,“public final Class getClass()”是在 Object 类中声明为“final”的公共实例方法,因此如果接口尝试声明具有此签名的方法,则编译将失败。

http://geekexplains.blogspot.com/2008/06/do-interfaces-really-inherit-from-class.html

查看JLS 9.2

如果接口没有直接的超接口,则该接口隐式声明了一个公共抽象成员方法m ,其签名为s ,返回类型为r ,并且 throws 子句t对应于每个具有签名s 、返回类型为rthrows子句的公共实例方法mthrows子句tObject声明,除非接口显式声明了具有相同签名、相同返回类型和兼容throws子句的方法。 如果在Object中将m声明为final的情况下,接口显式声明了这样的方法m ,则会出现编译时错误。

换句话说,每个接口都隐式定义了Object的每个方法,因此您可以@Override这些方法。 其他方法未在Object定义,因此您无法覆盖它们。

Interface您实际上并没有覆盖任何内容 - 根据定义,接口不能为其任何方法提供实现。 Demo只是从Object继承了equalstoString实现。

本质上,Java 中的接口包含一组零个或多个方法签名(所有这些都是隐式抽象的,在您的代码中,您通过添加关键字abstract使其显式),并且实现该接口的具体类必须为那些方法。 就您的代码而言,该实现来自Object ,因为所有类都隐式扩展了Object ,它为equalstoString (以及其他方法)提供了默认实现。

你真的不应该用@Override标记接口中的方法,正如你所看到的,它令人困惑并且没有实际用途。 相反,在实现接口方法的具体类中的方法中使用@Override ,如下所示:

class Demo implements Interface {
    @Override
    public void show() {
        System.out.println("Method invoked.");
    }
}

此外,完全没有必要在接口中声明equalstoString ,因此最好使用以下定义:

interface Interface {
    public void show();
}

@Override只能用于基类 Object 中定义的函数。 Object 定义了equalstoString ,因此您可以将@Override与它们一起使用,但不能与函数 show 一起使用。 它表示类中的@Override函数与其基类之间的关系,而不是派生类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM