PHP中虚函数的正确实现方式?

24
在我所在的工作场所(仅使用PHP),我们有一个用于数据库抽象的基类。 当您想要将新的数据库表添加到基础层时,您必须创建此基类的一个子类并覆盖一些方法以定义使用此表的个性化行为。 正常的行为应该保持不变。
现在,我看到了很多新程序员在我们公司,他们只是覆盖默认行为的方法。 有些人非常“友好”,将所有的默认行为放在那里,并在他们喜欢的地方添加了他们自己的东西,其他人则试图使用基类和它们的继承者而痛苦万分。
解决这个问题的第一个想法是考虑由继承类重写的抽象方法。 但是除了其他反对抽象方法的论据之外,“抽象”根本不能说明为什么基类不能单独使用以及为什么这些函数应该被重写。
经过一番搜索,我没有找到在PHP中实现“真正的”虚拟函数的好方法(只有一个虚拟函数,几乎让所有具体实现的希望破灭)。
那么,您会如何处理这个问题?

很抱歉,我不太明白你的问题。当你说“虚拟函数”时,你是指__call()和__callStatic()魔术方法吗?还是指lambda函数? - Alix Axel
5
我认为他的意思是方法覆盖。在C++中,它被称为虚函数。参考链接:http://en.wikipedia.org/wiki/Method_overriding。 - Bob Fanger
3个回答

36

在PHP中,所有的公共受保护函数都是“虚拟”的。您可以通过在函数前加上final关键字来防止函数被覆盖。(或者将它们设为私有,但这可能不是个好主意)。

在基类的设计中,我会考虑子类想要影响的行为。例如,我会创建像before_update()和after_insert()这样的空函数。

function after_insert() {
  // Virtual
}

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

也许在基类中有一个总是返回true的is_valid()函数,使用commentblock描述当子类返回false时的后果。

希望这能给你一些启示。


5

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

对我来说,他们似乎无法实现某些功能,因此重写了这些方法。您可能需要查看类的设计。


1

没有你的基类实现示例,很难给出具体信息。但是有几件事情值得注意:

  1. 数据库抽象化本身就是复杂的事情。我知道你想保持它简洁、干净、高效,但我认为这非常困难。你真的必须仔细查看不同数据库引擎的规格,以确定哪些部分是通用的,哪些部分需要专门处理。另外,你确定你没有把数据库抽象化混淆了与表数据网关模式,因为你在谈论通过扩展基类来添加数据库表?

  2. 如果扩展类为了保持代码干净而在当前基类的方法中加入了太多内容和/或方法不够通用,那么也许你应该把基类接口方法拆分成更小的受保护方法,这些方法足够通用,可以在扩展类的覆盖方法中重复使用?反之亦然:也许你应该在接口方法中添加可重写方法的钩子。

  3. 从第二点开始说起:为什么不能有一个带有一些一般实现方法的抽象类,让你的普通类(基类)和其他类从中继承呢?

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接