php PHP中虚函数的正确实现?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1349637/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Correct Implementation of Virtual Functions in PHP?
提问by erikbwork
at my working place (php only) we have a base class for database abstraction. When you want to add a new database table to the base layer, you have to create a subclass of this base class and override some methods to define individual behaviour for using this table. The normal behaviour should stay the same.
在我的工作场所(仅限 php),我们有一个用于数据库抽象的基类。当您想向基础层添加新的数据库表时,您必须创建该基类的子类并覆盖一些方法来定义使用该表的各个行为。正常行为应该保持不变。
Now I have seen many new programmers at our company, who just override the method for the default behaviour. Some are so "nice" to put in all the default behaviour and just add there individual stuff where they like it, others kill themself trying to use the baseclass and their inheritor.
现在我在我们公司看到很多新程序员,他们只是覆盖了默认行为的方法。有些非常“好”,可以放入所有默认行为,并在他们喜欢的地方添加单独的东西,其他人试图使用基类及其继承者而自杀。
My first thought to solve this problem, was thinking about abstract methods that should be overriden by inheriting classes. But beside other arguments against abstract methods, "abstract" just does not show whythe baseclass can't be used by its own and whythese function should be overriden.
我解决这个问题的第一个想法是考虑应该通过继承类覆盖的抽象方法。但是除了反对抽象方法的其他论点之外,“抽象”只是没有说明为什么基类不能被它自己使用以及为什么这些函数应该被覆盖。
After some googling around I didn't find a good answer to implementing "real" virtual functions in php (just that there is a virtual function, that nearly kills all hope of a concrete implementation).
经过一番谷歌搜索后,我没有找到在 php 中实现“真实”虚拟函数的好答案(只是有一个虚拟函数,这几乎扼杀了具体实现的所有希望)。
So, what would you do with this matter?
那么,你会怎么处理这件事呢?
回答by Bob Fanger
In PHP all publicand protectedfunctions are "virtual". You can prevent functions from being overriden by prepending the finalkeyword. (Or by making them private, but this is probably a bad idea).
在 PHP 中,所有公共和受保护的函数都是“虚拟的”。您可以通过添加final关键字来防止函数被覆盖。(或者通过将它们设为私有,但这可能是一个坏主意)。
In the design of the baseclass I would think of behaviors that subclasses would want to affect. I would for example create empty functions like before_update() and after_insert().
在基类的设计中,我会考虑子类想要影响的行为。例如,我会创建像 before_update() 和 after_insert() 这样的空函数。
function after_insert() {
// Virtual
}
Which the baseclass will call when an update/insert event occurs.
当更新/插入事件发生时基类将调用它。
Maybe an is_valid() function which always returns true in the baseclass, and use the commentblock to describe what the consequences are when a subclass return false.
也许是一个 is_valid() 函数,它总是在基类中返回 true,并使用注释块来描述子类返回 false 时的后果。
Hopefully this would give you some inspiration.
希望这会给你一些启发。
回答by Rob
You can always use the "final" keyword to prevent some of the classes functions from being overridden if people are using the class in the wrong way.
如果人们以错误的方式使用类,您始终可以使用“final”关键字来防止某些类函数被覆盖。
It sounds to me like they are unable to acheive certain functionality hence overriding the methods. You may need to take a look at the design of your classes.
在我看来,他们无法实现某些功能,因此覆盖了这些方法。您可能需要查看类的设计。
回答by Decent Dabbler
Without an example of the implementation of your base class, it's hard to give concrete info. But a few things come to mind:
如果没有基类实现的示例,则很难提供具体信息。但是我想到了一些事情:
Database abstraction is complex stuff to begin with. I understand that you want to keep it lean, clean and mean, but I think it's pretty darn difficult. You really have to take a thorough look at the specs of different DB engines to see what parts are general and what parts need specialization. Also; are you sure you don't have DB abstraction mixed up with the Table Data Gateway pattern, as you are talking about adding DB tables by extending the base class?
The methods of your current base class might be doing too much and/or are not general enough to begin with, if the extended classes are bending over backwards too keep it clean. Maybe you should break the base class interface methods up in smaller protected methods that are general enough to be reused in the overriding methods of the extended classes? Or vice versa: maybe you should have hooks to overridable methods in your interface methods.
Following from point 2: What's wrong with having an abstract class with some general implemented methods, and let your vanilla class (your base class) and other classes inherit from that?
Lastly, maybe you should just enforce an interface to be implemented, in stead of extending the base class?
数据库抽象从一开始就很复杂。我知道你想保持简洁、干净和刻薄,但我认为这非常困难。您确实必须彻底查看不同数据库引擎的规范,以了解哪些部分是通用的,哪些部分需要专门化。还; 您确定您没有将数据库抽象与表数据网关模式混在一起,因为您正在谈论通过扩展基类来添加数据库表吗?
您当前基类的方法可能做得太多和/或不够通用,如果扩展类向后弯曲也保持干净。也许您应该将基类接口方法分解为较小的受保护方法,这些方法足够通用以在扩展类的覆盖方法中重用?反之亦然:也许你应该在你的接口方法中有可覆盖方法的钩子。
从第 2 点开始:有一个带有一些通用实现方法的抽象类有什么问题,让您的普通类(您的基类)和其他类继承它?
最后,也许您应该只强制实现一个接口,而不是扩展基类?

