合成复用原则为什么能替代继承复用原则
。合成复用原则(Composition over Inheritance)
是一种设计思想,强调通过对象组合(合成)来实现复用,而不是通过继承。它的核心思想是,创建灵活的对象,并通过组合而不是继承来增强功能,避免了继承层次过深和过于紧耦合的问题。尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。
继承复用(Inheritance Reuse)
是通过继承父类来复用父类的功能和行为。package principles.composition_Reuse.before;
public interface Flyable {
void fly();
}
package principles.composition_Reuse.before;
public interface Swmmable {
void swim();
}
package principles.composition_Reuse.before;
public class Fish {
public void swim(){
System.out.println("鱼在游");
}
}
package principles.composition_Reuse.before;
public class Bird implements Flyable{
@Override
public void fly() {
System.out.println("鸟在咻咻飞");
}
}
package principles.composition_Reuse.before;
public class Duck extends Bird implements Swmmable{
@Override
public void swim() {
System.out.println("鸭鸭在游泳");
}
//继承飞
@Override
public void fly() {
System.out.println("鸭鸭噗噗的飞啦");
super.fly();//调用鸟的飞法
}
}
package principles.composition_Reuse.before;
public class Main {
public static void main(String[] args) {
Duck duck = new Duck();
duck.fly();
duck.swim();
}
}
super.fly()
去调用s时能够展示继承并复用父类的行为。它能够让我们看到父类的实现仍然可以在子类中被调用,并且我们还能在重写方法里面对父类的行为进拓展,也就是说鸭鸭不仅可以噗噗的飞也可以像鸟一样咻咻的飞,如上运行结果所示那样。“白箱复用”
。例如,如果 Bird 类的 fly() 方法实现发生变化,Duck 类的行为也可能发生变化,这会给系统带来不必要的风险。合成复用原则(Composition)
:是指通过将现有类的功能组合在一起,而不是通过继承来实现复用。也就是说,类的功能并不直接通过继承而获得,而是通过将其他类的实例作为成员变量,将其方法委托给这些成员来实现复用。package principles.composition_Reuse.after;
public interface Flyable {
void fly();
}
package principles.composition_Reuse.after;
public interface Swimmable {
void swim();
}
package principles.composition_Reuse.after;
// 具体行为实现
class Bird implements Flyable {
public void fly() {
System.out.println("Bird is flying");
}
}
package principles.composition_Reuse.after;
class Fish implements Swimmable {
public void swim() {
System.out.println("Fish is swimming");
}
}
package principles.composition_Reuse.after;
// Duck 类表示一个鸭子,它实现了飞行和游泳的行为。
// 通过合成复用的方式,Duck 类将飞行和游泳的行为委托给 Bird 和 Fish 类。
class Duck implements Flyable, Swimmable {
private Flyable flyable; // 用于保存飞行行为
private Swimmable swimmable; // 用于保存游泳行为
// 构造器注入飞行和游泳的实现类
public Duck(Flyable flyable, Swimmable swimmable) {
this.flyable = flyable;
this.swimmable = swimmable;
}
// 实现 Flyable 接口的 fly 方法,委托给 flyable 的 fly 方法
// Duck 类不需要直接实现飞行的逻辑,只需要委托 Bird 类来执行飞行的具体操作。
@Override
public void fly() {
System.out.println("鸭鸭会飞其委托给了 ---> ");
flyable.fly(); // 委托飞行行为的实现
}
@Override
public void swim() {
System.out.println("鸭鸭会游其委托给了 ---> ");
swimmable.swim(); // 委托游泳行为的实现
}
}
package principles.composition_Reuse.after;
// 测试代码
public class Main {
public static void main(String[] args) {
// 创建飞行和游泳的实现对象
Flyable bird = new Bird(); // 让 Bird 实现飞行
Swimmable fish = new Fish(); // 让 Fish 实现游泳
// 创建 Duck 对象,将飞行和游泳行为组合
Duck duck = new Duck(bird, fish);
// 测试 duck 的行为
duck.fly(); // 输出: Bird is flying
duck.swim(); // 输出: Fish is swimming
}
}
Car
类有一个 Engine
类,这时 Car
类并不是 Engine
类的子类,而是包含了一个 Engine
实例。Duck
需要同时拥有飞行和游泳的行为。不同的行为可以分别来自 Bird
和 Fish
,这时可以通过合成复用来组合不同的行为实现。Dog
是 Animal
的一种,“狗是动物”这个关系表明 Dog
可以继承自 Animal
。Car
类和 Truck
类都可以继承自 Vehicle
类,复用 Vehicle
类中通用的功能。