Java8-接口的变化

2017-08-06  本文已影响40人  任重而道元

一、Java8对接口的改变

1). 增加了default方法和static方法,这两种方法完全可以有方法体

public interface TestInter {

    /** 静态方法1 */
    static void test1() {
        System.out.printf("TestInter 的静态方法 test1()");
    }

    /** 默认方法2 */
    default void test2() {
        System.out.println("TestInter 的默认方法 test2()");
    }

    /** 默认方法3 */
    default void test3() {
        System.out.println("TestInter 的默认方法 test3()");
    }

}

2). default方法属于实例,static方法属于类(接口)

编写接口

/**
 * 接口
 */
public interface TestInter {

    /** 静态方法1 */
    static void test1() {
        System.out.printf("TestInter 的静态方法 test1()");
    }

    /** 默认方法2 */
    default void test2() {
        System.out.println("TestInter 的默认方法 test2()");
    }

    /** 默认方法3 */
    default void test3() {
        System.out.println("TestInter 的默认方法 test3()");
    }

}

编写接口的实现类

/**
 * 实现接口类
 */
class TestInterface implements TestInter{

}

编写Main方法

/**
 * Main方法
 */
class TestInterfaceMain {

    public static void main(String[] args) {

        // 访问接口的静态方法
        TestInter.test1();

        // 访问接口实例的静态方法
        TestInterface test = new TestInterface();
        test.test2();
        test.test3();

    }
}

3). 接口里面的静态方法不会被继承。静态变量会被继承下来。

编写接口

/**
 * 接口
 */
public interface TestInter {

    String USER_NAME = "道哥";

    /** 静态方法1 */
    static void test1() {
        System.out.printf("TestInter 的静态方法 test1()");
    }

    /** 默认方法2 */
    default void test2() {
        System.out.println("TestInter 的默认方法 test2()");
    }

    /** 默认方法3 */
    default void test3() {
        System.out.println("TestInter 的默认方法 test3()");
    }

}

编写子接口

/**
 * 继承接口TestInter
 */
interface SunInter extends TestInter {

    /** 重写父类的test2方法,USER_NAME变量可以直接被使用 */
    default void test2() {
        System.out.println("SunInter 的默认方法 test2() " + USER_NAME);
    }

}

编写Main方法

/**
 * Main方法
 */
class TestInterfaceMain {

    public static void main(String[] args) {

        //不会被继承
        //SunInter.test1();

        // 访问接口的静态方法
        System.out.println(SunInter.USER_NAME);

    }
}

4.1). 如果一个类实现了多个接口,并且这些接口相互之间没有继承关系,同时存在相同的默认方法会报错;

编写接口

/**
 * 接口
 */
public interface TestInter {

    /** 默认方法2 */
    default void test2() {
        System.out.println("TestInter 的默认方法 test2()");
    }

}

编写接口2

/**
 * 接口2
 */
interface TestInter2 {

    /** 默认方法2 */
    default void test2() {
        System.out.println("TestInter2 的默认方法 test2()");
    }

}

实现接口1和接口2

/**
 * 同时实现了两个接口,这两个接口都包含相同的默认方法,编译不会通过,会报错的
 * 必须重写接口相同的默认方法才可以
 */
class TestInterface implements TestInter,TestInter2{

}

4.2). 如果多个接口有继承关系,默认方法会被子接口覆盖。

编写接口

/**
 * 接口
 */
public interface TestInter {

    /** 默认方法2 */
    default void test2() {
        System.out.println("TestInter 的默认方法 test2()");
    }

}

编写接口2,集成接口1

/**
 * 接口2继承接口TestInter,重写test2方法
 */
interface TestInter2 extends TestInter {

    /** 默认方法2 */
    default void test2() {
        System.out.println("TestInter2 的默认方法 test2()");
    }

}

编写实现类

/**
 * 同时实现了两个接口,这两个接口都包含相同的默认方法,编译不会通过,会报错的
 * 必须重写接口相同的默认方法才可以
 */
class TestInterface implements TestInter,TestInter2{

}

编写main方法,测试

/**
 * Main方法
 */
class TestInterfaceMain {

    public static void main(String[] args) {

        TestInterface test = new TestInterface();
        test.test2(); // TestInter2 的默认方法 test2()

    }
}

5). 如果遇到有多个继承,并且有相同的默认方法,实现类可以通过特殊语法指定要访问哪个接口的方法,在实现类中重写默认方法,在方法里面写:<接口>.super.<方法名>([参数]);

编写两个接口,声明相同的默认方法

/**
 * 接口
 */
public interface TestInter {

    /** 默认方法2 */
    default void test2() {
        System.out.println("TestInter 的默认方法 test2()");
    }

}

/**
 * 接口2继承接口TestInter,重写test2方法
 */
interface TestInter2 {

    /** 默认方法2 */
    default void test2() {
        System.out.println("TestInter2 的默认方法 test2()");
    }

}

编写接口,继承前两个接口

/**
 * 继承接口TestInter
 */
interface SunInter extends TestInter,TestInter2 {

    /** 子接口可以重写父接口的默认方法 */
    default void test2() {
        TestInter2.super.test2();
    }

}

编写接口实现类

class TestInterface implements TestInter,TestInter2{

    /** 实现类可以重写父接口的默认方法 */
    @Override
    public void test2() {
        TestInter.super.test2();
    }
}

编写mian方法,测试类

/**
 * Main方法
 */
class TestInterfaceMain {

    public static void main(String[] args) {

        TestInterface test = new TestInterface();
        test.test2(); // TestInter2 的默认方法 test2()

    }
}

6). 如果一个接口只有一个抽象方法(包括继承的),该接口是一个函数式接口。函数式接口 可以使用Lambda表达式实现。

/**
 * 因为该接口只有一个抽象方法,默认就是函数式接口
 */
public interface TestFunctionInterfacel {

    void test();

}

/**
 * 没有方法的接口是普通的接口,这种接口通常用于标记使用,比如Java的序列化
 */
interface TestFunctionInterfacel2 {

}

7). 如果接口里面使用了FunctionalInterface注解限定接口里面只能有一个抽象方法。

/**
 * 使用FunctionalInterface注解的接口,有且仅有一个抽象方法
 */
@FunctionalInterface
interface TestFunctionInterfacel3 {

    void test();

    /**
     * 可以存在静态方法
     */
    static void test2() {

    }

}

/**
 * 找到多个抽象方法,不是函数式接口,不能使用FunctionalInterface 注解
 */
/*
@FunctionalInterface
interface TestFunctionInterfacel4 {

    void test();

    void test2();

}*/
上一篇 下一篇

猜你喜欢

热点阅读