接口
- 接口:接口就是一个规则,而且是独立于继承体系以外的规则。(可以理解为干爹,父类只能有一个,但接口可以有多个)
- 格式:关键字interface来定义 public interface 接口名{...}
- 使用:接口和类之间是实现关系,通过implement关键字表示
public class 类名 implements 接口 {...} - 注意点1:接口不能实例化,和抽象类一样
- 注意点2:接口的子类(实现类),要么重写接口中所有的抽象方法,要么实现类是一个抽象类
- 注意点3:一个类可以有多个接口,也可以在继承一个类的同时,实现多个接口
public class 类名 extends 父类 implements 接口 1,接口2
接口中成员的特点
- 成员变量:只能是常量。默认修饰符: public static final
- 构造方法:没有(成员变量是常量,在接口中已经赋值,不需要再通过构造方法初始化)
- 成员方法:只能是抽象方法。默认修饰符 public abstract
- JDK9的新特性:接口中可以定义有方法体的方法,私有方法,不止是抽象方法
接口和类的关系
- 类和类的关系:继承关系,只能单继承,不能多继承,但是可以多层继承
- 类和接口的关系:实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
- 接口和接口的关系:继承关系,可以单继承,也可以多继承
注意点:
- 如果父类也是一个抽象类的话,那么在子类当中,需要把所有的抽象方法进行重写,要么子类本身也是一个抽象类
- 如果多个接口中出现了重复的抽象方法,此时我们只需要重写一次就可以了。
- 如果有一个接口A继承了多个接口,此时相当于是把多个接口中的抽象方法都继承了下来,在以后实现类实现接口A的时候,需要把所有的抽象方法进行重写。
JDK8以后接口中新增的方法
- 允许在接口中定义默认方法,需要使用关键字default修饰(作用:默认方法可以不用重写)
- 允许在接口中定义静态方法,需要用static修饰
接口中默认方法的定义格式:
- 格式: public default 返回值类型 方法名(参数列表){}
- 范例:public default void show(){}
接口中静态方法的定义格式:
- 格式:public static 返回值类型 方法名(参数列表){}
- 范例: public static void show(){}
接口中默认方法的注意事项:
- 默认方法不是抽象方法,所以不强制被重写,但是如果被重写,重写的时候去掉default关键字,接口中的,defualt默认方法保留default关键字
- public可以省略,default不能省略
- 如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写
接口中静态方法的注意事项:
- 只有虚方法表里面的方法才能被重写,方法重写的实际意义就是替换了虚方法表中记录方法的内存地址(虚方法表:非static、非final、非private)
- 静态方法只能用过接口名调用,不能用过类名或者对象名调用
- public可以省略,static不能省略
JDK9新增的私有方法
为了抽取默认方法和静态方法中重复代码而出现的,同时又让外界无法访问到这个方法,仅仅为了抽取接口中多个方法间的重复代码。
格式1:private 返回值类型 方法名(参数列表){}
范例1:private void show(){}
格式2:private static 返回值类型 方法名(参数列表){}
范例2:private static void method(){}
总结
- JDK7以前:接口中只能定义抽象方法
- JDK8:接口中可以定义有方法体的方法。(默认、静态)
- JDK9:接口中可以定义私有方法
- 私有方法分为两种:普通的私有方法,静态的私有方法。
默认方法的作用
一、核心作用:接口的向后兼容(最重要!)
传统 Java 接口:
- 一旦发布,不能随便新增抽象方法
- 否则所有实现类都必须强制重写,直接导致旧代码编译报错、程序崩溃
默认方法解决了这个问题:
- 接口可以直接新增带实现的方法
- 所有已有的实现类不需要做任何修改,就能自动继承这个新方法
- 完全兼容旧代码,不影响线上运行
这是 Java 设计者最核心的目的。
二、让接口具备部分实现能力
传统接口只能定义抽象方法,完全没有代码实现。
默认方法让接口:
- 可以提供通用、默认的方法逻辑
- 实现类可以直接用,也可以选择重写
- 让接口从 “纯规范” 变成 “带通用能力的规范”
三、减少重复代码,让实现类更简洁
多个实现类如果有相同逻辑:
- 以前:必须写工具类 / 抽象类来复用
- 现在:直接写在接口默认方法里
- 所有实现类自动复用,不用重复写代码
四、支持接口的功能扩展与演进
随着业务升级,接口需要加新功能:
- 以前:不敢加,一加就崩
- 现在:用默认方法安全扩展
- 让接口可以持续迭代、长期维护
这对 JDK 自身、框架(Spring、MyBatis)极其重要。
五、为 Lambda 表达式 提供支持(Java 8 关键配套)
Java 8 的 Lambda 必须依赖函数式接口(只有一个抽象方法的接口)。
默认方法:
- 可以在函数式接口里添加额外方法
- 又不破坏 “只有一个抽象方法” 的规则
- 让 Lambda 更强大、更实用
没有默认方法,Java 函数式编程会受很大限制。
六、实现接口的多继承能力
Java 类只能单继承,但接口可以多实现。
默认方法让:
- 一个类可以从多个接口获得默认方法
- 获得类似 “多继承” 的能力
- 又避免了类继承的耦合问题
浙公网安备 33010602011771号