跳到内容

元数据卡

  • 前置知识:第8章全章(继承、多态、重写、抽象类、接口)
  • 预计时间:25 分钟
  • 阅读模式:动手实操
  • 完成标志:通过全部热身题,至少完成一个挑战题

你的进度

老陈师傅的铁匠铺里,你已经学完了继承、多态、@Override、抽象类和接口。工具箱里有了这些新工具,现在该动手了。

"光看不练,等于没学。"老陈递给你一块新铁胚:"把这几个练习做了,我才让你碰下一章。"


热身(10 分钟,必做)

1. Animal 继承与多态

创建一个 Animal 抽象类,包含 abstract void makeSound() 方法。创建 DogCat 继承它。最后写一个 Zoo 类,接收 Animal 参数并调用 makeSound()

java
// 参考框架
abstract class Animal {
    public abstract void makeSound();
}

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("汪!汪!");
    }
}

class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("喵~");
    }
}

class Zoo {
    public void letAnimalSpeak(Animal animal) {
        animal.makeSound(); // 多态!
    }
}

语言:Java 17+ 操作方法:复制到 IDE 中,在 main() 方法里创建 DogCat 传入 Zoo

2. 重写 toString()

在你自己的类上重写 toString() 方法,让打印输出类名和关键字段:

java
@Override
public String toString() {
    return "Dog{name='" + name + "', age=" + age + "}";
}

3. 试试 final

AnimalmakeSound() 加上 final 关键字——看看子类还能重写它吗?

java
abstract class Animal {
    public final void makeSound() { ... } // 子类无法重写
}

挑战(15 分钟,选做)

1. 设计一个支付系统

创建一个 Payable 接口,包含 void pay(double amount) 方法。然后创建 CreditCardAlipayWeChat 三个类实现它。最后写一个 ShoppingCart 类接收 Payable 参数——让支付方式可插拔:

java
interface Payable {
    void pay(double amount);
}

class CreditCard implements Payable {
    @Override
    public void pay(double amount) {
        System.out.println("信用卡支付: " + amount + "元");
    }
}

class ShoppingCart {
    public void checkout(Payable paymentMethod, double amount) {
        paymentMethod.pay(amount); // 多态!
    }
}

2. 实例判断练习

写一个方法,接收 Object 参数,用 instanceof 判断它的实际类型并打印不同信息。然后用模式匹配 instanceof(Java 16+)重写。


验收标准

  • 能解释 extendsimplements 的区别:一个继承实现,一个遵守契约
  • 能说出 super 的两种用途:调用父类构造器、调用被重写的父类方法
  • 知道为什么多态能写出"可扩展"的代码——新的子类不需要改动调用方
  • 能说清抽象类和接口的核心区别
  • 知道 Object 是所有类的根类

常见卡点

"我应该在什么时候用抽象类,什么时候用接口?" 经验法则:如果两个类共享状态(字段)和部分实现 → 抽象类。如果只是定义能力契约 → 接口。

"final 关键字在继承中怎么用?" 三处:final class 不能被继承(如 String);final 方法不能被子类重写;final 变量只能赋值一次。

"为什么说继承破坏了封装?" 子类依赖父类的内部实现。父类修改了一个 protected 字段的名字或含义,子类可能就炸了。所以设计继承体系时要精心选择 protected 暴露的接口——或者干脆用组合。


旅人笔记

继承消除重复,多态让调用方不依赖具体类型。 抽象类说"我有骨架,你来填",接口说"我只要你遵守契约"。 所有类都是 Object 的孩子。

下一站预告

完成了继承和多态的全套练习,你已经能设计灵活的类体系了。但下一站你会遇到一个新问题:每次需要不同行为就创建一个新类,太重了。能不能把行为本身当成参数传递?答案在 Lambda 和高阶函数。

Built with VitePress | Software Systems Atlas