使用未使用的继承成员打破多态与子类

时间:2009-10-31 04:02:18

标签: inheritance polymorphism

如果我使用继承,后来意识到单个子类需要一个不可用的方法或字段,我应该在基类中声明它而不是在其他子类中实现它,或者我应该在其中声明它单个子类?

如果我选择在子类中声明方法,那么我就不能再以多态方式处理所有内容。另一方面,如果我选择将它放在基类中,那么我最终会得到许多不实现属性或方法的子类。我已经在.net框架中看到了选择“未实现”方法的示例。什么是最好的方式?

6 个答案:

答案 0 :(得分:1)

如果只有一个子类有方法X,那么根据定义你当然不能多态地调用X. X存在于超类中是否合理(因此无处不在)但在大多数情况下都是无操作的?有时它是,有时你只需要重新考虑你的整个类层次结构,即为什么你想多态地调用X,即使它可能不存在(或者最好是无操作)?如果不了解更多,更多更多关于您的具体用例,则无法做出回应!

答案 1 :(得分:1)

除非每个可能的派生类都有适当的实现,否则方法不属于基类。

如果你必须在某些派生中抛出NotSupportedException,那么你已经打破了Liskov Substitution Principle。除了预期的基类之外,这个主要基本上表明任何派生类都应该是适当的。

类的公共接口应尽可能具有凝聚力。如果我遇到这样的选择,我几乎总是把它放到派生类中,除非我真的认为操作“属于”基础。

<强>更新

我想撤回先前的陈述。正如韦恩哈特曼指出的那样,如果这是真的,那么System.IO.Stream也会破坏LSP。该规则声明您不能从子类型中的方法中抛出新的异常。这似乎不适用于抽象方法,因为它们没有任何实现。

我认为重要的是保持你的抽象纯洁。如果在抽象方面将方法添加到基类中是有意义的,那么一定要做到这一点。但是,如果您只想要一个共同的位置来添加代码,那么我会避免将其添加到基础中。

我也同意,有时候部分实施是一致的。

答案 2 :(得分:0)

它是一种只需要一个子类需要的专门方法吗?然后在子类中实现。否则,在引发NotImplementedException的基类中实现为虚拟。然后在任何需要它的类中添加as override。

答案 3 :(得分:0)

如果它只在子类中使用并且不需要多态调用,那么只在子类中实现它。但是,如果您需要以多态方式使用它,那么请考虑该函数对超类的其他子类意味着什么。

如果该功能没有任何好处,那么您可能需要重新考虑您的类层次结构。但是,对于函数没有有效含义的子类,您可以执行No-op或抛出NotImplementedException。我不是真的喜欢它们,但有时候没有办法使用它们。

答案 4 :(得分:0)

我总是倾向于对尚未完成的代码使用NotImplemented样式异常。我永远不会亲自使用它,因此我可以将更多方法推入基类。

答案 5 :(得分:0)

对于这个,您需要回答一些关于API意图的问题。

  1. 如何使用您的API:如果您的API使用者几乎总是引用您的基类,那么将它放入基类可能是有意义的。
  2. 如果您尝试实现的方法适用于几乎所有可以选择实现该功能的派生类,请将其放在基类中。
  3. 考虑System.IO.Stream,这是一个抽象类,使用抽象方法进行搜索操作,不必从System.IO.SeekableStrem派生只是为了获取搜索功能是有意义的,API的用户应该只请参阅Stream