java8新特性之接口中的默认方法与静态方法

11/28/2019 默认方法静态方法

# 默认方法

Java 8中允许接口中包含具有具体实现的方法,该方法称为 “默认方法”,默认方法使用 default 关键字修饰。

一个例子

/**
 * @author black猫
 * @date 2019-11-27
 * 一个接口
 */
public interface MyInterface<T> {

    /***
     * sayHi 抽象方法
     * @param name
     * @return
     */
    T sayHi(String name);

    /***
     * sayHello 默认方法
     * @param name
     * @return
     */
    default String sayHello(String name) {
        return "Hello :" + name;
    }
}

/**
 * @author black猫
 * @date 2019-11-28
 * 实现类
 */
public class MyInterfaceImpl implements MyInterface<String> {

    /***
     * sayHi 方法
     * @param name
     * @return
     */
    @Override
    public String sayHi(String name) {
        return "Hi :" +name;
    }
}

/***
 * @author black猫
 * @date 2019-11-27
 * 接口的实现类 测试
 */
public class MyInterfaceTest {
    /***
     * 测试默认方法
     */
    @Test
    public void test01() {
        MyInterface myInterface = new MyInterfaceImpl();
        // MyInterfaceImpl类并没有实现 sayHello 方法就可以调用 MyInterface接口的静态方法
        System.out.println(myInterface.sayHello("Tom"));
        //  Hello :Tom
        System.out.println(myInterface.sayHi("Jim"));
        //  Hi :Jim
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

默认方法的重写,修改MyInterfaceImpl

/**
 * @author black猫
 * @date 2019-11-28
 * 实现类
 */
public class MyInterfaceImpl implements MyInterface<String> {

    /***
     * sayHi 方法
     * @param name
     * @return
     */
    @Override
    public String sayHi(String name) {
        return "Hi :" +name;
    }

    /***
     * sayHello 默认方法
     * @param name
     * @return
     */
    @Override
    public String sayHello(String name) {
        return "hello: "+name+" by MySuperClass...";
    }

}

/**
 * @author black猫
 * @date 2019-11-27
 * 接口的实现类 测试
 */
public class MyInterfaceTest {
    /***
     * 测试
     */
    @Test
    public void test01() {
        MyInterface myInterface = new MyInterfaceImpl();
        System.out.println(myInterface.sayHello("Tom"));
        //  hello: Tom by MySuperClass...
        System.out.println(myInterface.sayHi("Jim"));
        //  Hi :Jim
    }

}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

默认方法的继承

默认的方法也可以被继承

/**
 * @author black猫
 * @date 2019-11-27
 * 接口的实现类 测试
 */
public class MyInterfaceTest {

    @Test
    public void test02() {
         new Interface02(){}.printHello();
        //   Interface01 hello!
         new Interface03(){}.printHello();
        //   Interface03 hello!
         new Interface04(){
             @Override
             public void printHello() {
                 System.out.println("Interface04 hello!");
             }
         }.printHello();
        //   Interface04 hello!
    }
}
// Interface01接口里面有一默认方法
interface Interface01 {
    default void printHello() {
        System.out.println("Interface01 hello!");
    }
}

/***
 * Interface02 继承 Interface01 默认方法被继承
 */
interface Interface02 extends Interface01 {
}


/***
 * Interface03 继承 Interface01 默认方法继承后重写默认方法
 */
interface Interface03 extends Interface01 {
    @Override
    default void printHello() {
        System.out.println("Interface03 hello!");
    }
}

/***
 * Interface04 继承 Interface01 默认方法继承后重新定义为抽象方法
 */
interface Interface04 extends Interface01 {
    @Override
    void printHello();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

默认方法的多继承

当接口的默认方法有冲突时,需要自己重写调用方法,也可以使用 InterfaceName.super.methodName(); 的方式手动调用需要的接口默认方法。


// Interface05接口有一个默认方法 printHello
interface Interface05 {
    default void printHello() {
        System.out.println("Interface05 hello!");
    }
}

// Interface06接口有一个默认方法 printHi
interface Interface06 {
    default void printHi() {
        System.out.println("Interface06 hi!");
    }
}

// Interface07接口有两个默认方法 printHello 和 printHi
interface Interface07 {
    //默认方法 printHello
    default void printHello() {
        System.out.println("Interface07 hello!");
    }
    //默认方法 printHi
    default void printHi() {
        System.out.println("Interface07 hi!");
    }
}

// Class08 继承 Interface05和Interface06
class Class08 implements Interface05, Interface06 {

}

// 报错 Class09 继承 Interface06和Interface07 
// 默认方法printHi冲突 必须选择重写一个父类的printHi
//class Class09 implements Interface06, Interface07 {
//
//}


// Class10 继承 Interface06和Interface07
// 默认方法冲突 选择一个重写
class Class10 implements Interface06, Interface07 {
    @Override
    public void printHi() {
        //覆写存在歧义的方法,可以使用 InterfaceName.super.methodName(); 的方式手动调用需要的接口默认方法。
        Interface06.super.printHi();
        Interface07.super.printHi();
        System.out.println("Class10 hi!");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

接口和抽象类(类优先原则)

当接口继承行为发生冲突时,类的方法声明优先于接口默认方法,无论该方法是具体的还是抽象的。

/**
 * @author black猫
 * @date 2019-11-28
 * 
 */
public class AbstractTest {

    public static void main(String[] args) {
        Class001 class001 = new Class001();
        class001.printHello();
        //  hello interface01...
        class001.printHi();
        //  hi abstract01...
    }

}

// 继承抽象类Abstract001  并且实现接口Interface001
class Class001 extends Abstract001 implements Interface001 {

    @Override
    public void printHello() {
        Interface001.super.printHello();
    }

}

// 一个接口有两个默认方法
interface Interface001 {
    default void printHello() {
        System.out.println("hello interface01...");
    }

    default void printHi() {
        System.out.println("hi interface01...");
    }
}

//一个抽象类 有一个抽象方法 一个实现的方法
abstract class Abstract001 {

    abstract void printHello();

    public void printHi() {
        System.out.println("hi abstract01...");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

接口的静态方法

接口的静态方法和类的静态方法使用一致

/**
 * @author black猫
 * @date 2019-11-28
 * Java 8 还在允许在接口中定义静态方法。
 */
public class StaticTest {

    public static void main(String[] args) {
        Interface.printHelloWorld();
    }

}

/**
 * Interface接口有一个静态方法 printHelloWorld
 */
interface Interface {
    /***
     * 静态方法
     */
    static void printHelloWorld() {
        System.out.println("Interface11 printHelloWorld...");
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 我的小结

java8的接口默认方法降低了实现类之间的耦合,当需要为一个接口添加方法时,不必对所有实现类都修改。可以为接口添加新的默认方法,而不会破坏已有的接口的实现,也为升级旧接口且保持向后兼容提供了新的途径。

文章首发于黑猫のBlog (opens new window)欢迎来留言啊!!!

Last Updated: 8/20/2021, 5:31:07 PM