一、原则
多个默认方法情况
使用 Java8 开发应用程序是,子类实现多个接口时,对于接口默认方法定义可能会出现多个默认方法,并且接口默认方法可能会出现同名情况,此时对于子类在实现或者调用时通常遵循三条原则:
- 1、类中的方法优先级最高
- 2、如果第一条无法进行判断,那么子接口的优先级更高:函数签名相同时,优先选择拥有最具体实现的默认方法的接口,即如果B继承了A,那么B就比A更加具体
- 3、如果还是无法判断,继承了多个接口的类必须通过显示覆盖和调用期望的方法,显示地选择使用哪一个默认方法的实现
二、解读规则细化
- 接口中定义的静态方法,只能通过接口调用
- 通过实现类的对象,可以调用接口中的默认方法,如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写后的方法
- 如果子类(或实现类)继承的父类和实现的接口声明了同名同参数的方法,那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法--类优先原则(只对方法,如果是属性需要明确指明是哪个里面的属性)
- 如果实现类实现了多个接口,而多个接口中定义了同名同参数的默认方法,那么在实现类没有重写此方法的情况下,报错--- 接口冲突,,,这就需要我们必须在实现类中重写此方法
- 如何在实现类中调用接口中被重写的方法 CompareA.super.method2();
-
如果多个接口中同名同参数是抽象方法,则实现类中这里实现的就相当于CompareA和CompaareB的抽象方法都实现了
三、示例
示例1 :
public interface CompareA {
static void method1() {
System.out.println("CompareA 静态方法");
}
default void method2() {
System.out.println("CompareA 默认方法method2");
}
default void method3() {
System.out.println("CompareA 默认方法method3");
}
void walk();
}
interface CompareB {
static void method1() {
System.out.println("CompareB 静态方法");
}
default void method2() {
System.out.println("CompareB 默认方法method2");
}
default void method3() {
System.out.println("CompareB 默认方法method3");
}
void walk();
}
class SubCompareA extends SuperCompare implements CompareA {
//这里实现的就相当于CompareA和CompaareB的抽象方法都实现了
@Override
public void walk() {
}
public void show() {
CompareA.super.method2();
CompareA.super.method3();
}
@Override
public void method2() {
System.out.println("SubCompareA method2");
}
}
class SuperCompare {
public void method3() {
System.out.println("SuperCompare method3");
}
}
class CompareATest {
public static void main(String[] args) {
//接口静态方法只能接口调用,实现类无法调用
CompareA.method1();
CompareB.method1();
System.out.println();
SubCompareA subCompareA = new SubCompareA();
subCompareA.method2();
subCompareA.method3();
subCompareA.show();
}
}
打印结果:
CompareA 静态方法
CompareB 静态方法
SubCompareA method2
SuperCompare method3
CompareA 默认方法method2
CompareA 默认方法method3
示例2:如果第一条无法进行判断,那么子接口的优先级更高
/**
* 定义手机接口 提供默认info方法
*/
public interface Phone {
default void info(){
System.out.println("这是一部手机");
}
}
/**
* 定义MiPhone子接口 并继承 Phone 父接口 同时也提供info方法
*/
public interface MiPhone extends Phone{
default void info(){
System.out.println("这是一部小米手机");
}
}
/**
* 实现 Phone MiPhone 接口
*/
public class M2sPhone implements Phone,MiPhone {
public static void main(String[] args) {
new M2sPhone().info();
}
}
打印结果:
这是一部小米手机
示例3:类优先原则(只对方法,如果是属性需要明确指明是哪个里面的属性)
interface A { int x = 0}
class B { int x = 1}
class C extends B implement A {
public void px() {
System.out.println(x);//编译不通过
System.out.println(super.x);//父类的x
System.out.println(A.x); //接口的x
}
}
示例4:如果多个接口中同名同参数是抽象方法,则实现类中这里实现play方法的就相当于Playable 和Bounceable 的抽象方法都实现了
interface Playable {
void play();
}
interface Bounceable {
void play();
}
interface Rollable extends Playable,Bounceable {
Ball ball = new Ball("PingPang");
}
class Ball implement Rollable {
private String name;
public String getName() {
return name;
}
public Ball(String name) {
this.name = name;
}
public void play() {
System.out.println(ball.getName());
}
}
四、接口interface
java中类单继承,接口可以多重继承
接口中不能定义构造器。接口不能实例化
如果实现类覆盖了接口中所有的方法则实现类就可以实例化
如果实现类没有覆盖接口中多有抽象方法,则实现类为抽象类
抽象类可以不实现接口的抽象方法,或者实现部分,但继承抽象类的普通类需要实现抽象中剩下的没有实现接口的抽象方法。
C+B 中合计的重写方法,必须 =A中所有的方法。
C,B中若有扩展的方法,就>A中所有的方法。
interface Flyable {
void run();
void fly();
}
abstract class Bus implements Flyable {
}
abstract class Bus1 extends Bus {
@Override
public void run() {
}
}
class Bus2 extends Bus1 {
@Override
public void fly() {
}
}
class Car implements Flyable {
@Override
public void run() {
}
@Override
public void fly() {
}
}