继承或组合:什么时候应该选择哪个?
在软件设计中,继承(Inheritance)和组合(Composition)是两种常见的代码复用和结构化方式。选择继承还是组合取决于具体的需求、设计原则以及代码的可维护性和扩展性。
继承是一种**“is-a”**(是一个)的关系,子类继承父类的属性和行为。
明确的分类层次结构:
public class Animal {
public void eat() {
System.out.println("This animal eats food.");
}
}
public class Cat extends Animal {
public void meow() {
System.out.println("Meow!");
}
}
需要复用父类的行为:
多态的需要:
组合是一种**“has-a”**(拥有一个)的关系,对象通过包含其他对象来实现行为。
动态行为扩展:
public class Engine {
public void start() {
System.out.println("Engine starts.");
}
}
public class Car {
private Engine engine;
public Car(Engine engine) {
this.engine = engine;
}
public void drive() {
engine.start();
System.out.println("Car is driving.");
}
}
避免继承滥用:
需要灵活的模块化设计:
| 特性 | 继承 | 组合 |
|---|---|---|
| 关系类型 | “is-a”(是一个) | “has-a”(拥有一个) |
| 代码复用 | 子类复用父类的行为 | 通过包含其他对象实现复用 |
| 灵活性 | 静态,继承关系在编译时确定 | 动态,可以在运行时调整组合关系 |
| 耦合性 | 耦合度高,子类依赖父类 | 耦合度低,对象之间关系较松散 |
| 适用场景 | 明确的层次结构,行为统一 | 灵活的行为组合,模块化设计 |
| 修改影响 | 父类修改可能影响所有子类 | 修改一个组件通常不会影响其他组件 |
Square 继承自 Rectangle,但 Square 的行为与 Rectangle 不一致(如宽高相等),这违反了 LSP。
public class Bird {
public void fly() {
System.out.println("Flying...");
}
}
public class Sparrow extends Bird {
public void chirp() {
System.out.println("Chirp chirp!");
}
}
public class FlyBehavior {
public void fly() {
System.out.println("Flying...");
}
}
public class Sparrow {
private FlyBehavior flyBehavior = new FlyBehavior();
public void chirp() {
System.out.println("Chirp chirp!");
}
public void performFly() {
flyBehavior.fly();
}
}
2025 年陆剧市场依旧热度爆棚
时间:2025-09-19
阵地央一首播:年度高品质大剧,深度解锁文化抗战三重非凡意义
时间:2025-09-18
陈展鹏刘佩玥《巨塔之后》今首播
时间:2025-08-28
生万物大结局惊现最招恨角色,原来真正的坏都披着善的“羊皮”!
时间:2025-08-28
归队6集燃爆:袁姗姗化身“战地玫瑰”,实战军医双在线超吸睛!
时间:2025-08-28
许凯田曦薇新剧《子夜归》首播,点击率位列第七
时间:2025-08-21