提问人:bokabokaboka 提问时间:10/20/2023 最后编辑:bokabokaboka 更新时间:11/7/2023 访问量:95
为什么软件开发中的开放/封闭原则是使用抽象类实现的?
Why is the Open/Closed Principle in software development implemented using abstract classes?
问:
OCR码
using System;
namespace Example027 {
class Program {
static void Main(stringll args) {
Vehicle v = new Truck();
v.Run()
}
}
abstract class Vehicle {
public void Stop() {
Console.WriteLinel'Stopped!");
}
public void Fill() {
Console.WriteLinel' Pay and fill...");
}
public abstract void Run();
}
class Car : Vehicle {
public override void Run() {
Console.WriteLinel('Car is running ...");
}
}
class Truck : Vehicle {
请查看上面的代码。老师告诉我们,抽象类可以作为在软件开发中实现开放/封闭原则的工具。
上面的代码作为示例来说明这一点。老师说,所有车辆的常用方法,如停止和填充,都封装在车辆类中。这些方法的不同实现是通过重写在 Car 和 Truck 类中实现的。我理解这种方法,但我认为没有必要使用抽象类。我们可以在常规课程中实现同样的目标,对吧?
将 Vehicle 设置为常规类,并在其中仅实现 Stop 和 Fill 方法。然后,让 Car 和 Truck 继承自 Vehicle 并实现它们各自的 Run 方法。在程序开始时,使用
Var v = new Truck()
或
Truck v = new Truck()
并且仍然能够使用
v.Run()
我不明白使用抽象类的必要性?
答:
你是对的。没有必要使用抽象类来实现此行为。但是,使用常规类,您将能够实例化 ,这取决于您的目标,而不是您想要允许的。声明一个类的要点是确保该类被用于其目的,即在本例中被继承。Vehicle
abstract
评论
你认为一个常规类可以用来说明开放/封闭原则是正确的。
然而,抽象类更适合说明这一原则,因为从本质上讲,它们被设计为扩展,即“开放”扩展。
相比之下,常规类可以设置为“最终”(JAVA)或“密封”(C#),事实上,与客户端(使用您的类的代码)清楚地传达您提供的构造是开放的还是关闭的扩展被认为是好的编程。
你的想法的一个问题是它缺乏抽象。你不能写一个像这样的方法
public static void FillAndRun(Vehicle vehicle){
vehicle.Fill(); // Fine
vehicle.Run(); // Not fine, No such method on Vehicle
}
你可以创建一个虚拟的运行方法。但是,你有一个问题,基类应该如何实现它。抽象类提供了一个公共接口,并强制每个派生类实现自己的 run-method。
但是,将代码划分为可重用的组件是很困难的,抽象类可能不是最好的方法。
抽象类的一个问题是它混合了两个相关但不同的概念。接口继承和实现继承。
接口继承用于为类的用户提供公共接口,通常使用接口完成。这很常见,如果使用得当,完全没问题。
实现继承是为了重用实现,这更成问题。你只能从一个类继承,所以如果你想重用来自多个类的实现,你就不走运了。还有脆弱的基类问题和许多其他潜在问题。因此,通常建议首选“组合而不是继承”,即将通用实现移动到其他类或静态方法进行重用。
对于新开发人员来说,过度使用继承也很常见,这通常会导致“泄漏抽象”。因此,对于新开发人员,我建议不要太担心开放/关闭、抽象、接口等。这是一个非常困难的话题,即使是有经验的开发人员也很难解决。
评论