Java中的接口是一种引用类型,是方法特征的集合,在JDK8及之后版本中可以包含默认方法、静态方法和私有方法。接口本身不能实例化,需要被类实现或者被其他接口继承,是Java实现抽象和多态的重要载体。

Java接口的核心作用
1. 定义统一规范
接口最常见的用途是定义一组通用的方法规范,要求实现类必须实现这些方法,避免不同开发者实现相同功能时出现方法命名、参数不一致的问题。比如定义数据访问层的基础接口,统一增删改查的方法结构:
// 定义基础数据访问接口
public interface BaseDao<T> {
// 新增数据
void add(T entity);
// 根据id删除数据
void deleteById(Integer id);
// 根据id查询数据
T getById(Integer id);
// 查询所有数据
List<T> getAll();
}
所有业务模块的Dao类实现这个接口后,都必须提供上述四个方法的实现,保证整个项目的数据访问层结构统一。
2. 实现多态特性
接口可以声明变量,指向其实现类的实例,这是Java多态的典型体现。通过接口类型的变量调用方法时,实际执行的是实现类中重写的方法,让代码可以更灵活地切换不同的实现逻辑。
public interface PaymentService {
// 支付方法
void pay(double amount);
}
// 微信支付实现类
public class WechatPayment implements PaymentService {
@Override
public void pay(double amount) {
System.out.println("使用微信支付,金额:" + amount);
}
}
// 支付宝支付实现类
public class AlipayPayment implements PaymentService {
@Override
public void pay(double amount) {
System.out.println("使用支付宝支付,金额:" + amount);
}
}
public class OrderService {
private PaymentService paymentService;
// 构造方法注入支付服务
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
public void createOrder(double amount) {
// 调用支付方法,实际执行的是注入的实现类逻辑
paymentService.pay(amount);
}
}
3. 降低代码耦合度
接口将方法的声明和具体实现分离,上层模块只需要依赖接口,不需要关心下层的具体实现类,当实现类需要替换或者修改时,上层代码不需要做任何改动,降低了模块之间的耦合度。
比如上述订单服务的代码中,OrderService只依赖PaymentService接口,如果需要把微信支付改成支付宝支付,只需要把注入的实现类换成AlipayPayment即可,OrderService的代码完全不用修改。
4. 支持多继承扩展
Java的类是单继承的,但是一个类可以实现多个接口,一个接口也可以继承多个接口,这弥补了类单继承的局限性,让类可以拥有多种不同的能力。
// 可飞行接口
public interface Flyable {
void fly();
}
// 可游泳接口
public interface Swimmable {
void swim();
}
// 鸭子类同时实现两个接口
public class Duck implements Flyable, Swimmable {
@Override
public void fly() {
System.out.println("鸭子飞起来了");
}
@Override
public void swim() {
System.out.println("鸭子在水里游");
}
}
Java接口的设计思想
面向接口编程思想
接口的设计核心是面向接口编程,而不是面向实现编程。这种思想的核心是依赖抽象而不是依赖具体,把不变的部分抽象成接口,变化的部分放在实现类中,让系统更容易应对需求变化。
在实际开发中,我们通常会按照以下层次使用接口:先定义业务层的接口,再写接口的实现类,上层调用方只依赖接口,这样后续如果需要替换实现逻辑、或者增加新的实现,都不会影响上层代码。
契约式设计思想
接口本质上是一种契约,定义了实现类必须遵守的规则。实现类必须实现接口中所有的抽象方法(除非实现类是抽象类),就像签订合同一样,双方都要遵守约定的内容。这种契约式的设计让不同模块之间的协作更规范,减少了沟通成本和出错概率。
开闭原则的体现
接口是开闭原则的重要实现手段,开闭原则要求对扩展开放,对修改关闭。通过接口,我们可以在不修改原有代码的基础上,新增接口的实现类来扩展功能,比如上述的支付场景,后续要新增银联支付,只需要新增一个实现PaymentService接口的类即可,不需要修改原有的支付相关代码。
接口使用的注意事项
- 接口中的抽象方法默认是
public abstract修饰,不需要显式写出 - JDK8之后接口中的默认方法用
default修饰,实现类可以选择重写也可以直接继承 - 接口中不能定义普通成员变量,只能定义
public static final修饰的常量 - 不要为了使用接口而滥用接口,如果某个功能只有一个实现类,且未来扩展可能性极低,也可以直接写实现类,避免过度设计