java java8中的default方法

是什么?为什么使用default方法?可能遇到哪些问题?

参考:https://www.zhihu.com/question/41166418

 

一、是什么

default是Java8中的关键字。

 

在Java8中,可以在接口中实现方法(Java8中的static方法也可以在接口中实现,但这是另一个话题)。接口中被实现的方法叫做default方法,用关键字default作为修饰符来标识。

当一个类实现一个接口的时候,它可以实现已经在接口中被实现过的方法(不是必须的,可以重写)。这个类会继承default方法,所以当接口发生改变的时候,实现类不需要做改动。

二、为什么使用default

我们都知道在Java语言的接口中只能定义方法名,而不能包含方法的具体实现代码。

接口中定义的方法必须在接口的非抽象子类中实现。

举个我们都知道的例子,先写一个接口类:

testInterface.java

写一个实现类,实现method1方法:

testImpl.java

我们都知道,接口是一种协议,一般情况下是不应该变动的。但是我们在考虑接口方法时,不可能永远都考虑得那么周全,有时候也会想要在接口中加上新的方法。

那么问题来了:要如何新增新的接口方法?直接在接口写上一个新的方法吗?

如果这样做,实现类也要跟着接口实现这个新加的method2方法,否则实现类将无法通过编译。

如果我们不在实现类中实现method2方法,尝试使用javac进行编译:

6

既然实现类无法通过编译,当然就无法使用了。所以,不能随便新增接口方法。

这种问题非常影响版本的更新。举个例子:

在Java7,java.util.List接口没有sort方法,直到Java8才添加了这个方法。假如我在当时写了个类名为MyList,实现了List<T>接口,那当然不需要实现这个sort()方法(因为根本就没有)。

但是当我把JDK升级到1.8的时候,突然发现java.util.List接口上多了个方法,于是我的MyList类也得实现这个方法,并且重新编译才可以继续使用。

这个问题就很尴尬了。如果我新增一个接口方法,用户的实现类全部完蛋,需要实现接口方法再重新编译。如果我不新增接口方法,那么将永远无法新增功能。简直是进退两难,变着花样赶跑用户。

因此,我们需要一个解决方案:怎样才能在不需要改动实现类的基础上,在接口中新增方法?

于是,在Java8中作出了这样的改动:可以通过default关键字修饰接口方法,在接口中直接实现。实现类会直接继承default方法,不需要重新实现,甚至不需要重新编译。

改写testInterface.java:

尝试使用javac编译,编译通过。实现类继承了接口中的method2方法,可以直接调用:

testImpl.java

结果为:

这就是我们使用default的原因。

三、可能遇到的问题

刚才我们提到:“实现类继承了接口中的method2方法”。既然提到了继承,那就要警惕多继承问题。

如果实现类同时实现了testInterface1和testInterface2接口,两个接口中各有一个同名的default方法。如果你不重写method2,方法编译器将会提示错误:

你必须选择其中一个default方法进行实现(比如testInterface1中的default方法):

但是,如果你手动实现了method2方法,即表示不选择继承两个接口中的任何一个default方法:

将不会遇到这个问题。

提到多继承,我就想起了这篇文章:

java 多继承

文章中有一种声明多继承的方法:同时继承父类并且实现接口。

在当时我没有想明白接口如何实现继承(我以为接口方法都是需要自己实现的,不能继承现有的实现,算不上继承),现在看到实现类可以继承接口中的default方法,感觉有些茅塞顿开了。

四、总结

现在可以通过default新增接口方法了,能更好地完成接口的更新。但是不要忘记,接口是一种协议,应该在设计初期就考虑完善,设计完成之后还是少修改为妙。

1 对 “java java8中的default方法”的想法;

发表评论

电子邮件地址不会被公开。 必填项已用*标注