22

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

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

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

经过一番谷歌搜索后,我没有找到在 php 中实现“真正的”虚函数的好答案(只是有一个虚函数,这几乎扼杀了具体实现的所有希望)。

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

4

3 回答 3

33

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

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

function after_insert() {
  // Virtual
}

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

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

希望这会给你一些启发。

于 2009-08-31T22:13:52.780 回答
4

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

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

于 2010-07-01T11:04:30.763 回答
1

如果没有基类实现的示例,很难提供具体信息。但有几件事浮现在脑海:

  1. 数据库抽象从一开始就是复杂的东西。我知道你想让它保持精简、干净和刻薄,但我认为这非常困难。您确实必须彻底查看不同数据库引擎的规格,以了解哪些部分是通用的,哪些部分需要专门化。还; 您确定没有将 DB 抽象与 Table Data Gateway 模式混合在一起,因为您正在谈论通过扩展基类来添加 DB 表?

  2. 如果扩展类向后弯曲也保持清洁,则当前基类的方法可能做得太多和/或不够通用。也许您应该将基类接口方法分解为较小的受保护方法,这些受保护方法足够通用,可以在扩展类的覆盖方法中重用?反之亦然:也许你应该在你的接口方法中有对可覆盖方法的钩子。

  3. 从第 2 点开始:有一个带有一些通用实现方法的抽象类,并让您的 vanilla 类(您的基类)和其他类继承自它有什么问题?

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

于 2009-08-29T03:45:56.647 回答