Java 8新特性——default方法(defender方法)介绍

Java 8新特性——default方法(defender方法)介绍

我们都知道在Java语言的接口中只能定义方法名,而不能包含方法的具体实现代码。接口中定义的方法必须在接口的非抽象子类中实现。下面就是关于接口的一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public interface SimpleInterface {
   public void doSomeWork();
}
 
class SimpleInterfaceImpl implements SimpleInterface{
   @Override
   public void doSomeWork() {
     System.out.println( "Do Some Work implementation in the class" );
   }
 
   public static void main(String[] args) {
     SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
     simpObj.doSomeWork();
   }
}

那么,如果我们在SimpleInterface里面添加一个新方法,会怎样呢?

1
2
3
4
public interface SimpleInterface {
   public void doSomeWork();
   public void doSomeOtherWork();
}

如果我们尝试编译上面的这段代码,会得到如下结果:

1
2
3
4
5
6
$javac .\SimpleInterface.java
.\SimpleInterface.java:18: error: SimpleInterfaceImpl is not abstract and does not
override abstract method doSomeOtherWork() in SimpleInterface
class SimpleInterfaceImpl implements SimpleInterface{
^
1 error

因为接口有这个语法限制,所以要直接改变/扩展接口内的方法变得非常困难。我们在尝试强化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
public interface SimpleInterface {
   public void doSomeWork();
 
   //A default method in the interface created using "default" keyword
   //使用default关键字创在interface中直接创建一个default方法,该方法包含了具体的实现代码
   default public void doSomeOtherWork(){
     System.out.println( "DoSomeOtherWork implementation in the interface" );
   }
}
 
class SimpleInterfaceImpl implements SimpleInterface{
   @Override
   public void doSomeWork() {
     System.out.println( "Do Some Work implementation in the class" );
   }
   /*
    * Not required to override to provide an implementation
    * for doSomeOtherWork.
    * 在SimpleInterfaceImpl里,不需要再去实现接口中定义的doSomeOtherWork方法
    */
 
   public static void main( String [] args) {
     SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl();
     simpObj.doSomeWork();
     simpObj.doSomeOtherWork();
   }
}

该程序的输出是:

1
2
Do Some Work implementation in the class
DoSomeOtherWork implementation in the interface

以上是对default方法的一个非常简要的介绍。如果有兴趣的话,还可以通过看这篇文档,来获取更深层次的理解。

更新:

现在大家问得比较多的一个问题是:如果一个类实现了两个接口(可以看做是“多继承”),这两个接口又同时都包含了一个名字相同的default方法,那么会发生什么情况? 在这样的情况下,编译器会报错。让我用例子来解释一下:

1
2
3
4
5
6
7
8
9
10
11
public interface InterfaceWithDefaultMethod {
   public void someMethod();
   default public void someOtherMethod(){
     System.out.println( "Default method implementation in the interface" );
   }
}
public interface InterfaceWithAnotherDefMethod {
   default public void someOtherMethod(){
     System.out.println( "Default method implementation in the interface" );
   }
}

然后我们定义一个类,同时实现以上两个接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class DefaultMethodSample implements
   InterfaceWithDefaultMethod, InterfaceWithAnotherDefMethod{
 
   @Override
   public void someMethod(){
     System.out.println( "Some method implementation in the class" );
   }
   public static void main(String[] args) {
     DefaultMethodSample def1 = new DefaultMethodSample();
     def1.someMethod();
     def1.someOtherMethod();
  
}

如果编译以上的代码,会得到一个编译器错误,如下所示。因为编译器不知道应该在两个同名的default方法中选择哪一个,因此产生了二义性。

原文链接:  blog.sanaulla.info 翻译:  ImportNew.com 黄小非
译文链接:  http://www.importnew.com/7302.html
转载请保留原文出处、译者和译文链接。]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值