2

我正在处理一个大型代码库,其中有很多类和这些类上的很多抽象方法。我对人们对我在以下情况下应该做什么的看法感兴趣。

如果我有一个带有抽象方法的类 Parent-A。将只有2个孩子。如果 Child-B 实现 AbstractMethodA 但 Child-B 没有实现,因为它不适用。

我是不是该

  1. 从 parent 中删除 abstract 关键字并使用 virtual 或 dynamic?
  2. 提供该方法的空实现。
  3. 提供一个在调用时会引发错误的实现。
  4. 忽略警告。

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

4

6 回答 6

9

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

或者相反,如果 Child-B 继承自 Parent-A,并且 AbstractMethodA 不适用于孩子,那么它也不应该在父母中。

通过在 Parent-A 中放置一个方法,您是说该方法适用于 Parent-A 及其所有子级。这就是继承的意思,如果你用它来表示不同的东西,你最终会和你的编译器发生严重的争论。

[编辑-也就是说,如果该方法确实适用,则 Mladen Prajdic 的回答很好,但对于所涉及的一个或多个类不应该做任何事情。什么都不做的方法在 IMO 与不适用的方法不同,但也许我们所说的“不适用”并不是指同一件事]

另一种技术是无论如何在 Child-B 中实现该方法,但让它做一些极端的事情,比如总是返回失败,或者抛出异常,或者其他什么。它可以工作,但应该被视为有点笨拙而不是干净的设计,因为这意味着调用者需要知道他们所拥有的被视为 Parent-A 的东西真的是一个child-B,因此他们不应该调用AbstractMethodA。基本上,您已经放弃了多态性,这是 OO 继承的主要好处。就我个人而言,我更喜欢这样做而不是在基类中实现抛出异常,因为这样子类就不会因为“忘记”实现该方法而“意外地”表现得不好。它必须实现它,如果它实现它不起作用,那么它会明确地这样做。糟糕的情况应该是嘈杂的。

于 2008-11-28T12:44:09.340 回答
2

如果后代中的实现不是强制性的,那么您应该选择 1+2(即祖先中的空虚方法)

于 2008-11-28T12:47:11.707 回答
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.");
}
于 2008-11-28T13:24:25.750 回答
0

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

于 2008-11-28T12:43:21.527 回答
0

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

于 2008-11-28T12:46:28.137 回答
0

如果 A 的某些子类 (B1, B2, ...) 与其他子类 (C1, C2, ...) 用于其方法的不同子集,则可能会说 A 可以分为 B 和 C。

我不太了解Delphi(一点也不了解:)),但我认为就像在Java 和COM 中一样,一个类可以“实现”多个接口。在 C++ 中,这只能通过多重继承抽象类来实现。

更具体:我将创建两个抽象类(带有抽象方法),并更改继承树。

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

于 2008-11-28T13:01:37.123 回答