“组合优于继承”是一个面向对象编程的设计原则,它建议我们在需要复用代码的时候,尽量使用组合(has-a)的方式,而不是继承(is-a)的方式。组合是指一个类包含另一个类的对象作为自己的属性,而继承是指一个类直接从另一个类派生出来,拥有其所有的属性和方法。
为什么要使用组合而不是继承呢?主要有以下几个原因:
- 组合可以提高类的封装性和灵活性。通过组合,一个类可以动态地改变自己的行为,只需要改变包含的对象的引用即可。而继承则是静态的,一旦确定了父类和子类的关系,就无法在运行时改变。而且,通过组合,一个类可以复用多个类的代码,而继承则只能单根继承,不能同时从多个父类派生。
- 组合可以避免类之间的耦合和污染。通过继承,子类会暴露父类的内部实现细节,如果父类发生了变化,子类也必须跟着改变。而且,子类会无条件地继承父类所有的属性和方法,即使有些并不适用于子类。这样会造成子类的臃肿和混乱。通过组合,一个类只需要关心自己包含的对象提供了哪些接口,而不需要知道其内部实现。而且,一个类可以选择性地使用包含对象的属性和方法,不会被强制继承不需要的东西。
下面我给你举一个简单的例子来说明组合和继承的区别。假设我们要设计一个汽车(Car)类和一个发动机(Engine)类。如果我们使用继承的方式,那么我们可以让汽车类继承发动机类,这样汽车就拥有了发动机的属性和方法。但是这样做有几个问题:
- 首先,这样违反了“is-a”的逻辑关系。汽车并不是一种发动机,它们之间没有本质上的层次结构。
- 其次,这样导致了汽车和发动机之间的紧密耦合。如果发动机类发生了变化,比如增加了一个新的属性或方法,那么汽车类也必须跟着改变。这样会增加代码的复杂度和维护成本。
- 再次,这样限制了汽车和发动机之间的灵活性。如果我们想让汽车换一个不同类型或品牌的发动机,那么我们就必须重新定义一个新的汽车子类来继承那个发动机类。这样会导致代码冗余和浪费。
使用C#语言来表示就是这样:
// 使用继承的方式
public class Engine
{
public string Type { get; set; }
public int HorsePower { get; set; }
public void Start()
{
// Start the engine
}
public void Stop()
{
// Stop the engine
}
}
public class Car : Engine // Car is not an engine!
{
public string Model { get; set; }
public string Color { get; set; }
public void Drive()
{
// Drive the car
}
}
// 如果想换一个不同的发动机,就要定义一个新的子类
public class CarWithElectricEngine : ElectricEngine // Car is not an electric engine!
{
public string Model { get; set; }
public string Color { get; set; }
public void Drive()
{
// Drive the car
}
}
如果我们使用组合的方式,那么我们可以让汽车类包含一个发动机类的对象作为自己的属性,这样汽车就可以使用发动机的属性和方法。这样做有几个好处:
- 首先,这样符合了“has-a”的逻辑关系。汽车有一个发动机,它们之间是一种组合关系。
- 其次,这样降低了汽车和发动机之间的耦合。如果发动机类发生了变化,那么汽车类不需要跟着改变。只要发动机类提供了相同的接口,汽车类就可以正常工作。
- 再次,这样提高了汽车和发动机之间的灵活性。如果我们想让汽车换一个不同类型或品牌的发动机,那么我们只需要改变汽车类中包含的发动机对象的引用即可。这样可以实现运行时的动态变化。
使用C#语言来表示就是这样:
// 使用组合的方式
public class Engine
{
public string Type { get; set; }
public int HorsePower { get; set; }
public void Start()
{
// Start the engine
}
public void Stop()
{
// Stop the engine
}
}
public class Car
{
public string Model { get; set; }
public string Color { get; set; }
public Engine Engine { get; set; } // Car has an engine
public void Drive()
{
// Drive the car
Engine.Start(); // Use the engine's method
}
}
// 如果想换一个不同的发动机,只要改变引用即可
public class Example
{
public static void Main()
{
Car car = new Car();
car.Model = "Toyota";
car.Color = "Red";
car.Engine = new Engine(); // Use a normal engine
car.Engine.Type = "Gasoline";
car.Engine.HorsePower = 200;
car.Drive(); // Drive the car with a normal engine
car.Engine = new ElectricEngine(); // Use an electric engine
car.Engine.Type = "Electric";
car.Engine.HorsePower = 150;
car.Drive(); // Drive the car with an electric engine
}
}
标签:Engine,engine,优先,set,组合,get,继承,car,public
From: https://www.cnblogs.com/netlog/p/17472987.html