【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)进行区分。然而,出于风格的考虑,不鼓励这样做。

相关推荐
cyforkk10 分钟前
15、Java 基础硬核复习:File类与IO流的核心逻辑与面试考点
java·开发语言·面试
李少兄16 分钟前
解决 org.springframework.context.annotation.ConflictingBeanDefinitionException 报错
java·spring boot·mybatis
大飞哥~BigFei16 分钟前
整数ID与短字符串互转思路及开源实现分享
java·开源
benjiangliu19 分钟前
LINUX系统-09-程序地址空间
android·java·linux
历程里程碑25 分钟前
子串-----和为 K 的子数组
java·数据结构·c++·python·算法·leetcode·tornado
独自破碎E28 分钟前
字符串相乘
android·java·jvm
东东5161 小时前
OA自动化居家办公管理系统 ssm+vue
java·前端·vue.js·后端·毕业设计·毕设
没有bug.的程序员1 小时前
Spring Cloud Alibaba:Nacos 配置中心与服务发现的工业级深度实战
java·spring boot·nacos·服务发现·springcloud·配置中心·alibaba
rainbow68891 小时前
Java并发三要素:原子性、可见性、有序性
java
小罗和阿泽1 小时前
复习 Java(2)
java·开发语言