【Java】接口也继承了Object吗?

【Java】接口也继承了Object吗?

开篇先表明我的观点:没有继承。

分析问题

我个人在网上大家的观点不是很统一,有认为继承了的,也有认为没有继承的。

支持没有继承有以下观点

从接口的设计思想考虑

为了规避菱形问题Java采用了单一继承的原则,那么接口就诞生于解决单一继承的原则。若接口也继承了Object,某个类实现了某个接口,那么这个类即隐式继承了Object,接口也继承了Object,这就违背了Java的最初的单一继承原则。

支持继承有以下观点

实验代码

java 复制代码
Interface A {
    
}
class verify implements A{
    void f(A a) {
        System.out.println(a.hashCode());
        System.out.println(a.toString());
    }
}

以上的代码是可以通过编译通过的,证明是接口a也继承了Object。

个人观点

在Java Language Specification里面找答案

原文和翻译(来自ChatGPT,个人校验,英文水平有限)放在文末了。

根据Java8的文档,如果一个接口没有父接口,那么接口会隐式声明一个public abstract方法 ,这个方法与Object中的public实例方法相对应(签名相同、返回值相同、抛出异常相同),除非接口中声明了具有相同签名,相同返回值和兼容的异常抛出的抽象方法。

这段话就可以解释下面这段代码为什么能够编译成功了。

java 复制代码
Interface A {
    
}
class verify implements A{
    void f(A a) {
        System.out.println(a.hashCode());
        System.out.println(a.toString());
    }
}

我们还可以通过下面的代码来验证,让interface和class来对比一下。

通过获取A和B中的方法也可以看出interface A是没有继承Object的。

java 复制代码
class Main {
    public static void main(String[] args) {
        HashSet<String> setA = new HashSet<>();
        for (Method method : A.class.getMethods()) {
            setA.add(method.getName());
        }
        
        HashSet<String> setB = new HashSet<>();
        for (Method method : B.class.getMethods()) {
            setB.add(method.getName());
        }
        System.out.println("interface A:" + setA); 
        // interface A:[]
        System.out.println("class     B:" + setB); 
        // class     B:[getClass, wait, hashCode, equals, notifyAll, toString, notify]

    }
}

interface A {

}
class B {

}

JSL文档中也提到可以声明Object中的方法,那么此时finalize就是interface A自己的方法了,提高了访问级别,和异常级别。

java 复制代码
class Main {
    public static void main(String[] args) {
        HashSet<String> setA = new HashSet<>();
        for (Method method : A.class.getMethods()) {
            setA.add(method.getName());
        }
        System.out.println("interface A:" + setA); // interface A:[finalize]

    }
}

interface A {
    void finalize() throws Exception;
}
class verify implements A{
    void f(A a) {
        System.out.println(a.hashCode());
        System.out.println(a.toString());
    }

    @Override
    public void finalize() {

    }
}

Java8、9、17关于接口成员的文档

docs.oracle.com/javase/spec...

docs.oracle.com/javase/spec...

docs.oracle.com/javase/spec...

一步一步来研究

Java8

The members of an interface type are:

  • Members declared in the body of the interface (§9.1.4).

  • Members inherited from any direct superinterfaces (§9.1.3).

  • If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless an abstract method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.

    It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.

    It is a compile-time error if the interface explicitly declares a method with a signature that is override-equivalent (§8.4.2) to a public method of Object, but which has a different return type, or an incompatible throws clause, or is not abstract.

The interface inherits, from the interfaces it extends, all members of those interfaces, except for fields, classes, and interfaces that it hides; abstract or default methods that it overrides (§9.4.1); and static methods.

Fields, methods, and member types of an interface type may have the same name, since they are used in different contexts and are disambiguated by different lookup procedures (§6.5). However, this is discouraged as a matter of style.

接口类型的成员包括:

  • 在接口主体(§9.1.4)中声明的成员。

  • 从任何直接超级接口继承的成员(§9.1.3)。

  • 如果一个接口没有直接的超级接口,那么该接口会隐式声明一个公共抽象成员方法 m,其签名为 s,返回类型为 r,与 Object 中声明的每个公共实例方法 m 的签名 s、返回类型 r 和异常抛出声明 t 对应,除非接口明确声明了具有相同签名、相同返回类型和兼容的异常抛出声明的抽象方法。

​ 如果接口明确声明了在 Object 中被声明为 final 的这种方法 m,将导致编译时错误。

​ 如果接口明确声明了一个方法,其签名与 Object 的公共方法 override-equivalent(§8.4.2)相同,但返回类型不同、异常抛出声明 不兼容,或者不是抽象的,也会导致编译时错误。

接口从它所扩展的接口那里继承了这些接口的所有成员,除了隐藏的字段、类和接口;覆盖的抽象或默认方法(§9.4.1);以及静态方法。

接口类型的字段、方法和成员类型可以具有相同的名称,因为它们在不同的上下文中使用,通过不同的查找程序(§6.5)进行区分。然而,出于风格上的考虑,不鼓励这样做。

Java9

The members of an interface type are:

  • Members declared in the body of the interface (§9.1.4).

  • Members inherited from any direct superinterfaces (§9.1.3).

  • If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object (§4.3.2), unless an abstract method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.

    It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.

    It is a compile-time error if the interface explicitly declares a method with a signature that is override-equivalent (§8.4.2) to a public method of Object, but which has a different return type, or an incompatible throws clause, or is not abstract.

The interface inherits, from the interfaces it extends, all members of those interfaces, except for i) fields, classes, and interfaces that it hides, ii) abstract methods and default methods that it overrides (§9.4.1), iii) private methods, and iv) static methods.

Fields, methods, and member types of an interface type may have the same name, since they are used in different contexts and are disambiguated by different lookup procedures (§6.5). However, this is discouraged as a matter of style.

接口类型的成员包括:

  • 在接口声明的主体中声明的成员(§9.1.4)。

  • 从任何直接超级接口继承的成员(§9.1.3)。

  • 如果一个接口没有直接超级接口,那么该接口会隐式声明一个具有签名 s、返回类型 r 和异常抛出声明 t 的公共抽象成员方法 m,该方法对应于 Object(§4.3.2)中声明的每个公共实例方法 m 的签名 s、返回类型 r 和异常抛出声明 t,除非接口明确声明了具有相同签名、相同返回类型和兼容异常抛出声明的抽象方法。

​ 如果接口明确声明了一个在 Object 中被声明为 final 的方法 m,则这会导致编译时错误。

​ 如果接口明确声明了一个方法,其签名与 Object 的公共方法 override-equivalent(§8.4.2)相同,但返回类型不同、异常抛出声明 不兼容,或者不是抽象的,也会导致编译时错误。

接口从它扩展的接口那里继承了这些接口的所有成员,除了(i)隐藏的字段、类和接口,(ii)覆盖的抽象方法和默认方法(§9.4.1),(iii)私有方法,以及(iv)静态方法。

接口类型的字段、方法和成员类型可以具有相同的名称,因为它们在不同的上下文中使用,通过不同的查找过程(§6.5)进行区分。然而,出于风格的考虑,不鼓励这样做。

Java17

The members of an interface are:

  • Members declared in the body of the interface declaration (§9.1.5).

  • Members inherited from any direct superinterface types (§9.1.3).

  • If an interface has no direct superinterface types, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object (§4.3.2), unless an abstract method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.

    It is a compile-time error if the interface explicitly declares such a method m in the case where m is declared to be final in Object.

    It is a compile-time error if the interface explicitly declares a method with a signature that is override-equivalent (§8.4.2) to a public method of Object, but which has a different return type, or an incompatible throws clause, or is not abstract.

The interface inherits, from the interfaces it extends, all members of those interfaces, except for (i) fields, classes, and interfaces that it hides, (ii) abstract methods and default methods that it overrides (§9.4.1), (iii) private methods, and (iv) static methods.

Fields, methods, member classes, and member interfaces of an interface may have the same name, since they are used in different contexts and are disambiguated by different lookup procedures (§6.5). However, this is discouraged as a matter of style.

接口的成员包括:

  • 在接口声明的主体中声明的成员(§9.1.5)。

  • 从任何直接超级接口类型继承的成员(§9.1.3)。

  • 如果一个接口没有直接的超级接口类型,那么该接口会隐式声明一个公共抽象成员方法 m,其签名为 s,返回类型为 r,以及与 Object(§4.3.2)中声明的每个公共实例方法 m 的签名 s、返回类型 r 和异常抛出声明 t 对应,除非接口明确声明了具有相同签名、相同返回类型和兼容的异常抛出声明的抽象方法。

​ 如果接口明确声明了在 Object 中被声明为 final 的这种方法 m,则这会导致编译时错误。

​ 如果接口明确声明了一个方法,它的签名与 Object 的公共方法 override-equivalent(§8.4.2)相同,但返回类型不同、异常抛出声 明不兼容,或者不是抽象的,也会导致编译时错误。

接口从它扩展的接口那里继承了这些接口的所有成员,除了(i)隐藏的字段、类和接口,(ii)覆盖的抽象方法和默认方法(§9.4.1),(iii)私有方法,以及(iv)静态方法。

接口的字段、方法、成员类和成员接口可以具有相同的名称,因为它们在不同的上下文中使用,通过不同的查找过程(§6.5)进行区分。然而,出于风格的考虑,不鼓励这样做。

相关推荐
王哈哈嘻嘻噜噜2 分钟前
c语言中“函数指针”
java·c语言·数据结构
qq_3391911410 分钟前
spring boot admin集成,springboot2.x集成监控
java·前端·spring boot
苹果酱056726 分钟前
通过springcloud gateway优雅的进行springcloud oauth2认证和权限控制
java·开发语言·spring boot·后端·中间件
Sunny_yiyi29 分钟前
Gateway--服务网关
java·开发语言·gateway
Mike!40 分钟前
C++进阶 set和map讲解
java·开发语言·数据结构·c++·set·map·cpp
翔云12345642 分钟前
Go语言的垃圾回收(GC)机制的迭代和优化历史
java·jvm·golang·gc
不见长安见晨雾1 小时前
将Java程序打包成EXE程序
java·开发语言
逸狼2 小时前
【JavaEE初阶】多线程(5 单例模式 \ 阻塞队列)
java·开发语言
希忘auto3 小时前
Java之线程篇四
java
蓝黑20203 小时前
Java知识点小结3:内存回收
java·gc