
本文讲解如何通过职责分离与合理类设计(如引入 exhibit 展区类),解决子类(monkey)创建的实例无法被父类(zoo)安全访问的问题,避免静态滥用和数组 null 异常,构建可维护的动物园 oop 架构。
本文讲解如何通过职责分离与合理类设计(如引入 exhibit 展区类),解决子类(monkey)创建的实例无法被父类(zoo)安全访问的问题,避免静态滥用和数组 null 异常,构建可维护的动物园 oop 架构。
在面向对象设计中,“让 Monkey 类自己批量创建猴子并试图被 Zoo 调用”是一种典型的职责错位。Monkey 是一个实体类(Entity Class),应仅封装单只猴子的属性(如 name、species、age)和行为(如 makeSound());它不负责“批量生成”或“全局注册”。同样,Animals 作为抽象父类,应定义共性字段(name, type, age)和抽象方法(getInfo()),而非承担容器逻辑。
真正缺失的是容器类(Container Class)——即 Exhibit(展区)。它专用于聚合同类型动物,并提供统一的增删查接口。这样既符合单一职责原则(SRP),又自然解决了跨类数据访问问题:
// 动物基类:定义共性
abstract class Animal {
protected String name, type, species, color;
protected int age;
public Animal(String name, String type, String species, String color, int age) {
this.name = name; this.type = type; this.species = species;
this.color = color; this.age = age;
}
public abstract String getInfo();
}
// 具体动物类:专注个体特征
class Monkey extends Animal {
public Monkey(String name, String type, String species, String color, int age) {
super(name, type, species, color, age);
}
@Override
public String getInfo() {
return String.format("Monkey: %s, %s, %s, %d years old", name, species, color, age);
}
}
// 展区类:唯一负责管理一组动物
class Exhibit<T extends Animal> {
private final List<T> animals = new ArrayList<>();
public void add(T animal) { animals.add(animal); }
public List<T> getAll() { return new ArrayList<>(animals); } // 防止外部修改
public void displayAll() {
animals.forEach(animal -> System.out.println(animal.getInfo()));
}
}
// 动物园:持有多个展区,协调整体逻辑
class Zoo {
private final Exhibit<Monkey> monkeyExhibit = new Exhibit<>();
public void setupMonkeyExhibit() {
monkeyExhibit.add(new Monkey("Baby", "Monkey", "Baboon", "Brown", 8));
monkeyExhibit.add(new Monkey("Poppy", "Monkey", "Baboon", "Brown", 6));
monkeyExhibit.add(new Monkey("Dad", "Monkey", "Baboon", "White", 9));
monkeyExhibit.add(new Monkey("Mom", "Monkey", "Baboon", "White", 9));
monkeyExhibit.add(new Monkey("Sister", "Monkey", "Baboon", "Black", 7));
}
public void showMonkeys() {
System.out.println("=== Monkey Enclosure ===");
monkeyExhibit.displayAll();
}
public static void main(String[] args) {
Zoo zoo = new Zoo();
zoo.setupMonkeyExhibit();
zoo.showMonkeys();
}
}✅ 关键设计要点总结:
- 禁止在 Monkey 或 Animal 中定义 monkeyAddition() 或数组字段:这会导致状态分散、难以测试、违反封装。
- Exhibit 是桥梁:它解耦了“动物定义”与“动物集合”,Zoo 通过 Exhibit 实例间接访问所有猴子,无需直接操作 Monkey 内部。
- 避免 static 数组陷阱:原问题中数组为 null,往往因静态字段未初始化或作用域混乱所致;使用实例化 Exhibit 可彻底规避。
- 扩展友好:新增 LionExhibit 或 BirdExhibit 只需继承 Exhibit<Lion>,无需修改 Zoo 核心逻辑。
这种分层结构让代码更易理解、调试和演进——Zoo 管理“什么有”,Exhibit 管理“有多少”,Animal 管理“是什么”。这才是 OOP 的本质:用对象协作代替过程式堆砌。


















