在我的工作场所(仅限php),我们有一个用于数据库抽象的基类。如果要将新数据库表添加到基础层,则必须创建此基类的子类,并重写某些方法以定义使用此表的各个行为。正常行为应该保持不变。
现在我在公司看到了很多新的程序员,他们只是覆盖了默认行为的方法。有些人很擅长放入所有默认行为,只是在他们喜欢的地方添加个别内容,其他人则试图使用基类及其继承者。
我首先想到解决这个问题,正在考虑应该通过继承类来覆盖的抽象方法。但除了反对抽象方法的其他论据之外,“抽象”只是没有显示为什么基类不能被它自己使用而为什么这些函数应该被覆盖。
经过一些谷歌搜索后,我没有找到一个很好的答案在PHP中实现“真正的”虚拟功能(只是有一个虚拟功能,几乎杀死了具体实现的所有希望)。
那么,你会对这件事做些什么呢?
答案 0 :(得分:31)
在PHP中,所有 public 和 protected 函数都是“虚拟”。您可以通过添加 final 关键字来阻止覆盖功能。 (或者将它们设为私有,但这可能是一个坏主意)。
在基类的设计中,我会想到子类想要影响的行为。 我会创建像before_update()和after_insert()这样的空函数。
function after_insert() {
// Virtual
}
当更新/插入事件发生时,基类将调用哪个。
可能是一个is_valid()函数,它总是在基类中返回true,并使用commentblock来描述子类返回false时的后果。
希望这会给你一些灵感。
答案 1 :(得分:4)
如果人们以错误的方式使用该类,您可以始终使用“final”关键字来防止某些类函数被覆盖。
听起来我觉得他们无法实现某些功能,因此会覆盖这些方法。您可能需要查看课程的设计。
答案 2 :(得分:0)
如果没有基类实现的示例,很难给出具体信息。但是有些事情会浮现在脑海中:
数据库抽象是一开始很复杂的事情。我知道你想保持它的精益,干净和卑鄙,但我认为这很难。你必须仔细研究不同数据库引擎的规格,看看哪些部分是通用的,哪些部分需要专业化。也;你确定你没有将DB抽象与表数据网关模式混淆,因为你正在谈论通过扩展基类来添加数据库表吗?
当前基类的方法可能做得太多和/或不够通用,如果扩展类向后弯曲也要保持干净。也许你应该在较小的受保护方法中打破基类接口方法,这些方法通常足以在扩展类的重写方法中重用?反之亦然:也许你应该在接口方法中使用可覆盖方法的钩子。
从第2点开始:有一个带有一些通用实现方法的抽象类有什么问题,让你的vanilla类(你的基类)和其他类继承自那个?
最后,也许你应该只强制实现一个接口,而不是扩展基类?