代码之家  ›  专栏  ›  技术社区  ›  erikbstack

在PHP中正确实现虚拟函数?

  •  19
  • erikbstack  · 技术社区  · 15 年前

    在我的工作场所(仅限PHP),我们有一个用于数据库抽象的基类。当您想要向基础层添加一个新的数据库表时,您必须创建这个基础类的子类,并重写一些方法来定义使用这个表的单独行为。正常行为应该保持不变。

    现在,我在我们公司看到了许多新的程序员,他们只是为默认行为重写方法。有些人非常“好”地加入了所有的默认行为,只不过在他们喜欢的地方添加了一些单独的东西,而另一些人则在试图使用基类及其继承者时杀死了他们自己。

    我解决这个问题的第一个想法是考虑应该由继承类覆盖的抽象方法。但是除了其他反对抽象方法的论点,“抽象”并没有显示 为什么? 基类不能自己使用,并且 为什么? 这些函数应该被重写。

    在搜索了几次之后,我没有找到一个很好的答案来用PHP实现“真实”的虚拟函数(只是有一个虚拟函数,它几乎消除了具体实现的所有希望)。

    那么,你会怎么处理这件事?

    3 回复  |  直到 15 年前
        1
  •  31
  •   Bob Fanger    13 年前

    在PHP中 公众的 受保护的 功能是“虚拟的”。您可以通过预先设置 final 关键字。(或者让他们保密,但这可能是个坏主意)。

    在基类的设计中,我会想到子类想要影响的行为。 例如,我将创建空函数,如在_update()之前和在_insert()之后。

    function after_insert() {
      // Virtual
    }
    

    当发生更新/插入事件时,基类将调用它。

    可能是一个在baseclass中总是返回true的is-valid()函数,并使用commentBlock描述子类返回false时的结果。

    希望这能给你一些灵感。

        2
  •  4
  •   Rob    14 年前

    如果人们以错误的方式使用类,则可以始终使用“final”关键字来防止某些类函数被重写。

    在我看来,它们无法实现某些功能,因此无法覆盖这些方法。您可能需要看看您的类的设计。

        3
  •  0
  •   Decent Dabbler    15 年前

    如果没有基类实现的例子,就很难给出具体的信息。但我想到了一些事情:

    1. 数据库抽象从一开始就很复杂。我知道你想保持苗条、干净和刻薄,但我觉得这很困难。您真的需要仔细查看不同DB引擎的规格,看看哪些部分是通用的,哪些部分需要专门化。另外,您确定您没有将DB抽象与表数据网关模式混合在一起吗,因为您正在讨论通过扩展基类来添加DB表?

    2. 当前基类的方法可能做得太多和/或不够一般,无法从中开始,如果扩展类向后弯曲,请保持干净。也许您应该将基类接口方法分解成更小的受保护方法,这些方法足够通用,可以在扩展类的重写方法中重用。或者反之亦然:也许您应该在接口方法中有指向可重写方法的钩子。

    3. 从第2点开始:使用一些通用的实现方法拥有一个抽象类,并让您的普通类(您的基类)和其他类继承自 那个 ?

    4. 最后,也许您应该强制一个要实现的接口,而不是扩展基类?