默认方法
多继承
java 类可以实现多个接口,而在java8中,接口中可以有默认方法实现,相当于实现了“多继承”。如果一个类实现了两个含有相同默认方法的接口,会怎么样呢,我们做个小例子试一下
public interface InterfaceA {
default void defaultMethod(){
System.out.println("Interface A default method");
}
}
public interface InterfaceB {
default void defaultMethod(){
System.out.println("Interface B default method");
}
}
public class Impl implements InterfaceA, InterfaceB {
}
上面的例子会报编译错误 :
java: class Impl inherits unrelated defaults for defaultMethod() from types InterfaceA and InterfaceB
重写
如果要解决上面的情况,可以在实现类中提供默认方法的实现
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod() {
System.out.println("Class Impl default method");
}
public static void main(String[] args) {
Impl impl = new Impl();
impl.defaultMethod();
}
}
输出:
Class Impl default method
调用父接口实现
此外,如果我们想要调用父接口默认方法的实现,可以指定接口的名字,如:父接口.super.方法
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod() {
InterfaceA.super.defaultMethod();
InterfaceB.super.defaultMethod();
System.out.println("Class Impl default method");
}
public static void main(String[] args) {
Impl impl = new Impl();
impl.defaultMethod();
}
}
输出:
Interface A default method
Interface B default method
Class Impl default method
类优先于接口
如果Impl继承一个父类实现了InterfaceA,那么Impl可以不需要提供InterfaceA的实现,编译器会默认选择父类的方法实现。
public class ClassA implements InterfaceA{
@Override
public void defaultMethod() {
System.out.println("Class A default method");
}
}
public class Impl extends ClassA implements InterfaceB {
public static void main(String[] args) {
Impl impl = new Impl();
impl.defaultMethod();
}
}
输出:
Class A default method
默认方法与常规方法的区别
默认方法与常规方法是不同的,默认方法需要default修饰符。另外,常规方法可以使用和修改方法参数和属性,默认方法却不可以,因为接口没有任何状态,所以默认方法只能访问方法参数。
总之,默认方法能为已经存在的接口添加新的功能,而不会打破已有接口的原有实现
当我们扩展一个含有默认方法的接口时,遵循以下规则
- 如果不覆盖默认方法,就会继承父接口的默认方法
- 覆盖默认方法与子类覆盖父类方法一样
- 将默认方法重新声明为抽象的,这样就可以强制子类提供实现