Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 抽象方法的默认实现_Delphi_Oop_Abstract Methods - Fatal编程技术网

Delphi 抽象方法的默认实现

Delphi 抽象方法的默认实现,delphi,oop,abstract-methods,Delphi,Oop,Abstract Methods,我正在处理一个大型的代码库,它有许多类和这些类上的许多抽象方法。我感兴趣的是人们对我在以下情况下应该做什么的看法 如果我有一个带有抽象方法的类Parent-a。只有两个孩子。如果Child-B实现AbstractMethodA,但Child-B不实现,因为它不适用 我应该吗 从父级中删除抽象关键字并使用虚拟或动态 提供该方法的空实现 提供一个在调用时引发错误的实现 忽略警告 编辑:谢谢所有的答案。这证实了我的怀疑,这不应该发生。经过进一步调查,结果表明这些方法根本没有被使用,所以我将它们全部删除

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

如果我有一个带有抽象方法的类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.");
    }