Java中接口的方法

  • Java中接口的默认方法(Java 8新特性)
  • 1 Java中的修饰符
  • 2 接口中的默认方法
  • 3 用处
  • 4 带来的问题以及Java的解决方案


Java中接口的默认方法(Java 8新特性)

1 Java中的修饰符

Java中的修饰符有public,private,protected和default四种,它们四种的区别如下表:

作用域

当前类

同一包内

子类

其他包

public





private


protected




default



作用域从大到小依次是:public,protected,default,private

2 接口中的默认方法

Java 8中新增了接口的默认方法,新增后接口中就可以有实现方法,而不需要实现类去实现其方法。在之前的接口中,如果新增方法后,其实现类则必须重写每个方法,这样带来的问题是改变接口后所有实现类也必须改变。

定义默认方法只需要用default修饰符标记一下即可:

public interface Comparable<T> {
	default int compareTo(T other) { return 0; }
}

3 用处

默认方法的一个重要用法就是“接口演化”,比如,Collection接口已经作为Java的一部分有很多年了,假设你很早前就创建过一个类:public class Bag implements Collection,而在Java 8中这个接口又增加了一个stream方法。如果此时stream方法不是默认方法,那么Bag类将不能编译,因为它没有实现这个新方法。即为接口增加一个非默认方法不能保证“源代码兼容”。

可能的疑问?

这时候很多人会想,接口中新增了默认方法后,编译是通过了,但我还能在我的类中调用新增的方法吗?同样以Collection接口为例,如果没有重新编译而直接加载这个类,并且在Bag实例上调用stream方法,这时候会调用Collection.stream方法。

4 带来的问题以及Java的解决方案

思考这样一个场景:如果先在一个接口中将一个方法定义为默认方法,然后又在超类或另一个接口中定义同样的方法,会发生什么情况?Java中对这种情况有如下的规则:

  1. 超类优先:如果超类提供了一个具体方法,同名而且有相同参数类型的默认方法会被忽略。
  2. 接口冲突:如果一个接口提供了一个默认方法,另一个接口提供了一个同名而且参数类型(不论是否是默认参数)相同的方法,必须覆盖这个方法来解决冲突。(在实现类中覆盖指定要调用的方法。)
  3. 类优先原则:如果一个类扩展了一个超类,同时实现了一个接口,并且从超类和接口继承了相同的方法。这时只会考虑超类方法,接口中的默认方法会被忽略。这就是类优先原则。