Java 8 之 默认方法(Default Methods)
在Java的interface中一直只是包含方法的定义不能有实现,而且Java也不支持多继承。参考Why Multiple Inheritance is Not Supported in Java。Java 8开始提供在interface中可以有方法的实现,这个特性叫默认方法“Default Methods”。如此以来,interface有了方法实现,Java即可实现多继承,Java一贯提倡不支持多继承,为什么这次妥协了呢?
因为interface太过依赖于他们的实现类了,要往interface中添加一个方法就必须修改所有它的实现类。Java 8中为了配合增加的Lambda表达式特性需要修改java.util包的接口来添加方法,试想一下如果没有默认方法的话,是不是要修改所有集合类的实现啊。
List> list = …
list.forEach(…);
所以,在不破坏继承关系的前提下,引入“虚拟扩展方法”的概念,在接口中添加默认方法的实现,这也是很聪明的,虽然Java语言在被设计的时候一直强调不支持多继承,看来这次也是没有办法的了,Java也变得越来越像C++了。
interface Person {
// adds a java 8 default method
default void sayHello() {
System.out.println("Hello");
}
}
class Sam implements Person {
}
new Sam().sayHello();
interface Person {
// adds a java 8 default method
default void sayHello() {
System.out.println("Hello");
}
}
interface Male {
default void sayBye() {
System.out.println("Bye");
}
}
class Sam2 implements Person, Male {
}
new Sam2().sayHello();
new Sam2().sayBye();
interface Person {
// adds a java 8 default method
default void sayHello() {
System.out.println("Hello");
}
}
interface Male {
default void sayHello() {
System.out.println("Hi");
}
}
class Sam2 implements Person, Male {
// override the sayHello to resolve ambiguity
public void sayHello() {
Male.super.sayHello();
}
}
除过以前的那些区别外,带有默认方法的interface和抽象类的区别:
抽象类是有个状态的,它可以有构造函数和成员变量
抽象类不能用于lambda表达式中
默认方法不能覆盖 equals, hashCode, toString 方法!!!
原因可以参考Brian Goetz给出的回答:Allow default methods to override Object's methods
http://viralpatel.net/blogs/java-8-default-methods-tutorial/
http://zeroturnaround.com/rebellabs/java-8-explained-default-methods/