Java8 新添两宝——默认方法和静态方法

在Java8之前,我们只能在接口中使用方法的声明,随着需求的更变,我们需要在原有的接口中新添方法声明,这将导致所有实现该接口的类必须重写新添的方法。那么如何设计出更为“优质”的接口呢? 在Java8新特性中包含在接口中允许使用默认方法和静态方法。

Java Interface Default Method

栗子

interface Interface1 {

  default void log(String log) {
    System.out.println("Interface1 logging" + log);
  }
}

interface Interface2 {

  default void log(String str) {
    System.out.println("Interface2 logging::" + str);
  }

}

使用“default”关键字修饰接口中的默认方法,当类实现该接口时,无需强求重写该方法。

为了防止“Diamond Problem”,Java不允许多继承。栗子:有A,B,C,D四个类,B,C继承自A并重写了A中的同一个方法,如果D可以同时继承B和C,且D不重写该方法,那么编译时D到底该调用哪个父类重写的方法呢?纠结程度堪比问小盆友爸爸好还是妈妈好对不对?同样,使用了默认方法后,钻石问题也会在接口中发生:如果A类实现了B接口和C接口,B和C中存在相同的默认方法,此时A不得不重写该默认方法,否则将抛出编译时异常。

默认方法summary

1、接口中的默认方法的存在使得我们在扩展接口的时候无需担心对其实现类的“破坏”。
2、抽象类和接口之间一个重要的区别。
3、帮助开发者避免使用工具类,譬如所有Collections类中的方法可以由接口中的默认方法提供。
4、默认方法帮助移除“基础类”在的使用,实现接口的类中可以选择性重写或者保持接口中的默认方法。
5、强化Java8中Collections API对Java8中出现的Lambda表达式的支持。
6、笔者认为最费解的一点:在同一棵继承树上的类中若有一个相同的方法,则默认方法将会变得“irrelevant”。栗子:Object类是所有类的顶级父类,则默认方法无法重写Object类中的任何方法。我们在接口中定义了和Object类相同的默认方法将永远不会被调用!

Java Interface Static Method

在实现类中我们不能重写静态方法,这使得一些接口中的“优质方法”得以保护,以防实现类对其进行“不良实现”(poor implementation)

栗子:

public class DefaultStaticMethod implements Interface3 {

  public boolean isNull(String str) {
    System.out.println("Impl Null Check");

    return str == null ? true : false;
  }

  public static void main(String args[]) {
    DefaultStaticMethod obj = new DefaultStaticMethod();
    obj.print("");
    obj.isNull("abc");
  }
}

interface Interface3 {

  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;
  }
}

显而易见:相比于接口中的isNull()静态方法而言,实现类中的isNull()方法有些“poor implementation”的味道,这是Java8允许的,所以实现类中的isNull()方法仅是个简单的类方法,并不会主动重写接口中的静态方法,如果为其添加@Override注解,将会抛出编译时异常。
上述程序运行后得到:
Interface Null Check
Impl Null Check
将静态方法改成默认方法后,运行得:
Impl Null Check
MyData Print:
Impl Null Check

由此可见:静态方法只对接口方法可见,若把实现类中的isNull()方法移除,则会出现:

这里写图片描述

当然,我们可以使用类名.方法()的方式访问:boolean result = MyData.isNull(“abc”);

静态方法summary

1、仅是接口的一部分,实现类的对象不可调用。
2、提供了工具型的方法实现,譬如空值检查,集合类的排序等。
3、提供防止实现类不良重写的保障。
4、不能定义重写Object类中方法的静态方法,否则会抛出编译时异常“This static method cannot hide the instance method from Object”
5、例如Collections这样的工具类中的静态方法可以被移到对应的接口的静态方法中,便于查询和使用。

参考文献:https://www.journaldev.com/2752/java-8-interface-changes-static-method-default-method

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值