元数据卡
- 前置知识:第8章全章(继承、多态、重写、抽象类、接口)
- 预计时间:25 分钟
- 阅读模式:动手实操
- 完成标志:通过全部热身题,至少完成一个挑战题
你的进度
老陈师傅的铁匠铺里,你已经学完了继承、多态、@Override、抽象类和接口。工具箱里有了这些新工具,现在该动手了。
"光看不练,等于没学。"老陈递给你一块新铁胚:"把这几个练习做了,我才让你碰下一章。"
热身(10 分钟,必做)
1. Animal 继承与多态
创建一个 Animal 抽象类,包含 abstract void makeSound() 方法。创建 Dog 和 Cat 继承它。最后写一个 Zoo 类,接收 Animal 参数并调用 makeSound():
// 参考框架
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() 方法里创建 Dog 和 Cat 传入 Zoo
2. 重写 toString()
在你自己的类上重写 toString() 方法,让打印输出类名和关键字段:
@Override
public String toString() {
return "Dog{name='" + name + "', age=" + age + "}";
}3. 试试 final
把 Animal 的 makeSound() 加上 final 关键字——看看子类还能重写它吗?
abstract class Animal {
public final void makeSound() { ... } // 子类无法重写
}挑战(15 分钟,选做)
1. 设计一个支付系统
创建一个 Payable 接口,包含 void pay(double amount) 方法。然后创建 CreditCard、Alipay、WeChat 三个类实现它。最后写一个 ShoppingCart 类接收 Payable 参数——让支付方式可插拔:
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+)重写。
验收标准
- 能解释
extends和implements的区别:一个继承实现,一个遵守契约 - 能说出
super的两种用途:调用父类构造器、调用被重写的父类方法 - 知道为什么多态能写出"可扩展"的代码——新的子类不需要改动调用方
- 能说清抽象类和接口的核心区别
- 知道
Object是所有类的根类
常见卡点
"我应该在什么时候用抽象类,什么时候用接口?" 经验法则:如果两个类共享状态(字段)和部分实现 → 抽象类。如果只是定义能力契约 → 接口。
"final 关键字在继承中怎么用?" 三处:final class 不能被继承(如 String);final 方法不能被子类重写;final 变量只能赋值一次。
"为什么说继承破坏了封装?" 子类依赖父类的内部实现。父类修改了一个 protected 字段的名字或含义,子类可能就炸了。所以设计继承体系时要精心选择 protected 暴露的接口——或者干脆用组合。
旅人笔记
继承消除重复,多态让调用方不依赖具体类型。 抽象类说"我有骨架,你来填",接口说"我只要你遵守契约"。 所有类都是 Object 的孩子。
→ 下一站预告
完成了继承和多态的全套练习,你已经能设计灵活的类体系了。但下一站你会遇到一个新问题:每次需要不同行为就创建一个新类,太重了。能不能把行为本身当成参数传递?答案在 Lambda 和高阶函数。