如果我使用继承,后来意识到单个子类需要一个不可用的方法或字段,我应该在基类中声明它而不是在其他子类中实现它,或者我应该在其中声明它单个子类?
如果我选择在子类中声明方法,那么我就不能再以多态方式处理所有内容。另一方面,如果我选择将它放在基类中,那么我最终会得到许多不实现属性或方法的子类。我已经在.net框架中看到了选择“未实现”方法的示例。什么是最好的方式?
答案 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意图的问题。
考虑System.IO.Stream
,这是一个抽象类,使用抽象方法进行搜索操作,不必从System.IO.SeekableStrem
派生只是为了获取搜索功能是有意义的,API的用户应该只请参阅Stream
。