Java 8 新特性(二):接口的默认、静态方法
JAVA 8对接口进行了升级,原来的接口只能含有无方法体的方法定义,现在则引入了默认方法和静态方法的概念。
文章目录
概念
JAVA 8中引入的默认方法和静态方法是在接口中能够具有方法体的,分别被default和static关键字修饰的方法。
引入原因
默认方法
JAVA 8 中引入接口默认方法的主要场景如下:
以前创建了一个接口,并且已经被大量的类实现。
如果需要再扩充这个接口的功能加新的方法,就会导致所有已经实现的子类需要重写这个方法。
如果在接口中使用默认方法就不会有这个问题,原来的子类就不需要再重写这个方法了,只需要实际需要该接口的实现类进行重写。
所以从 JDK8 开始新加了接口默认方法,便于接口的扩展。
静态方法
接口的静态方法定义之后并不能够被其实现类发现,即不能通过实现类调用接口的静态方法,其调用只能通过**(接口名称.静态方法)**的形式调用,通过实现类或者实现类实例进行调用时都会提示“static method may be invoked on containing interface class only.”。
但接口中引入静态方法的实际用途不太明确,在网上找到一个样例,是讲在 JAVA 8 支持接口静态方法后,通过其来进行代码重构,提高代码内聚性的相关样例。
方法定义规则
1.默认方法使用 default 关键字,一个接口中可以有多个默认方法。
2.接口中既可以定义抽象方法,又可以定义默认方法,默认方法不是抽象方法。
3.子类实现接口的时候,可以直接调用接口中的默认方法,即继承了接口中的默认方法。
4.接口中同时还可以定义静态方法,静态方法通过接口名调用。
方法调用
默认方法
实现类未重写默认方法时,调用时默认调用接口的默认方法,若实现类重写了默认方法,则调用实现类的重写方法。
基于 JAVA 类单继承,多实现的情况,可能会出现继承或实现的类和接口中有重名的默认方法的问题,主要有以下四种情形:
1.一个类实现了一个接口的默认方法
接口MyInterface:
package cn.dyg.lambda.defaultmethod;
/**
* MyInterface 接口是 测试默认方法和静态方法的接口
*
* @author dongyinggang
* @date 2020-10-10 16:52
**/
public interface MyInterface {
/**
* 在interface里面的变量都是public static final 的
*
* 接口就是提供一种统一的协议, 而接口中的属性也属于协议中的成员。
* 它们是公共的,静态的,最终的常量。相当于全局常量。
*
* 尽管不写public static final,也是默认常量
*/
String INTERFACE_STATIC_VARIABLE = "静态变量";
/**
* defaultMethod 方法是 接口默认方法
*
* 接口的默认方法被引入的主要原因:
* 以前创建了一个接口,并且已经被大量的类实现。
* 如果需要再扩充这个接口的功能加新的方法,就会导致所有已经实现的子类需要重写这个方法。
* 如果在接口中使用默认方法就不会有这个问题。
* 所以从 JDK8 开始新加了接口默认方法,便于接口的扩展。
*
* @author dongyinggang
* @date 2020/10/10 16:53
*/
default void defaultMethod(){
System.out.println("这是接口MyInterface的默认方法");
}
/**
* defaultMethodWaitOverride 方法是 等待重写的接口默认方法
*
* @author dongyinggang
* @date 2020/10/12 9:47
*/
default void defaultMethodWaitOverride(){
System.out.println("等待重写的默认方法");
}
/**
* staticMethod 方法是 接口静态方法
*
* 在Java 8中,在接口中添加静态方法带来了一个限制 :这些方法不能由实现它的类继承。
* 这样做是有道理的,因为一个类可以实现多个接口。如果2个接口具有相同的静态方法,
* 它们都将被继承,编译器就不知道要调用哪个接口。
*
* 参考:
* 关于在java 8中,为什么不能调用当前类正在实现的接口的静态方法的解释
* https://blog.csdn.net/u012580143/article/details/81217732
*
* 疑问:
* 引入的原因是什么?有什么源码级应用么?暂时个人理解是有部分方法实现可以通过static方法写在接口中,
* 不需要必须写一个实现类来实现对应方法。提高代码的内聚性。
*
* 代码进化史:Java8接口静态方法应用
* https://my.oschina.net/geektao/blog/3156306
*
* @author dongyinggang
* @date 2020/10/10 16:53
*/
static void staticMethod(){
System.out.println("这是接口的静态方法");
}
/**
* ordinaryMethod 方法是 普通方法
*
* @author dongyinggang
* @date 2020/10/10 16:54
*/
void ordinaryMethod();
}
实现类DefaultMethodDemo:
package cn.dyg.lambda.defaultmethod;
/**
* DefaultMethodDemo 类是接口默认方法demo类
*
* 参考内容:
* 1.Java8 在接口的变化:
* https://blog.csdn.net/axuanqq/article/details/82773631
* 2.接口默认方法
* https://blog.csdn.net/h294590501/article/details/80303722
* 3.JAVA8学习5-接口默认方法(default)
* https://blog.csdn.net/z_yemu/article/details/89312788?utm_medium=distribute.pc_relevant.none-task-blog-title-4&spm=1001.2101.3001.4242
*
* @author dongyinggang
* @date 2020-10-10 16:58
**/
public class DefaultMethodDemo implements MyInterface {
public static void main(String[] args) {
DefaultMethodDemo defaultMethodDemo = new DefaultMethodDemo();
//1.接口的默认方法
defaultMethodDemo.defaultMet