【MapSheep】
[好记性不如烂笔头]


你想知道 Java 中接口、抽象类、设计模式的核心使用场景,我会用「场景+判断标准+示例」的方式讲清楚,每个知识点都给「什么时候用」「为什么用」,新手也能直接对应到实际开发场景。

一、接口(Interface):定义「能力/规范」,解耦实现

1. 核心使用场景

接口是「行为契约」,只定义做什么,不定义怎么做,适用于:

场景 示例 核心原因
定义通用能力(多实现) 定义 Payable 接口(包含 pay() 方法),让 AlipayPayWechatPayUnionPay 分别实现 不同支付方式都有「支付」能力,但实现逻辑不同,接口统一规范
解耦模块/跨系统交互 微服务中定义 UserService 接口,提供给订单模块调用,用户模块内部实现可随意改 屏蔽实现细节,模块间只依赖接口,降低耦合
标记型接口(无方法) SerializableCloneable 告诉 JVM/框架:实现该接口的类具备某类特性(如可序列化)
多继承需求(Java 单继承) 一个类需要同时具备 Runnable(线程能力)和 Comparable(比较能力) Java 类只能继承一个类,但可实现多个接口,补充多维度能力

2. 判断标准(满足其一就用接口)

  • 你需要定义「做什么」,但不关心「怎么做」;
  • 多个类有相同的行为,但实现逻辑完全不同;
  • 想让一个类具备多种独立能力(多维度扩展);
  • 跨模块/跨系统交互,需要屏蔽实现细节。

3. 示例代码

// 定义支付能力接口
public interface Payable {
    // 只定义规范,不实现
    boolean pay(BigDecimal amount);
}

// 支付宝实现
public class AlipayPay implements Payable {
    @Override
    public boolean pay(BigDecimal amount) {
        // 支付宝支付逻辑
        return true;
    }
}

// 微信支付实现
public class WechatPay implements Payable {
    @Override
    public boolean pay(BigDecimal amount) {
        // 微信支付逻辑
        return true;
    }
}

二、抽象类(Abstract Class):定义「模板/共性」,复用代码

1. 核心使用场景

抽象类是「模板类」,既定义规范(抽象方法),也提供通用实现(普通方法),适用于:

场景 示例 核心原因
多个类有「共性逻辑+差异化逻辑」 定义 AbstractOrder 抽象类:包含通用的「计算金额」calcAmount()(普通方法),抽象的「生成订单号」generateOrderNo()(子类实现) 复用通用代码,差异化逻辑交给子类实现
定义模板方法 定义 AbstractExport 抽象类:export() 方法固定流程(校验→查询→导出),其中「查询」queryData() 为抽象方法,子类实现不同数据源查询 固定业务流程,只开放差异化步骤给子类
限制类的实例化 工具类/基础类不想被直接实例化(如 AbstractBaseService 抽象类不能 new,只能被继承,避免错误使用

2. 判断标准(满足其一就用抽象类)

  • 多个类有大量重复代码,想复用这些共性逻辑;
  • 你需要定义「流程模板」,固定核心步骤,只开放少量差异化步骤;
  • 想限制类的实例化,只允许子类扩展使用;
  • 既有「必须实现的方法」(抽象方法),也有「直接能用的方法」(普通方法)。

3. 示例代码

// 订单抽象类:复用通用逻辑,开放差异化逻辑
public abstract class AbstractOrder {
    // 通用逻辑:所有订单都需要计算金额(直接实现)
    public BigDecimal calcAmount(BigDecimal price, Integer count) {
        return price.multiply(new BigDecimal(count));
    }

    // 差异化逻辑:不同订单生成订单号的规则不同(抽象方法)
    public abstract String generateOrderNo();
}

// 普通订单实现
public class NormalOrder extends AbstractOrder {
    @Override
    public String generateOrderNo() {
        return "NORMAL_" + System.currentTimeMillis();
    }
}

// 秒杀订单实现
public class SeckillOrder extends AbstractOrder {
    @Override
    public String generateOrderNo() {
        return "SECKILL_" + System.currentTimeMillis();
    }
}

三、设计模式:解决「重复/复杂/易变」的业务场景

设计模式是「通用解决方案」,针对开发中反复出现的问题,核心是提高代码复用性、可扩展性、可读性,以下是高频设计模式的使用场景:

1. 高频设计模式 & 核心场景

设计模式 核心解决问题 典型使用场景
单例模式 保证一个类只有一个实例 工具类(如 ConfigUtil)、连接池(DataSource)、日志工厂
工厂模式(简单/工厂方法/抽象工厂) 封装对象创建逻辑,解耦「创建」和「使用」 支付方式创建(PayFactory.createPay("alipay"))、数据库连接创建
策略模式 封装不同算法/逻辑,可动态切换 不同促销规则(满减/折扣/立减)、不同排序算法(升序/降序/自定义)
适配器模式 兼容新旧接口/第三方接口 集成老系统接口(新接口适配老接口)、对接第三方SDK(统一调用规范)
观察者模式 一对多通知(一个对象变,多个对象感知) 订单状态变更(通知库存/物流/财务)、消息通知(用户下单后推送短信/邮件)
装饰器模式 动态给对象添加功能,替代继承 IO流(BufferedReader 装饰 FileReader)、订单金额装饰(基础金额+优惠券+运费)
模板方法模式 固定流程,开放差异化步骤 接口请求流程(校验→签名→处理→返回)、导出Excel(查询→组装→写入)
代理模式(静态/动态) 控制对象访问(增强逻辑) 日志记录、权限校验、事务管理(Spring AOP 底层)

2. 判断标准(什么时候用设计模式)

  • 代码出现重复逻辑(如多处创建支付对象 → 工厂模式);
  • 需求频繁变更(如促销规则经常加 → 策略模式);
  • 代码耦合度高(如直接 new 对象 → 工厂模式解耦);
  • 系统扩展性差(如新增支付方式要改大量代码 → 策略/工厂模式);
  • 团队协作需要统一规范(如所有人按模板方法写接口流程)。

3. 示例:策略模式(解决促销规则多变)

// 促销策略接口
public interface PromotionStrategy {
    BigDecimal calcDiscount(BigDecimal amount);
}

// 满减策略
public class FullReduceStrategy implements PromotionStrategy {
    @Override
    public BigDecimal calcDiscount(BigDecimal amount) {
        return amount.subtract(new BigDecimal("10")); // 满100减10
    }
}

// 折扣策略
public class DiscountStrategy implements PromotionStrategy {
    @Override
    public BigDecimal calcDiscount(BigDecimal amount) {
        return amount.multiply(new BigDecimal("0.9")); // 9折
    }
}

// 策略上下文(统一调用)
public class PromotionContext {
    private PromotionStrategy strategy;

    public PromotionContext(PromotionStrategy strategy) {
        this.strategy = strategy;
    }

    public BigDecimal getFinalAmount(BigDecimal amount) {
        return strategy.calcDiscount(amount);
    }
}

// 使用:动态切换策略
public class Test {
    public static void main(String[] args) {
        // 满减策略
        PromotionContext context1 = new PromotionContext(new FullReduceStrategy());
        System.out.println(context1.getFinalAmount(new BigDecimal("100"))); // 90

        // 折扣策略(新增策略无需改原有代码)
        PromotionContext context2 = new PromotionContext(new DiscountStrategy());
        System.out.println(context2.getFinalAmount(new BigDecimal("100"))); // 90
    }
}

四、核心对比(接口 vs 抽象类 vs 设计模式)

维度 接口 抽象类 设计模式
核心定位 定义能力/规范 复用代码/定义模板 解决通用问题/优化代码结构
关系 抽象类可实现接口,接口不能继承抽象类 子类继承抽象类,抽象类可实现接口 基于接口/抽象类实现(如策略模式依赖接口)
使用优先级 先定义接口,再考虑抽象类 有复用代码时用,无则用接口 基础结构(接口/抽象类)搭好后,用设计模式优化

总结

  1. 接口:定义「做什么」,解决「多实现、解耦」问题,是代码扩展的基础;
  2. 抽象类:定义「怎么做的通用部分」,解决「代码复用、模板流程」问题;
  3. 设计模式:基于接口/抽象类,解决「重复、易变、耦合」的业务问题,是进阶优化手段;
  4. 落地顺序:先通过接口定规范 → 抽象类复用代码 → 设计模式优化复杂场景。
posted on 2026-03-03 10:12  (Play)  阅读(1)  评论(0)    收藏  举报