1. 新增 函数式接口 概念
函数式接口,只包含一个抽象方法的接口。同时提供了注解@FunctionalInterface 可以检测是否符合函数式接口格式。
注意:假如接口声明了一个覆盖java.lang.Object的全局方法之一的抽象方法,那么它不会计入接口的抽象方法数量中,因为对于这类方法,任何实现类都有继承自Object的实现或自己定义的实现。 比如comparator接口
jdk1.8之后大力提倡函数式编程,新增了一个java.util.function包,该包下全是函数式接口,用以提供对函数式编程的支持。
该包下常见的四大函数式接口:
2. 接口内可以添加非抽象方法,使用default或者static修饰
从jdk1.8开始,为了对接口功能进行扩充,但又不影响其已有实现类,接口中的方法不再是只能有抽象方法(隐式的使用public abstract 修饰),但是需要使用default或者static修饰。注意,接口内的非抽象方法也只能是public访问权限,所以同样无需显示指定。一个接口可以有多个静态方法和default方法,没有个数限制。实现类只需要实现它的抽象方法即可。
2.1 对于static方法,实现类无法继承,无法重写,无法调用,只能直接由接口名调用,只属于接口本身。
如图,可以看到不支持重写,去掉重写注解编译通过,说明可以定义同名的方法,在调用时也是调用自身的
2.2 对于default方法,很明显是需要实例对象来调用的。
java不支持多继承,但支持多实现,接口中可以定义default方法后,有点变相实现了多继承的意思。但也随之而来不少问题。
类A实现接口B和接口C,两个接口中定义相同抽象方法并不影响,但是假如B和C中定义了相同的default方法(是完全相同,不是重载),会产生编译报错(将图中注释解开)提示A继承了来自B和C的不相关的默认值。可以预想一下,A的实例对象在调用world()方法时,它怎么知道该调用来自B的还是来自C的呢?怎么解决这种问题呢,重写该方法,重写的话,就不能使用default修饰了,它只能用在接口中,同时访问权限也必须是public(权限不能比原方法小嘛)如图,编译通过
另外再提一点,假如A实现接口B,继承类C,B中定义了default方法world(),C中也定义了方法world(),A中并没有重写,那么A的实例对象在调用world()方法时,优先调用父类的方法。