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 {
@Override
public 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