例如,在Yii2框架中,yii'filters'AccessControl
类重写其父类yii'base'Object
中的init()
函数。这个Object类又有一个类似这样的构造函数方法:
Class Object implements Configurable {
public function __construct($config = [])
{
if (!empty($config)) {
Yii::configure($this, $config);
}
$this->init(); // calls the method defined below
}
}
// and the definition of this init function ...
public function init()
{
}
现在,编写这样一个空函数显然没有什么用处,除非有人想用来初始化他/她将来可能需要的一些属性。
但是__construct()
方法有完全相同的用途!我需要了解这种init()
方法有多大帮助。
原因很简单:他们希望您扩展类
所以你应该做一些类似的事情
class Bob extends Object {
public function init() {
$this->setup_something();
}
}
因此,因为Bob
扩展了Object
,所以Bob
的方法就是被调用的方法。如果不需要初始化某个东西,只需跳过定义,基类就会调用空方法。
这使您不必做一些可能更混乱的事情:覆盖构造函数
class Bob extends Object {
public function __construct($config = []) {
$this->setup_something();
}
}
现在,这很混乱,因为很多人错过了一些关键的东西(在这个例子中,我故意忽略了这一点):父构造函数将不会被调用(您可以通过parent::__construct($config)
来做到这一点。)。因此,通过有一个单独的init()
,可以完全避免这种混乱。有一种明确的方法可以自己设置。
Yii论坛上对此进行了详细讨论。Yii项目负责人:
init()的原因之一是关于对象(确切地说是组件)的生命周期。
使用init()方法,可以在对象被实例化之后和完全初始化之前配置对象。例如,可以使用应用程序配置来配置应用程序组件。如果您重写它的init()方法,您将确保应用了配置,并且可以安全地检查是否一切就绪。类似的事情也发生在小部件和其他可配置组件上。
即使init()是在构造函数内而不是由另一个对象调用的,它也有意义。例如,在CApplication中,有preInit()和init()。它们设置了应用程序的生命周期,并且可能会被覆盖,以便自定义只在预期的生命周期中发生。
我同意你的观点,方法命名非常重要。在Yii中,init()方法意味着对象已经完全配置好,并且应该在该方法中完成一些额外的初始化工作。
和:
每个函数的存在都应该有原因。在Yii的情况下,init()方法主要用于允许在组件的特定生命周期进行自定义。在您的日历应用程序中,您可能需要也可能不需要init()。如果你打算发布它供公众使用,我建议你在允许定制方面更加保守。也就是说,除非你有充分的理由,否则不要定义init()。一旦你提供了一个受保护的或公共的方法,就意味着你需要在未来的版本中维护它。