2009-08-28 220 views
19

在我的工作地点(仅限PHP)我们有一个数据库抽象的基类。如果要将新数据库表添加到基础层,则必须创建此基类的子类并重写一些方法来定义使用此表的单个行为。正常的行为应该保持不变。在PHP中正确实现虚函数?

现在我看到很多新的程序员在我们公司,他们只是重写默认行为的方法。有些是非常“好”的,可以放入所有的默认行为,只需在那里添加他们喜欢的东西,其他人会自己尝试使用基类和它们的继承者。

我要解决这个问题首先想到的,还想着应该由继承类重写的抽象方法。但对抽象方法其他参数的旁边,“抽象”只是不显示为什么的基类不能被单独使用和为什么这些功能应该被重写。

经过一番周围的Googling我没有找到一个很好的答案实现在PHP中“真实”的虚拟功能(只是有一个虚函数,几乎杀死一个具体实现的希望)。

那么,你会怎么做这件事呢?

+0

对不起,但我并不完全明白你的问题,当你说“虚拟函数”是你在谈论__call()和__callStatic()魔术方法吗?还是lambda函数? – 2009-08-29 01:35:23

+5

我认为他意味着方法重写。 http://en.wikipedia.org/wiki/Method_overriding在C++中被称为虚函数。 – 2009-08-31 21:53:17

回答

31

在PHP中所有公共保护功能是 “虚拟” 的。您可以通过预先设定final关键字来防止功能被覆盖。 (或者将它们私人化,但这可能是一个坏主意)。

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

function after_insert() { 
    // Virtual 
} 

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

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

希望这会给你一些启发。

0

没有你的基类实现的例子,很难给出具体的信息。但有几件事情浮现在脑海:

  1. 数据库抽象是复杂的东西开始。我明白,你想保持它的精益,干净和平均,但我认为这是相当困难的。你必须仔细研究不同数据库引擎的规格,看看哪些部分是通用的,哪些部分需要专业化。也;你确定你没有将数据库抽象与表数据网关模式混淆,因为你正在谈论通过扩展基类来添加数据库表吗?

  2. 如果扩展类向后弯曲,保持它的清洁,那么当前基类的方法可能做得太多和/或不够通用。也许你应该将基类接口方法分解成更小的受保护的方法,这些方法通用性足以在扩展类的重写方法中重用。反之亦然:也许你应该在你的接口方法中使用可重写方法的钩子。

  3. 从2点之后:有什么不对具有某些一般的方法来实现一个抽象类,并让您的香草类(基类)和其他类从继承?

  4. 最后,也许你应该只执行一个接口来实现,在扩展的基类代替?

3

如果用户以错误的方式使用类,则始终可以使用“final”关键字来防止某些类功能被覆盖。

这听起来像他们不能达到某些功能,因此覆盖了方法。你可能需要看看你的课程设计。