1、接口增强
Java 8 对接口做了进一步的增强:
- 在接口中可以添加使用 default 关键字修饰的非抽象方法。即:默认方法(或扩展方法)
- 接口里可以声明静态方法,并且可以实现。
2、接口的静态方法
java8中为接口新增了一项功能:定义一个或者更多个静态方法。类似于类中的静态方法,接口定义的静态方法可以独立于任何对象调用。所以,在调用静态方法时,不需要实现接口,也不需要接口的实例,也就是说和调用类的静态方法的方式类似。语法如:InterfaceName.methordName()。
public class MyStaticInterface {
public static void main(String[] args) {
StaticInterface.print();
}
interface StaticInterface {
static void print() {
System.out.println("static interface");
}
}
}
注意:
- 接口的static方法不能被子接口继承;
- 使用static修饰的接口中的方法必须有主体;
- 接口的static不能被实现类重写或直接调用;
- 接口的static方法只能被接口本身调用:接口名.静态方法名。
3、接口的默认方法
默认方法允许接口方法定义默认实现,子类方法不必须实现此方法就可以拥有该方法及实现。
public interface MyDefaultInterface {
default void methord1(){
System.out.println("default methord1!");
}
default void methord2(){
System.out.println("default methord2!");
}
}
默认方法的优势:
1、默认方法主要优势是提供了一种扩展接口的方法,而不破坏现有代码。
如果一个已经投入使用的接口需要扩展一个新的方法,在Java8以前,我们必须再该接口的所有实现类中都添加该方法的实现,否则编译会出错。如果实现类数量很少且我们有修改的权限,可能工作量会少,但是如果实现类很多或者我们没有修改代码的权限,这样的话就很难解决了。而默认方法提供了一个实现,当没有显式提供时就默认采用这个实现,这样新添加的接口就不会破坏现有的代码。
2、默认方法另一个优势是该方法是可选的,实现类可以根据不同的需求而override或者采用默认实现。
在项目实战中,我们可以将大家都要共用的方法写作接口的默认方法,使用时直接实现该接口并选择默认实现。对于某些特定的需求,则可以选择override来实现。
public class DefaultInterfaceTest implements MyDefaultInterface {
@Override
public void methord1() {
System.out.println("override default methord1");
}
public static void main(String[] args) {
DefaultInterfaceTest defaultInterfaceTest = new DefaultInterfaceTest();
defaultInterfaceTest.methord1();
defaultInterfaceTest.methord2();
}
}
注意:
- 如果一个类实现两个或两个以上接口,并且多个接口中包含统一默认方法,此时,编译器将报错。这种情况,我们必须让子类Override该方法,否则无法编译通过。
- 在所有的情况,类实现的优先级高于接口的默认实现,也就是先使用自己类中定义的方法或者是父类中的方法。
- 如果是一个接口继承了另外一个接口,2个接口中也包含相同的默认方法,那么继承接口的版本具有更高的优先级。比如A扩展了B接口,那么优先使用A类里面的方法。
- 通过使用super,可以显式的引用被继承接口的默认实现,语法如下:InterfaceName.super.methodName()。
4、Java8中抽象类与接口的异同
相同点:
- 都是抽象类型;
- 都可以有实现方法(以前接口不行);
- 都可以不需要实现类或者继承者去实现所有方法(以前不行,现在接口中默认方法不需要实现者实现)。
不同点:
- 抽象类不可以多重继承,接口可以(无论是多重类型继承还是多重行为继承);
- 抽象类和接口所反映出的设计理念不同。其实抽象类表示的是"is-a"关系,接口表示的是"like-a"关系;
- 接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值;抽象类中的变量默认是 friendly 型,其值可以在子类中重新定义,也可以重新赋值。