接口
大约 4 分钟
解决多重继承问题,但又不会产生致命方块的问题
基本概念
接口定义了某一批类所需要遵守的规范
- 定义:
public interface test(){}
- 定义:
接口不关心这些类的内部数据,也不关心这些类里的方法的实现细节,它之规定这些类里必须提供某些方法
实现类必须实现接口中所有方法,未全部实现则需将类变为抽象类
调用:
import 包名.*
或import 包名.接口名
接口不能实例化,只能通过引用指向类实例
接口的灵活性就在于“规定一个类必须做什么,而不管你如何做”。可以定义一个接口类型的引用来指向实现接口的类的实例,当这个引用调用方法时,会根据实际引用类的实例来判断具体调用哪个方法,这是一种典型的多态的表现
当接口引用指向实现类时,不能直接调用实现类独有的方法,需要进行强制类型转换才可以调用
默认方法和静态方法自 JDK1.8 后可以在接口中应用,默认方法可以在实现类中应用,静态方法只属于接口
在一个Java文件中可以存在多个类,多个接口。但是 只能存在一个public修饰的类或接口,且此时文件名需要与public修饰的类或者接口同名
接口只能使用两种访问修饰符
- 默认访问权限(包内可见)
public
常量
- 默认访问修饰符:
public static final
,三个任意一个缺省不影响使用 - 接口中定义的常量在定义时必须初始化
- 可通过
接口名.常量名
访问
- 默认访问修饰符:
抽象方法(成员方法)
- 默认访问修饰符:
public abstract
,两个任意一个缺省不影响使用 - 实现类中实现抽象方法后,可通过 接口引用 或者 实现类引用 访问相关方法
- 默认访问修饰符:
默认方法
- 接口中可以使用
default
关键字定义默认方法,子类中不需要实现,可以带方法体 - 定义:
public default 返回值类型 方法名(参数列表){方法体}
(public
为默认访问修饰符,可省略) - 可以在实现类中重写与重载,重写时去掉
default
关键字,重载的方法无法通过接口引用访问- 重写方法后,可以通过
接口名.super.默认方法名()
调用接口中原有的默认方法,不加super
只能调用接口的静态成员
- 重写方法后,可以通过
- 使用场景:使用接口中的某些方法,而其他一些方法重新实现没有意义
- 接口中可以使用
静态方法
- 接口中可以使用
static
关键字定义静态方法,可以带方法体 - 实现类中无法继承接口中的静态方法
- 不可以在实现类中重写,可以存在相同静态格式,但相互独立
- 定义:
public static 返回值类型 方法名(参数列表){方法体}
(public
为默认访问修饰符,可省略) - 在实现类中需要通过接口名进行访问
- 使用场景:希望更多的接口拓展方法支持在无实例对象产生的情况下调用
- 接口中可以使用
多接口
实现类可以通过
implements
实现多个接口,通过 逗号分隔,当实现类同时继承父类并实现接口时,需要先继承后实现多个接口中存在相同成员,类同时实现多个接口,子类无法分辨,需要在子类中重新定义
继承的父类和实现的接口中存在相同定义的成员,类中无实现时,会优先继承父类的成员及静态方法
接口继承
- 子接口可以通过
extends
继承多个接口,接口之间通过逗号分隔 - 多个接口中有重名方法,子接口继承时应重写父接口中的重名方法
- 单继承中:子接口可继承父接口中定义的常量、抽象方法、默认方法,无法继承静态方法
- 多继承中:只可继承父接口中定义的抽象方法,常量和默认方法无法分辨
接口与抽象类
- 抽象类通常用来捕捉子类的通用特性,即更加侧重重用
- 接口多是为了把程序模块进行固化的契约,即侧重降低耦合,可以理解为 更加抽象的抽象类
- 当希望描述多种毫无关系的类型之间的共同行为能力,更推荐用接口
- 当多类间可以形成可追溯的产生轨迹,则更推荐抽象类继承