[英]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 、返回类型为r和
throws
子句的公共实例方法m和throws
子句t在Object
声明,除非接口显式声明了具有相同签名、相同返回类型和兼容throws
子句的方法。 如果在Object
中将m声明为final
的情况下,接口显式声明了这样的方法m ,则会出现编译时错误。
换句话说,每个接口都隐式定义了Object
的每个方法,因此您可以@Override
这些方法。 其他方法未在Object
定义,因此您无法覆盖它们。
在Interface
您实际上并没有覆盖任何内容 - 根据定义,接口不能为其任何方法提供实现。 类Demo
只是从Object
继承了equals
和toString
实现。
本质上,Java 中的接口包含一组零个或多个方法签名(所有这些都是隐式抽象的,在您的代码中,您通过添加关键字abstract
使其显式),并且实现该接口的具体类必须为那些方法。 就您的代码而言,该实现来自Object
,因为所有类都隐式扩展了Object
,它为equals
和toString
(以及其他方法)提供了默认实现。
你真的不应该用@Override
标记接口中的方法,正如你所看到的,它令人困惑并且没有实际用途。 相反,在实现接口方法的具体类中的方法中使用@Override
,如下所示:
class Demo implements Interface {
@Override
public void show() {
System.out.println("Method invoked.");
}
}
此外,完全没有必要在接口中声明equals
和toString
,因此最好使用以下定义:
interface Interface {
public void show();
}
@Override
只能用于基类 Object 中定义的函数。 Object 定义了equals
和toString
,因此您可以将@Override
与它们一起使用,但不能与函数 show 一起使用。 它表示类中的@Override
函数与其基类之间的关系,而不是派生类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.