在PHP中声明一个类的ctor'final'是不好的做法吗?

时间:2010-01-03 01:24:21

标签: php class constructor final

如果我有一个由很多很多其他类扩展的父类,并且我想确保父类的构造函数总是运行,那么声明构造函数final是不是一个坏主意? / p>

我在考虑做这样的事情:

class ParentClass {

    public final function __construct() {

        //parent class initialization...

        $this->construct();

    }

    protected function init() {

        echo 'constructing<br>';

    }

}

class ChildClass extends ParentClass {

    protected function init() {

        //child class initialization

        echo 'constructing child<br>';

    }

}

这样子类可以有一个排序构造函数,父类的构造函数将始终执行。这是不好的做法吗?

3 个答案:

答案 0 :(得分:9)

声明final __construct可确保任何扩展您的类的人都无法实现具有相同名称的方法。从表面上看,这似乎意味着没有其他人可以为这个类的子类声明构造函数,但事实并非如此,因为{4}的PHP 4样式仍然可以正常工作构造函数的备用名称。实际上,将构造函数声明为final可以在PHP中找不到任何东西。

答案 1 :(得分:5)

从PHP 5.3.3开始,我已经使用5.6和7.0对此进行了测试,声明类__construct的{​​{1}}方法将阻止任何子类使用final覆盖构造函数或PHP 4样式的__construct(请注意PHP 7样式自PHP 7起已弃用)。防止声明构造函数的子类将确保始终调用父构造函数。当然,这将不允许任何子类实现自己的构造函数逻辑。虽然我不建议将其作为良好做法,但肯定会有实际用例。

一些例子:

未声明ClassName()最终版

__construct

最后class ParentClassWithoutFinal { private $value = "default"; public function __construct() { $this->value = static::class; } function __toString() { return $this->value; } } class ChildClassA extends ParentClassWithoutFinal { public function __construct() { // Missing parent::__construct(); } } echo (new ChildClassA()); // ouput: default

__construct

尝试在子类中声明class ParentClassWithFinal extends ParentClassWithoutFinal { public final function __construct() { parent::__construct(); } } class ChildClassB extends ParentClassWithFinal { } echo (new ChildClassB()); // output: ChildClassB

__construct

尝试在子类中声明class ChildClassC extends ParentClassWithFinal { public function __construct() { } } // Fatal error: Cannot override final method ParentClassWithFinal::__construct() 构造函数

ClassName()

答案 2 :(得分:-1)

在完成构造函数后,您无法将任何变量传递给初始化函数。它强制您的类的用户使用全局变量作为其子类的设置。

在Zend Framework中使用可覆盖的init()是常见的做法,但我从未见过在那里完成构造函数。

相关问题