Java8 Default Methods和Static Methods 详细介绍

来源:互联网 发布:二维数组冒泡排序 编辑:程序博客网 时间:2024/04/30 13:35

Java8 以前的interface接口机制中,接口中的方法不能有具体的实现,全部要为空方法,实现类必须全部实现相关的方法。但若上层接口需要做改变的时候(如增加新的空方法),下层接口就需要实现新增的方法,在某些情况下,变得不灵活,Java8接口新增default方法,可如下定义:

public interface SomethingIsWrong {default void aMethod(int aValue) {    System.out.println("Hi Mom");}}

Default方法使用场景:
通常都是用于在已有的接口中添加新的方法,可以避免其实现类都做出相应的改动,且default方法通常使用已经存在的方法进行定义。

扩展含有default方法的接口会遇到以下三种情况:
1. 不在扩展接口中提及原default方法,则所有实现该接口的类都默认实现原接口中的default方法。
2. 重新声明和default方法名一致的方法(包括形参列表),则新接口的实现类必须实现该方法。
3. 扩展接口重新定义该default方法,注意要加default关键字,则会复写原接口中的default方法。
4. 如果该接口的实现类重新声明和default方法名一致的方法(包括形参列表),则会复写原接口中的default方法。
5. 如果一个类实现的两个接口含有相同的default方法,且这两个接口无继承关系,则该类必须明确复写该default方法,否则会发生编译错误。若这两个接口有继承关系,则会明确的接口胜过上层接口,即在实现类中表现为更明确的接口中的方法。如下代码所示,

interface A {default void doSth() {    System.out.println("inside A");}interface B {}interface C extends A {default void doSth() {    System.out.println("inside C");    }}class App implements C, B, A {public static void main(String[] args) {    new App().doSth();    }}

这将打印出inside C

interface A {default void doSth() {    System.out.println("inside A");}}interface B {default void doSth() {    System.out.println("inside B");}class App implements B, A {@Overridepublic void doSth() {    B.super.doSth();}public static void main(String[] args) {  new App().doSth();    }}

这将会打印出inside B。

参考:
http://blog.csdn.net/u013291394/article/details/52551180?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
参考Java官网文档:
https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

Static 方法:
static方法和default方法类似,但在其实现类中不能进行复写该方法,This feature helps us in avoiding undesired results incase of poor implementation in implementation classes.

public interface MyData {default void print(String str) {    if (!isNull(str))        System.out.println("MyData Print::" + str);}static boolean isNull(String str) {    System.out.println("Interface Null Check");    return str == null ? true : "".equals(str) ? true : false;    }}public class MyDataImpl implements MyData {public boolean isNull(String str) {    System.out.println("Impl Null Check");    return str == null ? true : false;}public static void main(String args[]){    MyDataImpl obj = new MyDataImpl();    obj.print("");    obj.isNull("abc");    }}

接口中的方法都默认为public,所以无需加public修饰,此处MyDataImpl中的isNull只是一个普通的类方法,并没有重写MyData中的isNull方法,
如果在isNull() 方法之前加了 @Override annotation ,则编译出错。
以上代码输出为:
Interface Null Check
Impl Null Check

如果将MyData中的isNull方法从static改为 default,那么输出结果为:
Impl Null Check
MyData Print::
Impl Null Check

Java interface的static方法只对interface里的方法可见,如果将MyDataImpl中的isNull移除,那么MyDataImpl实例就无法使用isNull方法。和其他静态方法类似,可以使用类名来调用接口中的静态方法,如下语句是合法的:

boolean result = MyData.isNull(“abc”);

Java interface的static方法几点注意事项:
1. 该static方法属于interface的一部分,不能在其实现类的实例中直接使用
2. Java interface的static方法有利于提供通用的方法,比如判空检查,集合排序等。
3. Java interface的static方法通过禁止实现类复写该方法,来帮助我们提供安全保障。
4. 不能在类的方法中定义和interface的static方法名一致签名的静态方法,会编译出错,
如果实现类复写和interface的static方法名一致签名的普通方法,用实现类的实例调用该方法时,实际调用的为实现类中的方法。
5. 通过使用Java interface的static方法,我们可以移除工具类,比如Collections,并且把所有工具类中的静态方法移动到一致的接口当中,以便于查询和使用。(待论证)

原文参考链接:
http://www.journaldev.com/2752/java-8-interface-changes-static-method-default-method

进一步理解Java 8 default方法可以参考下文:
https://my.oschina.net/benhaile/blog/176007

0 0
原创粉丝点击