从具体派生class?

Deriving from a concrete class?

在书'Head First Design Patterns'中,提到不违反'Dependency Inversion'原则的方法之一是:

No class derive from a concrete class.

是否可以彻底遵守这条规则?在许多常用的框架和库中,通常会发现 类 不遵循此规则。

继承是c#的重要组成部分,排除它是一种浪费。

不过,这本书强调open for extension closed for change SOLID原则,这其实是一件好事。

不从具体派生 类(注意,抽象 类 和接口不是具体的),帮助您适应这种范式。继承通常不适合扩展,并且使反转更难(因为后者依赖于接口而具体不是接口)。

所以在实践中,您会发现基数 类 通常是 abstract。不是全部,也不是每个框架都采用它。有时有充分的理由从具体继承。但这本书在某种程度上是一种易于阅读的方式,并且详细介绍例外情况会使它更难阅读。

所以底线:不,不应该不惜一切代价遵循规则,只有在以下情况之一时才进行具体继承:

  • 你知道自己在做什么(所以你有一个非常非常非常好的理由)
  • 你知道这没关系(因为它很简单project/object)
  • 你知道具体内容将包含在项目本身(内部)

由于编程中的问题千差万别,很难说。有时你这样做很有用,有时则不然。

也可以重新设计您认为无法实际实现的情况。但在新设计中,您最终可能会得到更多 class 您并不真正需要且仅用于实现此目的的元素。

这种情况下的问题是:有更多的东西只是为了实现一些原则而不在代码中出现问题是好的设计吗?

根据我的经验,最好尝试避免继承具体的 classes。尝试设计你的代码,这样你就不会继承具体的 classes。这将使您的代码更好地阅读和理解,因为它会指导您更好地设计抽象。但有时这样做很有用。

正如您提到的框架那样。尤其是 GUI 框架。你在那里看到了很多来自具体 classes 的继承。这是因为向现有控件添加额外的行为很有用。

例如 Button 本身就很好,但有时您可能需要根据需要添加其他行为。继承自 Button 并添加您需要的新东西就可以了。你能换一种方式吗?当然可以,但是为了避免从具体的 class 继承,是否值得添加额外的 classes and/or 接口或来自 Button 的应对代码?有那么糟糕吗?它可以去哪里?

您确实以这种方式实现了可扩展性,因为框架仍然可以正常工作。

GUI 框架也使用组合 a-lot,因此您得到的是组合与从具体和抽象 class 继承的组合。只用在你需要的地方。

并非所有问题都像具有 a-lot 相关对象的层次结构那样。有时继承会损害可扩展性,使用组合是更好的选择。