如何考虑接口和抽象类来改进程序设计?

时间:2019-04-02 08:36:16

标签: c# oop abstract-class abstraction

考虑到已接受的答案here,一般建议的想法是,在可能的情况下,建议优先于接口定义类。

请考虑以下设计:

  1. 基类ChessPiece,其中还定义了多个子类
  2. 某些类型的作品如果已经移动(即PawnRookKing)需要记录:bool HasMoved属性
  3. 一种棋子,King无法捕获;其他一切都可以是:bool IsCaptured属性

问题是#2和3之间的冲突(如果我仅实现这两个中的一个就没有问题),因为派生类King在#2和3中很常见。

理想情况下,应该都继承自CapturablePiece的两个抽象类MoveRecordedPieceChessPiece。但是C#不允许多类继承,而这正是接口的所在。

如果实现了接口,那么现在所有具体的子类都可以手动实现每个必需的属性。然后考虑以下示例:

// needed type-check
ChessPiece piece;
// some calculations...
if (piece is ICapturablePiece)    // or using the 'as' keyword
//or...
if (piece is IMoveRecordedPiece)
// which in the case of non-conflicting abstract classes,
// this is easily doable and valid because of
// inheritance to the base class

我不能这样做,因为接口是原样的。它不能继承任何东西,它只是必须实现的方法的独立标记。

仍然最好使用抽象类版本-CapturablePieceMoveRecordedPiece,因为其基本类型为ChessPiece,并且我确定此逻辑是“ is -an ”,而不是“ 可以做”(如上面的链接所述)。

我现在的问题是,我将如何改进设计,请考虑:

  1. 您不能继承多个类,而接口也不能继承任何东西。
  2. 抽象类胜于接口
  3. 需要类型检查的代码块

编辑:

这不是链接问题的重复项。在考虑接口和抽象类的同时,这更多是如何改进设计的

1 个答案:

答案 0 :(得分:0)

彼此独立地定义行为,并通过必需的实例将其聚合。 您的问题不是继承,而是在一堂课中承担太多责任。国王的动作与典当的动作不同。因此,独立定义这些类型的行为并将其添加到国际象棋人物类中。类似运动。从外部实现该行为,并将其传递给需要它的类。

这使您可以很好地解耦代码。