java8 接口的重新定义

2021/09/01 JAVA8 共 27613 字,约 79 分钟
闷骚的程序员

1. java8之前的接口定义

我们知道,接口中只能包含2部分内容:
(1)公共的静态的全局常量;
(2)公共的非静态的抽象方法.
请参考:java中接口和抽象类

2. java8对接口的重新定义

java8对之前的接口语法进行了升级,允许在接口中定义实现好的方法,而不仅仅是提供抽象方法的定义。
其中,实现好的实例方法,必须得由default关键字修饰,我们称之为default方法,允许在接口中定义多个;
实现好的静态方法,必须得由static关键字修饰,我们称之为静态方法,允许在接口中定义多个。
注意,default是java8新增的一个用于在接口中定义默认方法的关键字。

3. 默认方法

在java8之前,一个接口中的方法必须全部是抽象方法,不能有具体实现,实现接口的类需要复写接口中的所有抽象方法为其提供对应的实现。
但是从java8开始,允许在接口中声明有具体实现的方法,准确来讲,java8中的默认方法可以提供具体实现。
因为接口中的默认方法会被所有子类继承,因此,子类也可以选择重新复写接口中定义的默认方法。
(1)接口中的默认方法必须提供实现;
(2)接口中的默认方法可以被实现类或者子接口复写。

4. 静态方法

同样,从java8开始,可以直接在接口中定义静态方法。
接口中的静态方法和普通类中的静态成员一样,是不能被子类继承的,更谈不上子类去复写了。
接口中定义的静态方法,权当做一个工具方法来使用就可以了。
(1)接口的静态方法不能被子接口继承或者被子类继承;
(2)接口的静态方法必须提供实现;
(3)接口的静态方法不能被子接口或者实现类复写;
(4)接口的静态方法只能通过接口本身调用:接口名.静态方法名。
(5)接口的静态方法访问权限只能是public,一般不用显式指定,当省略时也是public。

5. 看一个案例

使用java8定义一个接口 MyJava8Interface.
该接口中定义了2个默认方法,2个静态方法,和2个抽象方法。

package zeh.myjavase.code42java8.demo01;

import org.apache.commons.lang.StringUtils;

public interface MyJava8Interface {

    // java8中提供的默认方法
    default String formatName(String name) {
        if (StringUtils.isNotBlank(name)) {
            return "format_" + name;
        }
        return name;
    }

    // 一个接口中可以定义多个默认方法
    default void sayHello() {
        System.out.println("hello java8.");
    }

    // java8接口中也允许提供静态方法
    static String getName(String name) {
        if (StringUtils.isNotBlank(name)) {
            return "竹联帮" + name;
        }
        return name;
    }

    // 再搞一个静态方法
    static void print(String name) {
        System.out.println("name is " + name);
    }

    // 接口中提供的抽象方法1
    void refactorName(String name);

    // 接口中提供的抽象方法2
    String buildNewName(String name);
}

实现类:MyJava8InterfaceImpl1

package zeh.myjavase.code42java8.demo01;

public class MyJava8InterfaceImpl1 implements MyJava8Interface {
    @Override
    public void refactorName(String name) {
        System.out.println("refactor name by MyJava8InterfaceImpl1, name is " + name);
    }

    @Override
    public String buildNewName(String name) {
        return "MyJava8InterfaceImpl1 name is " + name;
    }
}

实现类:MyJava8InterfaceImpl2

package zeh.myjavase.code42java8.demo01;

public class MyJava8InterfaceImpl2 implements MyJava8Interface {
    @Override
    public void refactorName(String name) {
        System.out.println("refactor name by MyJava8InterfaceImpl2, name is " + name);
    }

    @Override
    public String buildNewName(String name) {
        return "MyJava8InterfaceImpl2 name is " + name;
    }
}

运行代码:

package zeh.myjavase.code42java8.demo01;

public class MyJava8InterfaceRun {


    public static void main(String[] args) {
        MyJava8Interface myJava8Interface1 = new MyJava8InterfaceImpl1();

        MyJava8Interface myJava8Interface2 = new MyJava8InterfaceImpl2();

        // 调用接口的静态方法
        System.out.println(MyJava8Interface.getName("test"));
        MyJava8Interface.print("eric");

        // 调用接口的默认方法
        System.out.println(myJava8Interface1.formatName("daisy"));
        myJava8Interface1.sayHello();
        System.out.println(myJava8Interface2.formatName("kenneth"));
        myJava8Interface2.sayHello();

        // 通过子类对象分别调用各自实现的方法
        System.out.println(myJava8Interface1.buildNewName("eric zhao"));
        myJava8Interface1.refactorName("eric zhao");
        System.out.println(myJava8Interface2.buildNewName("kenneth bao"));
        myJava8Interface2.refactorName("kenneth bao");
    }
}

运行结果:

C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\bin\java.exe "-javaagent:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=50597:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\charsets.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\deploy.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\access-bridge-64.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\cldrdata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\dnsns.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jaccess.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jfxrt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\localedata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\nashorn.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunec.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunjce_provider.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunmscapi.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunpkcs11.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\zipfs.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\javaws.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jce.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfr.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfxswt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jsse.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\management-agent.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\plugin.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\resources.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\rt.jar;C:\D\zhaoehcode-java\myJavaSE\target\classes;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\esb_all.jar;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\basicplayer3.0.jar;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\luajava-1.1.jar;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\commonentity-1.0.1-20190830.060836-388.jar;C:\D\soft\soft_application\maven\repo\junit\junit\4.11\junit-4.11.jar;C:\D\soft\soft_application\maven\repo\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\D\soft\soft_application\maven\repo\org\springframework\spring-core\4.3.7.RELEASE\spring-core-4.3.7.RELEASE.jar;C:\D\soft\soft_application\maven\repo\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\D\soft\soft_application\maven\repo\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;C:\D\soft\soft_application\maven\repo\commons-beanutils\commons-beanutils\1.9.3\commons-beanutils-1.9.3.jar;C:\D\soft\soft_application\maven\repo\commons-collections\commons-collections\3.2.2\commons-collections-3.2.2.jar;C:\D\soft\soft_application\maven\repo\org\javassist\javassist\3.21.0-GA\javassist-3.21.0-GA.jar;C:\D\soft\soft_application\maven\repo\org\ow2\asm\asm\6.2\asm-6.2.jar;C:\D\soft\soft_application\maven\repo\cglib\cglib\3.2.2\cglib-3.2.2.jar;C:\D\soft\soft_application\maven\repo\org\apache\ant\ant\1.9.6\ant-1.9.6.jar;C:\D\soft\soft_application\maven\repo\org\apache\ant\ant-launcher\1.9.6\ant-launcher-1.9.6.jar;C:\D\soft\soft_application\maven\repo\dom4j\dom4j\1.6.1\dom4j-1.6.1.jar;C:\D\soft\soft_application\maven\repo\xml-apis\xml-apis\1.0.b2\xml-apis-1.0.b2.jar;C:\D\soft\soft_application\maven\repo\jdom\jdom\1.0\jdom-1.0.jar;C:\D\soft\soft_application\maven\repo\com\alibaba\fastjson\1.2.5\fastjson-1.2.5.jar;C:\D\soft\soft_application\maven\repo\com\fasterxml\jackson\core\jackson-core\2.8.7\jackson-core-2.8.7.jar;C:\D\soft\soft_application\maven\repo\com\fasterxml\jackson\core\jackson-databind\2.8.7\jackson-databind-2.8.7.jar;C:\D\soft\soft_application\maven\repo\com\fasterxml\jackson\core\jackson-annotations\2.8.0\jackson-annotations-2.8.0.jar;C:\D\soft\soft_application\maven\repo\log4j\log4j\1.2.17\log4j-1.2.17.jar;C:\D\soft\soft_application\maven\repo\com\itextpdf\itextpdf\5.5.9\itextpdf-5.5.9.jar;C:\D\soft\soft_application\maven\repo\com\itextpdf\tool\xmlworker\5.5.8\xmlworker-5.5.8.jar;C:\D\soft\soft_application\maven\repo\org\apache\poi\poi-ooxml\3.14\poi-ooxml-3.14.jar;C:\D\soft\soft_application\maven\repo\org\apache\poi\poi\3.14\poi-3.14.jar;C:\D\soft\soft_application\maven\repo\commons-codec\commons-codec\1.10\commons-codec-1.10.jar;C:\D\soft\soft_application\maven\repo\org\apache\poi\poi-ooxml-schemas\3.14\poi-ooxml-schemas-3.14.jar;C:\D\soft\soft_application\maven\repo\org\apache\xmlbeans\xmlbeans\2.6.0\xmlbeans-2.6.0.jar;C:\D\soft\soft_application\maven\repo\stax\stax-api\1.0.1\stax-api-1.0.1.jar;C:\D\soft\soft_application\maven\repo\com\github\virtuald\curvesapi\1.03\curvesapi-1.03.jar;C:\D\soft\soft_application\maven\repo\org\freemarker\freemarker\2.3.28\freemarker-2.3.28.jar;C:\D\soft\soft_application\maven\repo\org\springframework\spring-beans\4.2.5.RELEASE\spring-beans-4.2.5.RELEASE.jar;C:\D\soft\soft_application\maven\repo\org\apache\commons\commons-lang3\3.9\commons-lang3-3.9.jar zeh.myjavase.code42java8.demo01.MyJava8InterfaceRun
竹联帮test
name is eric
format_daisy
hello java8.
format_kenneth
hello java8.
MyJava8InterfaceImpl1 name is eric zhao
refactor name by MyJava8InterfaceImpl1, name is eric zhao
MyJava8InterfaceImpl2 name is kenneth bao
refactor name by MyJava8InterfaceImpl2, name is kenneth bao

Process finished with exit code 0

6. 为什么java8要改动接口的语法定义?

主要是因为java8中增加了Stream流式api,需要方便的操作集合。
对于集合而言,每一种类型的集合都需要有获取stream的方法—stream()。按照设计思想,这个stream()方法应该在集合的根接口Collection中去声明,然后让Collection接口的所有实现类去实现这个方法。
但这样做,很显然,一个是获取stream的方式应该是高度统一的,每个实现类去做重复的逻辑,有些代码冗余;另一个是集合体系在jdk中非常庞大,如果在Collection接口中声明stream()方法,那么所有Collection接口的实现类都要复写该方法以提供实现,对现存的jdk体系架构改动很大。
所以,如果Collection接口中可以定义有具体实现的stream()方法就不会破坏现有的架构,Collection的所有实现类只需要继承这个方法就可以了。
在jdk8的源码中,我们可以看到Collection接口中定义的默认方法stream()如下:

package java.util;

import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

public interface Collection<E> extends Iterable<E> {
    
    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}

正是由于java8要支持很多类似Stream的操作,因此它升级了jdk的基本语法,允许在接口中定义默认方法和静态方法。

7. 默认方法和冲突

首先声明,因为静态方法不参与继承,因此静态方法不会和子类中的方法产生冲突。而接口中的默认方法会被所有子类继承,因此接口中的默认方法将有可能导致方法冲突。
在java中始终存在一条不变的真理:类只能单继承,而接口可以多实现,即一个子类只能允许继承一个父类,但允许实现多个接口。
在java8之前,由于接口中只能定义抽象方法,实现类必须实现该抽象方法才行。因此,即便实现类实现了多个接口中的相同签名的方法,也不会产生冲突,因为方法的真正实现只能在实现类中完成。
而java8之后,允许接口中定义默认方法了,这样一来,一个实现类如果实现多个接口,而这些接口中恰好存在完全相同签名的默认方法,那么这个实现类到底继承的是哪个接口中的默认方法呢?因此,java8的默认方法打破了java继承体系中的单继承问题,可能导致多继承—一个类从多个地方(类或者接口)继承了有相同方法签名的方法。

对于这种默认方法冲突的问题,我们需要遵循下面3个原则:
(1)类中的方法优先级最高。类或者父类中定义的方法的优先级高于任何接口中声明为默认方法的优先级。
(2)如果第(1)条原则无法判断,子接口中声明的默认方法的优先级仅次于类中声明方法的优先级。
(3)上面两条如果都无法判断,实现类必须显式重写方法或者显式选择使用哪个默认方法的实现。

7.1 类和接口的方法冲突

多个接口中存在相同的默认方法签名,同时一个普通类中也存在一个完全相同的方法签名。
MyInterfaceA:

package zeh.myjavase.code42java8.demo01;

public interface MyInterfaceA {

    default void printClassName() {
        System.out.println("MyIntefaceA");
    }
}

MyInterfaceB:

package zeh.myjavase.code42java8.demo01;

public interface MyInterfaceB {

    default void printClassName() {
        System.out.println("MyInterfaceB");
    }
}

普通类 MyInterfaceClass:

package zeh.myjavase.code42java8.demo01;

public class MyInterfaceClass {

    public void printClassName() {
        System.out.println("MyInterfaceClass");
    }
}

实现类 MyInterfaceImpl:

package zeh.myjavase.code42java8.demo01;

public class MyInterfaceImpl extends MyInterfaceClass implements MyInterfaceA, MyInterfaceB {

    public static void main(String[] args) {
        MyInterfaceImpl myInterface = new MyInterfaceImpl();
        myInterface.printClassName();
    }
}

运行结果如下:

C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\bin\java.exe "-javaagent:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=50968:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\charsets.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\deploy.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\access-bridge-64.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\cldrdata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\dnsns.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jaccess.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jfxrt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\localedata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\nashorn.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunec.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunjce_provider.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunmscapi.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunpkcs11.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\zipfs.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\javaws.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jce.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfr.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfxswt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jsse.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\management-agent.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\plugin.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\resources.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\rt.jar;C:\D\zhaoehcode-java\myJavaSE\target\classes;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\esb_all.jar;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\basicplayer3.0.jar;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\luajava-1.1.jar;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\commonentity-1.0.1-20190830.060836-388.jar;C:\D\soft\soft_application\maven\repo\junit\junit\4.11\junit-4.11.jar;C:\D\soft\soft_application\maven\repo\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\D\soft\soft_application\maven\repo\org\springframework\spring-core\4.3.7.RELEASE\spring-core-4.3.7.RELEASE.jar;C:\D\soft\soft_application\maven\repo\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\D\soft\soft_application\maven\repo\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;C:\D\soft\soft_application\maven\repo\commons-beanutils\commons-beanutils\1.9.3\commons-beanutils-1.9.3.jar;C:\D\soft\soft_application\maven\repo\commons-collections\commons-collections\3.2.2\commons-collections-3.2.2.jar;C:\D\soft\soft_application\maven\repo\org\javassist\javassist\3.21.0-GA\javassist-3.21.0-GA.jar;C:\D\soft\soft_application\maven\repo\org\ow2\asm\asm\6.2\asm-6.2.jar;C:\D\soft\soft_application\maven\repo\cglib\cglib\3.2.2\cglib-3.2.2.jar;C:\D\soft\soft_application\maven\repo\org\apache\ant\ant\1.9.6\ant-1.9.6.jar;C:\D\soft\soft_application\maven\repo\org\apache\ant\ant-launcher\1.9.6\ant-launcher-1.9.6.jar;C:\D\soft\soft_application\maven\repo\dom4j\dom4j\1.6.1\dom4j-1.6.1.jar;C:\D\soft\soft_application\maven\repo\xml-apis\xml-apis\1.0.b2\xml-apis-1.0.b2.jar;C:\D\soft\soft_application\maven\repo\jdom\jdom\1.0\jdom-1.0.jar;C:\D\soft\soft_application\maven\repo\com\alibaba\fastjson\1.2.5\fastjson-1.2.5.jar;C:\D\soft\soft_application\maven\repo\com\fasterxml\jackson\core\jackson-core\2.8.7\jackson-core-2.8.7.jar;C:\D\soft\soft_application\maven\repo\com\fasterxml\jackson\core\jackson-databind\2.8.7\jackson-databind-2.8.7.jar;C:\D\soft\soft_application\maven\repo\com\fasterxml\jackson\core\jackson-annotations\2.8.0\jackson-annotations-2.8.0.jar;C:\D\soft\soft_application\maven\repo\log4j\log4j\1.2.17\log4j-1.2.17.jar;C:\D\soft\soft_application\maven\repo\com\itextpdf\itextpdf\5.5.9\itextpdf-5.5.9.jar;C:\D\soft\soft_application\maven\repo\com\itextpdf\tool\xmlworker\5.5.8\xmlworker-5.5.8.jar;C:\D\soft\soft_application\maven\repo\org\apache\poi\poi-ooxml\3.14\poi-ooxml-3.14.jar;C:\D\soft\soft_application\maven\repo\org\apache\poi\poi\3.14\poi-3.14.jar;C:\D\soft\soft_application\maven\repo\commons-codec\commons-codec\1.10\commons-codec-1.10.jar;C:\D\soft\soft_application\maven\repo\org\apache\poi\poi-ooxml-schemas\3.14\poi-ooxml-schemas-3.14.jar;C:\D\soft\soft_application\maven\repo\org\apache\xmlbeans\xmlbeans\2.6.0\xmlbeans-2.6.0.jar;C:\D\soft\soft_application\maven\repo\stax\stax-api\1.0.1\stax-api-1.0.1.jar;C:\D\soft\soft_application\maven\repo\com\github\virtuald\curvesapi\1.03\curvesapi-1.03.jar;C:\D\soft\soft_application\maven\repo\org\freemarker\freemarker\2.3.28\freemarker-2.3.28.jar;C:\D\soft\soft_application\maven\repo\org\springframework\spring-beans\4.2.5.RELEASE\spring-beans-4.2.5.RELEASE.jar;C:\D\soft\soft_application\maven\repo\org\apache\commons\commons-lang3\3.9\commons-lang3-3.9.jar zeh.myjavase.code42java8.demo01.MyInterfaceImpl
MyInterfaceClass

Process finished with exit code 0

案例中MyInterfaceImpl同时继承了MyInterfaceClass类、MyInterfaceA接口和MyInterfaceB接口中的printClassName()方法,此时MyInterfaceImpl类中就产生了方法冲突。
依据第1条原则:类或者父类中声明的方法优先级最高。
因此,调用 MyInterfaceImpl 对象的printClassName()方法,从MyInterfaceClass类中继承过来的优先级最高,运行结果符合预期。

7.2 父接口和子接口的方法冲突

父接口中存在默认方法,同时子接口中也存在相同签名的默认方法。
父接口A:

package zeh.myjavase.code42java8.demo01;

public interface A {

    default void print() {
        System.out.println("It's A");
    }
}

子接口B:

package zeh.myjavase.code42java8.demo01;

public interface B extends A {
    default void print() {
        System.out.println("It's B");
    }
}

实现类C:

package zeh.myjavase.code42java8.demo01;

public class C implements A, B {

    // 当父接口和子接口存在相同签名的默认方法时,子接口中的方法优先级高
    public static void main(String[] args) {
        C c = new C();
        c.print();
    }
}

运行结果:

C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\bin\java.exe "-javaagent:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=51050:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\charsets.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\deploy.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\access-bridge-64.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\cldrdata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\dnsns.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jaccess.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jfxrt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\localedata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\nashorn.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunec.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunjce_provider.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunmscapi.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunpkcs11.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\zipfs.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\javaws.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jce.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfr.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfxswt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jsse.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\management-agent.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\plugin.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\resources.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\rt.jar;C:\D\zhaoehcode-java\myJavaSE\target\classes;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\esb_all.jar;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\basicplayer3.0.jar;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\luajava-1.1.jar;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\commonentity-1.0.1-20190830.060836-388.jar;C:\D\soft\soft_application\maven\repo\junit\junit\4.11\junit-4.11.jar;C:\D\soft\soft_application\maven\repo\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\D\soft\soft_application\maven\repo\org\springframework\spring-core\4.3.7.RELEASE\spring-core-4.3.7.RELEASE.jar;C:\D\soft\soft_application\maven\repo\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\D\soft\soft_application\maven\repo\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;C:\D\soft\soft_application\maven\repo\commons-beanutils\commons-beanutils\1.9.3\commons-beanutils-1.9.3.jar;C:\D\soft\soft_application\maven\repo\commons-collections\commons-collections\3.2.2\commons-collections-3.2.2.jar;C:\D\soft\soft_application\maven\repo\org\javassist\javassist\3.21.0-GA\javassist-3.21.0-GA.jar;C:\D\soft\soft_application\maven\repo\org\ow2\asm\asm\6.2\asm-6.2.jar;C:\D\soft\soft_application\maven\repo\cglib\cglib\3.2.2\cglib-3.2.2.jar;C:\D\soft\soft_application\maven\repo\org\apache\ant\ant\1.9.6\ant-1.9.6.jar;C:\D\soft\soft_application\maven\repo\org\apache\ant\ant-launcher\1.9.6\ant-launcher-1.9.6.jar;C:\D\soft\soft_application\maven\repo\dom4j\dom4j\1.6.1\dom4j-1.6.1.jar;C:\D\soft\soft_application\maven\repo\xml-apis\xml-apis\1.0.b2\xml-apis-1.0.b2.jar;C:\D\soft\soft_application\maven\repo\jdom\jdom\1.0\jdom-1.0.jar;C:\D\soft\soft_application\maven\repo\com\alibaba\fastjson\1.2.5\fastjson-1.2.5.jar;C:\D\soft\soft_application\maven\repo\com\fasterxml\jackson\core\jackson-core\2.8.7\jackson-core-2.8.7.jar;C:\D\soft\soft_application\maven\repo\com\fasterxml\jackson\core\jackson-databind\2.8.7\jackson-databind-2.8.7.jar;C:\D\soft\soft_application\maven\repo\com\fasterxml\jackson\core\jackson-annotations\2.8.0\jackson-annotations-2.8.0.jar;C:\D\soft\soft_application\maven\repo\log4j\log4j\1.2.17\log4j-1.2.17.jar;C:\D\soft\soft_application\maven\repo\com\itextpdf\itextpdf\5.5.9\itextpdf-5.5.9.jar;C:\D\soft\soft_application\maven\repo\com\itextpdf\tool\xmlworker\5.5.8\xmlworker-5.5.8.jar;C:\D\soft\soft_application\maven\repo\org\apache\poi\poi-ooxml\3.14\poi-ooxml-3.14.jar;C:\D\soft\soft_application\maven\repo\org\apache\poi\poi\3.14\poi-3.14.jar;C:\D\soft\soft_application\maven\repo\commons-codec\commons-codec\1.10\commons-codec-1.10.jar;C:\D\soft\soft_application\maven\repo\org\apache\poi\poi-ooxml-schemas\3.14\poi-ooxml-schemas-3.14.jar;C:\D\soft\soft_application\maven\repo\org\apache\xmlbeans\xmlbeans\2.6.0\xmlbeans-2.6.0.jar;C:\D\soft\soft_application\maven\repo\stax\stax-api\1.0.1\stax-api-1.0.1.jar;C:\D\soft\soft_application\maven\repo\com\github\virtuald\curvesapi\1.03\curvesapi-1.03.jar;C:\D\soft\soft_application\maven\repo\org\freemarker\freemarker\2.3.28\freemarker-2.3.28.jar;C:\D\soft\soft_application\maven\repo\org\springframework\spring-beans\4.2.5.RELEASE\spring-beans-4.2.5.RELEASE.jar;C:\D\soft\soft_application\maven\repo\org\apache\commons\commons-lang3\3.9\commons-lang3-3.9.jar zeh.myjavase.code42java8.demo01.C
It's B

Process finished with exit code 0

类C同时实现了A接口和B接口,其中B接口又是A接口的子接口,其中存在相同签名的默认方法,按照第2条原则:子接口的默认方法优先级高。
因此,调用类C对象的print()方法,从子接口B中继承过来的优先级高。
运行结果符合预期。

7.3 接口和接口的方法冲突

两个毫无关系的接口,存在相同签名的方法。
Interface1接口:

package zeh.myjavase.code42java8.demo01;

public interface Interface1 {

    default void print(){
        System.out.println("It's Interface1");
    }
}

Interface2接口:

package zeh.myjavase.code42java8.demo01;

public interface Interface2 {
    default void print() {
        System.out.println("It's Interface2");
    }
}

实现类 InterfaceImpl :

package zeh.myjavase.code42java8.demo01;

public class InterfaceImpl implements Interface1, Interface2 {

    // 当多个接口中存在相同的默认方法时,此时实现类必须显式指定到底覆盖哪一个接口中的默认方法才行,否则编译报错
    @Override
    public void print() {
        Interface1.super.print();
    }

    public static void main(String[] args) {
        InterfaceImpl inter = new InterfaceImpl();
        inter.print();
    }
}

运行结果:

C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\bin\java.exe "-javaagent:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\lib\idea_rt.jar=51112:C:\D\soft\soft_application\onlyou-app\intellij-idea\IntelliJ IDEA 2018.2.5\bin" -Dfile.encoding=UTF-8 -classpath C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\charsets.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\deploy.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\access-bridge-64.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\cldrdata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\dnsns.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jaccess.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\jfxrt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\localedata.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\nashorn.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunec.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunjce_provider.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunmscapi.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\sunpkcs11.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\ext\zipfs.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\javaws.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jce.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfr.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jfxswt.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\jsse.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\management-agent.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\plugin.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\resources.jar;C:\D\soft\soft_application\jdk\jdk_window\jdk1.8\jre\lib\rt.jar;C:\D\zhaoehcode-java\myJavaSE\target\classes;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\esb_all.jar;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\basicplayer3.0.jar;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\luajava-1.1.jar;C:\D\zhaoehcode-java\myJavaSE\src\main\lib\commonentity-1.0.1-20190830.060836-388.jar;C:\D\soft\soft_application\maven\repo\junit\junit\4.11\junit-4.11.jar;C:\D\soft\soft_application\maven\repo\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\D\soft\soft_application\maven\repo\org\springframework\spring-core\4.3.7.RELEASE\spring-core-4.3.7.RELEASE.jar;C:\D\soft\soft_application\maven\repo\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\D\soft\soft_application\maven\repo\commons-lang\commons-lang\2.6\commons-lang-2.6.jar;C:\D\soft\soft_application\maven\repo\commons-beanutils\commons-beanutils\1.9.3\commons-beanutils-1.9.3.jar;C:\D\soft\soft_application\maven\repo\commons-collections\commons-collections\3.2.2\commons-collections-3.2.2.jar;C:\D\soft\soft_application\maven\repo\org\javassist\javassist\3.21.0-GA\javassist-3.21.0-GA.jar;C:\D\soft\soft_application\maven\repo\org\ow2\asm\asm\6.2\asm-6.2.jar;C:\D\soft\soft_application\maven\repo\cglib\cglib\3.2.2\cglib-3.2.2.jar;C:\D\soft\soft_application\maven\repo\org\apache\ant\ant\1.9.6\ant-1.9.6.jar;C:\D\soft\soft_application\maven\repo\org\apache\ant\ant-launcher\1.9.6\ant-launcher-1.9.6.jar;C:\D\soft\soft_application\maven\repo\dom4j\dom4j\1.6.1\dom4j-1.6.1.jar;C:\D\soft\soft_application\maven\repo\xml-apis\xml-apis\1.0.b2\xml-apis-1.0.b2.jar;C:\D\soft\soft_application\maven\repo\jdom\jdom\1.0\jdom-1.0.jar;C:\D\soft\soft_application\maven\repo\com\alibaba\fastjson\1.2.5\fastjson-1.2.5.jar;C:\D\soft\soft_application\maven\repo\com\fasterxml\jackson\core\jackson-core\2.8.7\jackson-core-2.8.7.jar;C:\D\soft\soft_application\maven\repo\com\fasterxml\jackson\core\jackson-databind\2.8.7\jackson-databind-2.8.7.jar;C:\D\soft\soft_application\maven\repo\com\fasterxml\jackson\core\jackson-annotations\2.8.0\jackson-annotations-2.8.0.jar;C:\D\soft\soft_application\maven\repo\log4j\log4j\1.2.17\log4j-1.2.17.jar;C:\D\soft\soft_application\maven\repo\com\itextpdf\itextpdf\5.5.9\itextpdf-5.5.9.jar;C:\D\soft\soft_application\maven\repo\com\itextpdf\tool\xmlworker\5.5.8\xmlworker-5.5.8.jar;C:\D\soft\soft_application\maven\repo\org\apache\poi\poi-ooxml\3.14\poi-ooxml-3.14.jar;C:\D\soft\soft_application\maven\repo\org\apache\poi\poi\3.14\poi-3.14.jar;C:\D\soft\soft_application\maven\repo\commons-codec\commons-codec\1.10\commons-codec-1.10.jar;C:\D\soft\soft_application\maven\repo\org\apache\poi\poi-ooxml-schemas\3.14\poi-ooxml-schemas-3.14.jar;C:\D\soft\soft_application\maven\repo\org\apache\xmlbeans\xmlbeans\2.6.0\xmlbeans-2.6.0.jar;C:\D\soft\soft_application\maven\repo\stax\stax-api\1.0.1\stax-api-1.0.1.jar;C:\D\soft\soft_application\maven\repo\com\github\virtuald\curvesapi\1.03\curvesapi-1.03.jar;C:\D\soft\soft_application\maven\repo\org\freemarker\freemarker\2.3.28\freemarker-2.3.28.jar;C:\D\soft\soft_application\maven\repo\org\springframework\spring-beans\4.2.5.RELEASE\spring-beans-4.2.5.RELEASE.jar;C:\D\soft\soft_application\maven\repo\org\apache\commons\commons-lang3\3.9\commons-lang3-3.9.jar zeh.myjavase.code42java8.demo01.InterfaceImpl
It's Interface1

Process finished with exit code 0

Interface1和Interface2接口中存在相同的默认方法,且两个接口没有任何继承关系,InterfaceImpl同时实现两个接口,同时继承了相同的print()方法。
按照第3条原则:实现类中必须显式指定或者复写到底要使用哪个接口中的方法,否则编译器报错。
因此,InterfaceImpl实现类中复写了print()方法,显式指定使用Interface1中继承而来的print()方法。
运行结果符合预期。

文档信息

Search

    Table of Contents