Gor*_*onM 27 php oop subclassing
当您继承对象并希望扩展初始化代码时,有两种方法.覆盖__construct(),并实现超类构造函数调用的初始化方法.
方法1:
class foo
{
public function __construct ($arg1, $arg2, $arg3)
{
// Do initialization
}
}
class bar extends foo
{
public function __construct ($arg1, $arg2, $arg3)
{
parent::__construct ($arg1, $arg2, $arg3);
// Do subclass initialization
}
}
Run Code Online (Sandbox Code Playgroud)
方法2
class foo
{
public function init ()
{
// Dummy function
}
public function __construct ($arg1, $arg2, $arg3)
{
// Do subclass defined initialization
$this -> init ();
// Do other initialization
}
}
class bar extends foo
{
public function init ()
{
// Do subclass initialization
}
}
Run Code Online (Sandbox Code Playgroud)
对于Zend框架的文件似乎阻止重载构造函数,并希望您重写初始化方法,若设置,但不知何故只是不觉得我的权利.Zend还倾向于做一些我不满意的事情,所以我不确定它是否应该被用作最佳实践的一个例子.我个人认为第一种方法是正确的,但我已经看到第二种方法经常足以想知道这实际上是我应该做的.
你对覆盖__construct有什么意见吗?我知道你必须小心记住调用超类构造函数,但大多数程序员应该知道这一点.
编辑: 我没有使用Zend,我只是使用它作为代码库的一个例子,鼓励你使用init()而不是重写__construct().
Fro*_*y Z 18
看起来第二种方法是推迟问题.
如果你有一个班级:
class bar2 extends bar // which already extends foo
{
public function init()
{
// You should then do anyway:
parent::init();
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
我也会采用第一种方法,更合乎逻辑,更直接,因为无法无休止地避免使用parent::init()或parent::__construct()调用.第一种方法IMO不那么容易混淆.
我能想到的唯一两种情况init()是使用它是有意义的,当你的构造函数是非公开的,但你需要给人们一个影响初始化的机会,例如在一个抽象的Singleton中(你不想使用它) .或者,像在Zend Framework中一样,应该延迟额外的初始化(但是你不要init()从构造函数调用).
顺便提一下,从超类中调用子类中的方法称为模板方法.UseCase将协调某个工作流程,但允许子类型影响其中的部分工作流程.这通常是通过常规方法完成的.请注意,构造函数不应该编排任何东西,只需将对象初始化为有效状态即可.
你绝对应该不叫/报价init()从构造以防止不必记住调用父类的构造函数的开发.虽然这听起来很方便,但很快就会破坏继承层次结构.还要注意,它与通常初始化对象的方式不同,开发人员必须学习这种新行为,就像他们必须学会调用超类型的构造函数一样.