Java 8新特性——default方法(defender方法)介绍
发布日期:2021-07-01 01:31:12 浏览次数:2 分类:技术文章

本文共 3080 字,大约阅读时间需要 10 分钟。

转载自 

 

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

publicinterface SimpleInterface {

  publicvoid doSomeWork();

}

 

classSimpleInterfaceImpl implementsSimpleInterface{

  @Override

  publicvoid doSomeWork() {

    System.out.println("Do Some Work implementation in the class");

  }

 

  publicstatic void main(String[] args) {

    SimpleInterfaceImpl simpObj = newSimpleInterfaceImpl();

    simpObj.doSomeWork();

  }

}

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

1

2

3

4

publicinterface SimpleInterface {

  publicvoid doSomeWork();

  publicvoid 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() inSimpleInterface

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

publicinterface SimpleInterface {

  publicvoid doSomeWork();

 

  //A default method in the interface created using "default" keyword

  //使用default关键字创在interface中直接创建一个default方法,该方法包含了具体的实现代码

  defaultpublic void doSomeOtherWork(){

    System.out.println("DoSomeOtherWork implementation in the interface");

  }

}

 

classSimpleInterfaceImpl implementsSimpleInterface{

  @Override

  publicvoid doSomeWork() {

    System.out.println("Do Some Work implementation in the class");

  }

  /*

   * Not required to override to provide an implementation

   * for doSomeOtherWork.

   * 在SimpleInterfaceImpl里,不需要再去实现接口中定义的doSomeOtherWork方法

   */

 

  publicstatic void main(String[] args) {

    SimpleInterfaceImpl simpObj = newSimpleInterfaceImpl();

    simpObj.doSomeWork();

    simpObj.doSomeOtherWork();

  }

}

该程序的输出是:

1

2

Do Some Work implementation inthe class

DoSomeOtherWork implementation inthe interface

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

更新:

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

1

2

3

4

5

6

7

8

9

10

11

publicinterface InterfaceWithDefaultMethod {

  publicvoid someMethod();

  defaultpublic void someOtherMethod(){

    System.out.println("Default method implementation in the interface");

  }

}

publicinterface InterfaceWithAnotherDefMethod {

  defaultpublic void someOtherMethod(){

    System.out.println("Default method implementation in the interface");

  }

}

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

1

2

3

4

5

6

7

8

9

10

11

12

13

publicclass DefaultMethodSample implements

  InterfaceWithDefaultMethod, InterfaceWithAnotherDefMethod{

 

  @Override

  publicvoid someMethod(){

    System.out.println("Some method implementation in the class");

  }

  publicstatic void main(String[] args) {

    DefaultMethodSample def1 = newDefaultMethodSample();

    def1.someMethod();

    def1.someOtherMethod();

  

}

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

原文链接:  翻译: 

译文链接: 

转载地址:https://maokun.blog.csdn.net/article/details/80203189 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:避免代码冗余,使用接口和泛型重构Java代码
下一篇:Java抽象类与接口的区别

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年04月18日 00时41分23秒