java8接口默认方法的使用

89 阅读2分钟

如下,定义一个接口Test1,其中有两个方法,一个正常的接口方法sayHi(),一个默认的接口方法sayHello(),其中默认的接口方法sayHello()已经定义了具体的实现逻辑,此时定义一个Test1的实现类,则sayHi()必须实现,否则编译报错,sayHello()则因为在接口就已经有默认的实现所以没有强制实现类必须强制实现。

/**
 * 测试接口1
 * @author wukongjian
 * @date 2019/7/25 13:44
 */
public interface Test1 {
    /**
     * 正常的接口方法
     */
    void sayHi();

    /**
     * 默认的接口方法
     */
    default void sayHello() {
        System.out.println("Test1 Hello");
    }
}

/**
 * Test1的实现类
 * @author wukongjian
 * @date 2019/7/25 13:47
 */
public class TestImpl implements Test1{

    @Override
    public void sayHi() {
        System.out.println("Hi");
    }

    public static void main(String[] args) {
        TestImpl test = new TestImpl();
        test.sayHi();
        test.sayHello();
    }

}

输出:
Hi
Test1 Hello

现在有一个问题,如果还有一个接口Test2,如下,接口方法同Test1,此时如果实现类同时实现Test1和Test2两个接口,那么此时就必须实现类重新实现sayHello()逻辑,否则报错。

/**
 * 测试接口2
 * @author wukongjian
 * @date 2019/7/25 13:44
 */
public interface Test2 {
    void sayHi();

    default void sayHello() {
        System.out.println("Test2 Hello");
    }
}

/**
 * Test1和Test2的实现类
 * @author wukongjian
 * @date 2019/7/25 13:47
 */
public class TestImpl implements Test1, Test2{

    @Override
    public void sayHi() {
        System.out.println("Hi");
    }

    public static void main(String[] args) {
        TestImpl test = new TestImpl();
        test.sayHi();
        test.sayHello();
    }

}

编译报错:

0e79a2f9-65a0-42f4-a2dc-86c0f7ca1baf.png

所以在使用接口的默认方法时,如果出现以上的这种一个实现类同时实现的几个接口中有相同的默认方法的情况,就只能老老实实地重写默认方法,如下:

/**
 * Test1和Test2的实现类
 * @author wukongjian
 * @date 2019/7/25 13:47
 */
public class TestImpl implements Test1, Test2{

    @Override
    public void sayHi() {
        System.out.println("Hi");
    }

    @Override
    public void sayHello() {
        // 重写的逻辑
        Test1.super.sayHello(); // 执行Test1接口地默认方法
        Test2.super.sayHello(); // 执行Test2接口地默认方法
        System.out.println("Test Hello");
    }

    public static void main(String[] args) {
        TestImpl test = new TestImpl();
        test.sayHi();
        test.sayHello();
    }

}

为什么使用接口默认方法?

因为这样代码可用性更好,即此时在接口中新增一个默认方法,则此接口所有存量的实现类都不需要重新去实现该新增的接口方法,直接使用即可,如Iterable接口的forEach()。