2008-11-28 107 views
2

我正在处理一个大型的代码库,它在这些类中有很多类和很多抽象方法。我对以下情况下我应该做的事情感兴趣。抽象方法的默认实现

如果我有一个带有抽象方法的Parent-A类。只有两个孩子。如果Child-B实现AbstractMethodA但Child-B不适用。

我应该

  1. 从母体中取出抽象的关键字,并使用虚拟的或动态?
  2. 提供该方法的空实现。
  3. 提供一个实现,如果调用会引发错误。
  4. 忽略警告。

编辑:谢谢你的所有答案。它证实了我的怀疑,认为这不应该发生。经过进一步调查后发现这些方法根本没有使用,所以我已经完全删除了它们。

回答

9

如果AbstractMethodA不适用于Child-B,则Child-B不应该从Parent-A继承。

或者,如果Child-B从Parent-A继承,并且AbstractMethodA不适用于子级,则它不应该在父级中。

通过在Parent-A中添加一个方法,您表示该方法适用于Parent-A及其所有子项。这就是继承意味着,如果你用它来表示不同的东西,你最终会与编译器发生严重的争执。

[编辑 - 也就是说,如果该方法确实适用,Mladen Prajdic的答案没问题,但对于涉及的一个或多个类别应该什么也不做。一种什么都不做的方法是与不适用的方法不同,但也许我们并不是指“不适用”的同一个事物]

另一种技术是在Child中实现该方法-B无论如何,但要让它像总是返回失败一样激烈,或者抛出异常或其他东西。它的工作原理,但应该被认为是一个闪光点,而不是一个干净的设计,因为这意味着来电者需要知道他们有什么东西,他们对待父母A是真的一个孩子B和因此他们不应该调用AbstractMethodA。基本上你已经抛弃了多态,这是OO继承的主要好处。就我个人而言,我更喜欢这样做,因为在基类中有一个抛出异常的实现,因为这样子类就不会“意外”地通过“遗忘”来执行该方法。它必须实现它,如果它实现它不起作用,那么它明确地这样做。糟糕的情况应该是嘈杂的。

0

使其在基类中虚拟为空,并在子类中覆盖它。

0

您可以使用接口。然后Child-A和Child-B都可以实现不同的方法,并仍然继承Parent-A。接口像抽象方法一样工作,因为它们迫使类实现它们。

2

如果后代实现不是强制性的,那么你应该去1 + 2(在祖先即空的虚拟方法)

0

如果一些亚类(B1,B2,......)的A用于其方法的不同子集(C1,C2,...),可以说A可以在B和C中分开。

我不知道德尔福太好了(根本不是:)),但我认为就像例如在Java和COM中,一个类可以'实现'多个接口。在C++中,这只能通过多次继承抽象类来实现。

更具体一点:我会创建两个抽象类(使用抽象方法),并更改继承树。

如果这不可行,解决方法可以是“适配器”:一个中间类A_nonB_,所有B方法都实现为空(并且在调用它们时产生警告)以及A_nonC_。然后更改继承树来解决您的问题:B1,B2,...从A_nonC_继承,C1,C2 ...从A_NonB_继承。

1

我认为,一般来说,如果您无法首先实现所有抽象方法,则不应该从抽象类继承,但我知道在某些情况下它仍然有意义(请参阅Stream类及其实现)。

我认为你应该创建这些抽象方法的实现,抛出一个NotImplementedException。

您也可以尝试使用ObsoleteAttribute,以便调用该特定的方法将是编译时错误(当然,抛出NotImplementedException)。请注意,ObsoleteAttribute并不完全用于此目的,但我想如果您在评论中使用了有意义的错误消息,那没有关系。

强制性代码例如:

[Obsolete("This class does not implement this method", true)] 
public override string MyReallyImportantMethod() 
{ 
    throw new NotImplementedException("This class does not implement this method."); 
}