无论如何(或模式)是否强制调用父方法?
我有一个像这样的抽象类:
abstract class APrimitive{
public function validate(){
//Do some stuff that applies all classes that extend APrimitive
}
}
然后我有一些扩展到APrimitive“base”的类:
class CSophisticated extends APrimitive{
public function validate(){
//First call the parent version:
parent::validate();
//Then do something more sophisticated here.
}
}
问题在于,如果我们在几个月后回到代码中,并使用validate()
方法创建一些类似CSophisticated的类,我们可能会忘记拨打电话该方法中parent::validate()
。
请注意,某些CS复杂类可能没有validate()
方法,因此将调用父版本。
我知道可以在某个地方发表评论,提醒程序员拨打parent::validate()
,但是有更好的方法吗?如果未在parent::validate()
方法中调用validate()
,那么抛出异常的自动方式可能会很好。
答案 0 :(得分:10)
您可以使用以下内容强制执行此操作:
abstract class APrimitive{
final public function validate(){
//do the logic in validate
overrideValidate();
}
protected function overrideValidate(){
}
}
class CSophisticated extends APrimitive{
protected function overrideValidate(){
}
}
现在只允许调用validate
,这将调用您的重写方法。语法可能稍微偏离(PHP
不是我选择的语言)但该原则适用于大多数OOP语言。
进一步解释:
abstract class APrimitive{
public function validate(){
echo 'APrimitive validate call.';
overrideValidate();
}
protected function overrideValidate(){
}
}
class CSophisticated extends APrimitive{
protected function overrideValidate(){
echo 'CSophisticated call.';
}
}
CSophisticated foo;
foo.overrideValidate(); //error - overrideValidate is protected
foo.validate(); //
输出:
APrimitive validate call.
CSophisticated call.
函数调用基本上执行以下操作:
foo.validate() -> APrimitive.validate() -> ASophisticated.overrideValidate() (or APrimitive.overrideValidate() if it wasn't overriden)
答案 1 :(得分:9)
您正在寻找The Template Method模式 此模式允许您通过子类化以某种方式修改操作,但确保始终涉及基类。
class Base {
//declared final so it can't be overridden
public final function validate() {
//perform base class operations here
//then forward to the sub class
$this->doValidate();
//do some more base class stuff here if needed
}
//override this method to alter validate operation
protected function doValidate(){
//no-op in base
}
}
class Sub {
protected function doValidate() {
//if required
//make the sub-class contribution to validate here
}
}