我希望能对如何正确实现“组合优于继承”进行一些澄清。我认为我已经掌握了理论,但在实践中我很难理解它如何不会导致代码重复。
我有以下示例(它是 Java):假设我们有一个抽象动物类:
abstract class Animal {
protected void eat() {
// Common eating implementation
}
protected void sleep() {
// Common sleeping implementation
}
}
我们想要建造飞行和游泳的动物。我知道,遵循 LSP 的最佳方法是为每个接口提供接口:
interface Flyer {
void fly();
}
interface Swimmer {
void swim();
}
那么我们就会有
class Salmon extends Animal implements Swimmer {
@Override
public void swim() {
// Swim implementation
}
}
class Sparrow extends Animal implements Flyer {
@Override
public void fly() {
// Fly implementation
}
}
但随后我们得到了一个新的要求,即Magpie
它的飞行方式与麻雀相同。我们将创建一个类,与 a 没有太大不同Sparrow
:
class Magpie extends Animal implements Flyer {
@Override
public void fly() {
// Same exact fly implementation as Sparrow.fly
}
}
出于本练习的目的,想象一下,苍蝇的实现非常复杂,包括数据库集成、日志记录等。这会导致大量重复的代码,如果我们添加更多的鸟或鱼,我们甚至需要重复代码更远。
还有一个想法是为相同类型的传单创建一个抽象类,例如
abstract class FlyingBird extends Animal implements Flyer
并在那里有通用的实现,但是如果我们需要创建其中一些并且有一只动物需要扩展其中两个怎么办?这是一个滑坡...
有什么办法可以避免这种情况吗?或者我在某个地方遗漏了标记?