本文主要介绍Java 8default 方法的简单使用

简介

  1. default方法作为接口的一部分由实现类继承
  2. default方法的目标用户是类库设计者
    • 兼容的方式解决类库的演进问题

冲突解决

一个类可以实现多个拥有默认方法的接口,从而实现行为的多继承,按照下列步骤解决冲突

  1. 类或父类中声明的方法的优先级高于任何声明为默认方法的优先级
  2. 子接口的default方法优先级高于父接口的default方法
  3. 显式选择使用哪一个default方法

类与接口定义

相关代码托管在java8_demo

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
interface A {
default String hello() {
return "Hello From A";
}
}

interface B extends A {
@Override
default String hello() {
return "Hello From B";
}
}

class C implements A {
@Override
public String hello() {
return "Hello From C";
}
}

class D extends C implements A, B {
}


class E extends D implements A, B {
@Override
public String hello() {
return "Hello From E";
}
}

class F implements A, B {
}

interface G {
default String hello() {
return "Hello From G";
}
}

class H implements B, G {
@Override
public String hello() {
// A.super.hello() is not ok
return B.super.hello(); // 显示选择 B 的 default 方法实现
}
}

类或父类中的方法

1
2
3
4
5
6
7
8
9
10
11
 @Test
public void fatherTest() {
Supplier<D> dSupplier = D::new;
assertEquals("Hello From C", dSupplier.get().hello());
}

@Test
public void selfTest() {
Supplier<E> eSupplier = E::new;
assertEquals("Hello From E", eSupplier.get().hello());
}
  1. D 继承类 C,类 C 有自己的重写版本,优先级高于接口的 default 方法,选择父类 C 的重写版本
  2. E 有自己的重载版本,优先级高于间接父类C的重写版本和接口的 default 方法,选择自身的重写版本

子接口的default方法

1
2
3
4
5
@Test
public void sonInterfaceTest() {
Supplier<F> fSupplier = F::new;
assertEquals("Hello From B", fSupplier.get().hello());
}

F 实现接口 BA,而B有继承 A,子接口B的优先级更高,选择接口 Bdefault 实现

显式选择

1
2
3
4
5
@Test
public void explicitTest() {
Supplier<H> hSupplier = H::new;
assertEquals("Hello From B", hSupplier.get().hello());
}

接口 BG 没有继承关系,对 类 H 来说两者属于平等关系 ,必须重写,重写版本中显示选择了 Bdefault 实现