Java8新特性之默认方法

默认方法:简单的说接口可以有实现方法,而且不需要实现类去实现其方法。只需在方法名前面加个default关键字即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public interface DefaultMethod {
  default void foo(){
      System.out.println("调用DefaultMethod接口的默认方法foo");
  }

}

public class DefaultMethodTest implements DefaultMethod {

  public static void main(String[] args) {
      DefaultMethodTest defaultMethodTest = new DefaultMethodTest();
      defaultMethodTest.foo();// 调用DefaultMethod.foo

  }

}

java8抽象类与接口对比

相同点:
      1.都是抽象类型。
      2.都可以有实现方法(java 8 接口有default method)。
      3.都可以不需要实现类或者继承者去实现所有方法。
不同点:
       1.抽象类不可以多重继承,接口可以。
       2.抽象类是is-a的关系,接口表示是like-a关系。
       3.接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值;
         抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以重新赋值。

多重继承

如果一个类实现了两个接口,并且两个接口都用相同的签名定义了默认方法,这该怎么办?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public interface A {
  default void foo() {
      System.out.println("Calling A.foo()");

  }

}

public interface B {
  default void foo() {
      System.out.println("Calling B.foo()");

  }

}

public class AB implements A, B {

}
//Duplicate default methods named foo with the parameters () and () are inherited from the types B and A。

上面代码通不过编译:类AB从A,B接口继承了重复的默认方法foo。 解决此问题AB类必须重写冲突方法:

1
2
3
4
5
6
public class AB implements A, B {
  @Override
  public void foo() {
      
  }
}

如果AB类想调用接口的默认方法,那么可以按照以下方式:

1
2
3
4
@Override
public void foo() {
  A.super.foo();
}