Delphi 抽象方法的默认实现
我正在处理一个大型的代码库,它有许多类和这些类上的许多抽象方法。我感兴趣的是人们对我在以下情况下应该做什么的看法 如果我有一个带有抽象方法的类Parent-a。只有两个孩子。如果Child-B实现AbstractMethodA,但Child-B不实现,因为它不适用 我应该吗Delphi 抽象方法的默认实现,delphi,oop,abstract-methods,Delphi,Oop,Abstract Methods,我正在处理一个大型的代码库,它有许多类和这些类上的许多抽象方法。我感兴趣的是人们对我在以下情况下应该做什么的看法 如果我有一个带有抽象方法的类Parent-a。只有两个孩子。如果Child-B实现AbstractMethodA,但Child-B不实现,因为它不适用 我应该吗 从父级中删除抽象关键字并使用虚拟或动态 提供该方法的空实现 提供一个在调用时引发错误的实现 忽略警告 编辑:谢谢所有的答案。这证实了我的怀疑,这不应该发生。经过进一步调查,结果表明这些方法根本没有被使用,所以我将它们全部删除
编辑:谢谢所有的答案。这证实了我的怀疑,这不应该发生。经过进一步调查,结果表明这些方法根本没有被使用,所以我将它们全部删除。在基类中将其虚拟为空,并在子类中重写它。如果AbstractMethodA不适用于Child-B,则Child-B不应继承自父-A 或者相反,如果Child-B继承自父级A,而AbstractMethodA不适用于该子级,那么它也不应该位于父级中 将一个方法放在Parent-a中,就是说该方法适用于Parent-a及其所有子对象。这就是继承的含义,如果你用它来表示不同的意思,你最终会和你的编译器发生严重的争执 [编辑-也就是说,如果该方法确实适用,那么Mladen Prajdic的回答是可以的,但是对于所涉及的一个或多个类不应该做任何事情。一个不做任何事情的方法与一个不适用的方法是不同的,但我们所说的“不适用”可能不是同一件事]
另一种技术是无论如何在Child-B中实现该方法,但是让它做一些激烈的事情,比如总是返回失败,或者抛出异常,等等。它是有效的,但应该被视为一种预兆,而不是一种干净的设计,因为这意味着调用方需要知道他们作为父对象处理的东西-a实际上是子对象-B,因此他们不应该调用AbstractMethodA。基本上,您已经放弃了多态性,这是OO继承的主要好处。就我个人而言,我更喜欢这样做,而不是在基类中使用异常抛出实现,因为这样子类就不会因为“忘记”实现该方法而“意外”表现糟糕。它必须实现它,如果它实现它不起作用,那么它会显式地这样做。糟糕的情况应该是嘈杂的。您可以使用接口。然后,Child-A和Child-B都可以实现不同的方法,并且仍然从父级A继承。接口的工作方式类似于抽象方法,因为它们强制类实现它们。如果子类中的实现不是强制性的,那么您应该选择1+2(即祖先中的空虚拟方法)如果某些子类(B1,B2,…)A的一部分用于其方法的不同子集(C1,C2,…),可以说A可以分为B和C 我不太了解Delphi(一点也不了解:),但我认为就像Java和COM中一样,一个类可以“实现”多个接口。在C++中,这只能通过对继承抽象类进行多重继承来实现。 更具体:我将创建两个抽象类(使用抽象方法),并更改继承树
如果这是不可能的,那么解决方案可以是一个“适配器”:一个中间类a_nonB_,其中所有B方法都实现为空(并在调用它们时产生警告),以及一个a_nonC_。然后更改继承树以解决您的问题:B1、B2。。。从非继承项和C1,C2,。。。继承自A_NonB_。我认为,一般来说,如果无法首先实现所有抽象方法,则不应该继承自抽象类,但我理解,在某些情况下,这样做仍然是有意义的(请参见流类及其实现) 我认为您应该创建这些抽象方法的实现,它们抛出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.");
}