我们都知道在Java语言的接口中只能定义方法名,而不能包含方法的具体实现代码。接口中定义的方法必须在接口的非抽象子类中实现。下面就是关于接口的一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
那么,如果我们在SimpleInterface里面添加一个新方法,会怎样呢?
1 2 3 4 |
|
如果我们尝试编译上面的这段代码,会得到如下结果:
1 2 3 4 5 6 |
|
因为接口有这个语法限制,所以要直接改变/扩展接口内的方法变得非常困难。我们在尝试强化Java 8 Collections API,让其支持lambda表达式的时候,就面临了这样的挑战。为了克服这个困难,Java 8中引入了一个新的概念,叫做default方法,也可以称为Defender方法,或者虚拟扩展方法(Virtual extension methods)。
Default方法是指,在接口内部包含了一些默认的方法实现(也就是接口中可以包含方法体,这打破了Java之前版本对接口的语法限制),从而使得接口在进行扩展的时候,不会破坏与接口相关的实现类代码。接下来,让我们看一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
该程序的输出是:
1 2 |
|
以上是对default方法的一个非常简要的介绍。如果有兴趣的话,还可以通过看这篇文档,来获取更深层次的理解。
更新:
现在大家问得比较多的一个问题是:如果一个类实现了两个接口(可以看做是“多继承”),这两个接口又同时都包含了一个名字相同的default方法,那么会发生什么情况? 在这样的情况下,编译器会报错。让我用例子来解释一下:
1 2 3 4 5 6 7 8 9 10 11 |
|
然后我们定义一个类,同时实现以上两个接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
如果编译以上的代码,会得到一个编译器错误,如下所示。因为编译器不知道应该在两个同名的default方法中选择哪一个,因此产生了二义性。
原文链接: blog.sanaulla.info 翻译: ImportNew.com- 黄小非
译文链接: http://www.importnew.com/7302.html
[ 转载请保留原文出处、译者和译文链接。]