在 Java 中,**组合(Composition)和继承(Inheritance)**都是实现代码复用的重要手段,但它们的设计思想、使用方式和适用场景有明显区别。
继承是 “is-a” 关系,表示子类是父类的一种。
class Animal {
void eat() {}
}
class Dog extends Animal {
void bark() {}
}
✅ Dog is an Animal
组合是 “has-a” 关系,表示类中包含另一个类的对象。
class Engine {
void run() {}
}
class Car {
private Engine engine = new Engine();
void start() {
engine.run();
}
}
✅ Car has an Engine
| 对比点 | 继承 | 组合 |
|---|---|---|
| 关系 | is-a | has-a |
| 耦合度 | 高(父类改变影响子类) | 低(修改内部实现不影响外部) |
| 灵活性 | 编译期确定 | 运行期可动态替换 |
| 代码复用方式 | 通过扩展父类 | 通过调用成员对象 |
| 多态支持 | 天然支持 | 需借助接口 |
| 破坏封装风险 | 容易(访问 protected) | 更小 |
| 适合场景 | 明确的层级关系 | 功能组装、解耦 |
class A {
void method() {}
}
class B extends A {
void method() {
super.method();
}
}
如果 A 改了实现,B 可能直接出问题。
class Logger {
void log() {}
}
class Service {
private Logger logger = new Logger();
}
class Service {
private Logger logger;
Service(Logger logger) {
this.logger = logger;
}
}
可以使用:
“优先使用组合,而不是继承”
——《Effective Java》
原因:
✅ 适合使用继承的情况:
abstract class BaseService {
void execute() {
before();
doWork();
after();
}
abstract void doWork();
}
如果你愿意,我也可以给你一个真实业务场景对比示例(比如订单系统、支付系统)。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。