在Java8之前,接口中只能包含抽象方法。那么这有什么样弊端呢?比如,想再Collection接口中添加一个spliterator抽象方法,那么也就意味着之前所有实现Collection接口的实现类,都要重新实现spliterator这个方法才行。而接口的默认方法就是为了解决接口的修改与接口实现类不兼容的问题,作为代码向前兼容的一个方法。接口的默认方法也是Java8的一个新的特性。
那么如何在接口中定义一个默认方法呢?来看下JDK中Collection中如何定义spliterator方法的:
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
}
可以看到定义接口的默认方法是通过default关键字。因此,在Java8中接口能够包含抽象方法外还能够包含若干个默认方法(即有完整逻辑的实例方法)。
public interface IAnimal {
default void breath(){
System.out.println("breath!");
};
}
public class DefaultMethodTest implements IAnimal {
public static void main(String[] args) {
DefaultMethodTest defaultMethod = new DefaultMethodTest();
defaultMethod.breath();
}
}
输出结果为:breath!
可以看出IAnimal接口中有由default定义的默认方法后,那么其实现类DefaultMethodTest也同样能够拥有实例方法breath。但是如果一个类继承多个接口,多个接口中有相同的方法就会产生冲突该如何解决?实际上默认方法的改进,使得java类能够拥有类似多继承的能力,即一个对象实例,将拥有多个接口的实例方法,自然而然也会存在方法重复冲突的问题。
下面来看一个例子:
public interface IDonkey{
default void run() {
System.out.println("IDonkey run");
}
}
public interface IHorse {
default void run(){
System.out.println("Horse run");
}
}
public class DefaultMethodTest implements IDonkey,IHorse {
public static void main(String[] args) {
DefaultMethodTest defaultMethod = new DefaultMethodTest();
defaultMethod.breath();
}
}
定义两个接口:IDonkey和IHorse,这两个接口中都有相同的run方法。DefaultMethodTest实现了这两个接口,由于这两个接口有相同的方法,因此就会产生冲突,不知道以哪个接口中的run方法为准,编译会出错:inherits unrelated defaults for run.....
解决方法:
针对由默认方法引起的方法冲突问题,只有通过重写冲突方法,并方法绑定的方式,指定以哪个接口中的默认方法为准。
public class DefaultMethodTest implements IAnimal,IDonkey,IHorse {
public static void main(String[] args) {
DefaultMethodTest defaultMethod = new DefaultMethodTest();
defaultMethod.run();
}
@Override
public void run() {
IHorse.super.run();
}
}
DefaultMethodTest重写了run方法,并通过 IHorse.super.run();指定以IHorse中的run方法为准。
提枪策马乘胜追击04-21 20:01
代码小兵87207-15 12:10
杨晶珍05-11 14:54
杨晶珍05-12 17:30