黑神话悟空之抽象类与接口详解

🎮 第一幕:西游世界的代码启示录

1. 基础概念重铸

// 抽象类:妖怪的本质(是什么)
abstract class Demon {
    // 不需要重写的方法
    void appear() {
        System.out.println("妖气冲天!");
    }
    
    // 必须实现的抽象方法
    abstract void uniqueSkill();
}

// 接口:妖怪的能力(能做什么)
interface FlameMagic {
    default void fireAttack() { // 可不重写
        System.out.println("释放三昧真火");
    }
}

// 大Boss现身!
class RedBoy extends Demon implements FlameMagic {
    @Override
    void uniqueSkill() {
        System.out.println("召唤火尖枪阵列");
    }
    
    // 重写默认方法
    @Override
    public void fireAttack() {
        System.out.println("🔥 八荒焚天诀!");
    }
}

2. 黄金三问解析

  • Q1:为什么模板模式可以不用final?

    • 技术真相:不用final时子类仍可重写父类方法,但会破坏模板结构(比如黑熊精突然改变战斗流程)
    • 最佳实践:应该用final保护模板流程:
      abstract class BattlePhase {
          // 锁定战斗流程
          public final void execute() {
              prepare();
              attack();
              escape();
          }
          
          protected abstract void prepare();
          protected abstract void attack();
          protected void escape() { // 钩子方法
              System.out.println("土遁逃脱");
          }
      }
  • Q2:"是什么" vs "能做什么"如何区分?

    • 抽象类案例SpiritMacaque(灵明石猴)定义猴类本质属性
    • 接口案例七十二变法天象地作为可装配能力
    • 组合威力
      class SunWukong extends SpiritMacaque 
          implements 七十二变, 法天象地, 金刚不坏 {
          // 既是石猴(本质),又有各种神通(能力)
      }

⚔️ 第二幕:黑神话战斗系统架构实战

1. 模板模式深度应用

abstract class BossBattle {
    // 最终决战流程(不可修改)
    public final void battleProcess() {
        phase1(); 
        phase2();
        enragePhase();
    }

    // 第一阶段通用逻辑
    private void phase1() {
        System.out.println("召唤小妖助阵");
        meleeAttack();
    }

    // 抽象方法:各Boss不同表现
    protected abstract void meleeAttack();
    protected abstract void phase2();
    
    // 狂暴阶段(可选重写)
    protected void enragePhase() {
        System.out.println("进入狂暴状态!");
    }
}

// 黄风怪实现
class YellowWindDemonBattle extends BossBattle {
    protected void meleeAttack() {
        System.out.println("三股叉连续突刺");
    }

    protected void phase2() {
        System.out.println("召唤沙尘暴领域");
    }

    @Override
    protected void enragePhase() {
        System.out.println("黄风大葬!天地变色");
    }
}

2. 接口的灵活装配

// 法宝能力接口
interface MagicTreasure {
    default void activate() {
        System.out.println("法宝基础效果触发");
    }
}

// 具体法宝实现
class GoldenHoops implements MagicTreasure {
    @Override
    public void activate() {
        System.out.println("金箍棒变大横扫千军!");
    }
}

class WindFireWheel implements MagicTreasure {
    // 不重写则使用默认效果
}

// 战斗中使用
class BattleSystem {
    void useTreasure(MagicTreasure treasure) {
        treasure.activate(); // 多态生效
    }
}

// 实战演示:
BattleSystem system = new BattleSystem();
system.useTreasure(new GoldenHoops()); // 金箍棒特效
system.useTreasure(new WindFireWheel());// 默认法宝效果

🔮 第三幕:进阶设计哲学

1. 模板模式的三大铁律

  • 流程固化:把确定的流程钉死在模板方法里(就像黑神话的BOSS战阶段)
  • 弹性扩展:通过钩子方法(Hook Method)允许选择性重写
  • 好莱坞原则:"不要调用我们,我们会调用你"——子类只需填空,不用管流程

2. 接口的现代进化

interface CombatStyle {
    // 默认方法实现连招模板
    default void comboAttack() {
        lightAttack();
        heavyAttack();
        specialMove();
    }

    private void lightAttack() {
        System.out.println("轻攻击");
    }

    abstract void heavyAttack();
    abstract void specialMove();
}

// 实现示例
class SpearStyle implements CombatStyle {
    public void heavyAttack() {
        System.out.println("长枪突刺");
    }

    public void specialMove() {
        System.out.println("游龙掷月枪");
    }
}

// 使用时:
CombatStyle style = new SpearStyle();
style.comboAttack(); // 轻攻→突刺→必杀技

3. 终极对比表

特性抽象类接口
设计定位本质继承(是什么)能力装配(能做什么)
模板模式适用度★★★★★★★☆ (通过默认方法有限支持)
多态方向自上而下自下而上
代码复用共享父类代码通过默认方法共享
黑神话应用案例BOSS战流程模板法宝/神通系统


口语化解释一下接口和抽象类多态的区别,抽象类是用于是什么的场景,接口是用于能做什么的场景。感觉更好区分的是,抽象类中间可用模板模式,进行方法的链式制定。 (个人观点,请多指正)

补充:

🟢 抽象类的正确打开方式(模板方法示例):

abstract class Beverage {
    // 模板方法:控制制作流程
    public final void prepare() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    // 公共实现
    private void boilWater() { 
        System.out.println("煮沸100℃水");
    }

    // 抽象方法
    protected abstract void brew();
    protected abstract void addCondiments();
}

class Coffee extends Beverage {
    @Override
    protected void brew() {
        System.out.println("冲泡咖啡粉");
    }

    @Override
    protected void addCondiments() {
        System.out.println("加奶加糖");
    }
}

🔵 接口的正确打开方式(策略模式示例):

interface Flyable {
    void fly(); // 能力契约
}

interface Quackable {
    void quack();
}

class RocketDuck extends Duck implements Flyable, Quackable {
    public void fly() {
        System.out.println("喷气式飞行");
    }

    public void quack() {
        System.out.println("电子音鸣叫");
    }
}

💡 关键区分点表格:

特性抽象类接口
设计目的代码复用 + 多态扩展行为契约 + 能力组合
模板方法适用性✅ 天然支持❌ 无法定义方法实现
多态维度纵向继承(是什么)横向扩展(能做什么)
成员类型可含字段/具体方法仅抽象方法/默认方法
设计模式模板方法、工厂方法策略、装饰器、适配器

🔍 为什么模板方法必须用抽象类:

  1. 需要固化流程(final方法控制步骤顺序)
  2. 需要共享公共代码(如boilWater方法)
  3. 需要定义抽象方法的调用结构

🚫 接口无法实现模板方法的情况:

interface Template { // 反模式示例
    default void process() {
        step1(); // 错误!接口默认方法不能调用未实现的抽象方法
        step2();
    }
    
    void step1();
    void step2();
}

✅ 但Java8+的接口可以通过默认方法实现简单流程(有限制):

interface Loggable {
    default void logProcess() {
        String msg = formatMessage(); // 调用抽象方法
        saveToFile(msg);
    }

    String formatMessage(); // 仍需实现
    
    private void saveToFile(String msg) {
        // 公共日志保存逻辑
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值