1. 默认方法
JAVA8中接口能提供方法的默认实现,如果实现该接口的类不显示地提供该方法的具体实现,就会从接口中默认继承该默认方法
public interface TestDefault {
//这里的default指定该方法为默认方法,可以在接口中提供该方法的默认实现
default void printInfo(){
System.out.println("这是默认方法");
}
}
//实现类未提供接口方法的实现
public class TestDefOne implements TestDefault {
}
//提供了接口方法的实现
public class TestDef implements TestDefault {
@Override
public void printInfo() {
System.out.println("我覆盖了默认方法");
}
}
//测试
@Test
public void test(){
TestDef testDef = new TestDef();
TestDefOne testDefOne = new TestDefOne();
testDef.printInfo();
testDefOne.printInfo();
}
结果
我覆盖了默认方法
这是默认方法
Java8中的常见默认方法:Collection.stream(),List.sort()
默认方法出现的原因在于JAVA8以前实现接口要么定义它所有的方法,要么定义为抽象方法由子类实现,无论哪种情况在接口添加新方法的情况下,如果想使用该方法都必须去修改接口的所有的实现类(在不调用新方法的情况下,由于二进制级的兼容,可以在不修改类的情况下继续运行)。而由于默认方法的存在,只要把新添加的方法声明为default,实现类是默认继承该方法的,不会影响原实现类的结构,这可以实现API的平滑演化。
2.继承冲突问题
//接口A
public interface A {
default void printInfo(){
System.out.println("HelloWolrd A");
}
}
//接口B
public interface B{
default void printInfo(){
System.out.println("Nice to meet B");
}
}
public class C implements A {
@Override
public void printInfo() {
System.out.println("come from C");
}
}
//实现类
public class TestDef extends C implements B,A {
/*@Override
public void printInfo() {
//System.out.println("I`m from Test");
//B.super.printInfo();
}*/
}
//测试类
@Test
public void test() {
TestDef def = new TestDef();
def.printInfo();
}
方法签名查找机制
类中的方法优先级最高,(类自身的>父类的)
所以这里会打印
come from C
如果TestDef中的注释打开的话,他自身的方法的优先级最高
如果第一条不能判断,那么会选择子接口中拥有最具体实现的默认方法。
即如果不继承C的话,B比A更具体,所以会打印
Nice to meet B
最后还不能判断,则只能让TestDef显示实现该方法,要么自己定义方法体,
要么通过A.super.printInfo()显示调用A接口的默认方法printInfo
菱形继承问题的解决同上
3. 静态方法
可以在接口中定义一个静态方法(包含实体)
public interface A {
//默认方法
default void printInfo(){
System.out.println("HelloWolrd A");
}
//静态方法
static void getInfo(){
System.out.println("hhhh");
}
}
//通过接口直接调用该方法
A.getInfo();