Is bad practice class declaration of "final" in PHP?

If I have a parent class that is extended by many and many other classes, and I want to make sure that the constructor of the parent class is ALWAYS started, is it a bad idea to declare a final constructor?

I was thinking of doing something like this:

 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>'; } } 

thus, the child class can have a constructor sort, and the constructor of the parent class will always execute. Is this a bad practice?

+7
constructor php class final
source share
3 answers

The final __construct declaration ensures that no one who extends your class can implement a method with the same name. At first glance, this seems like it does not mean that no one can declare a constructor for subclasses of this class, but this is not so, since the PHP 4 ClassName() style still works fine as an alternate name for the constructor. So, really, declaring a constructor as final gets nothing in PHP.

+9
source share

As in PHP 5.3.3, I tested this with 5.6 and 7.0, declaring that the __construct method of the final class would prevent any child class overriding the constructor, either using __construct or the PHP 4 style ClassName() (note that the PHP style 4 deprecated since PHP 7). Preventing the child class declaring the constructor ensures that the parent constructor is always called. This, of course, will not allow child classes to implement their own design logic. There will certainly be practical examples of use for this, although I would not recommend it as a good practice in general.

Some examples:

Without announcement __construct final

 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 

With the final __construct

 class ParentClassWithFinal extends ParentClassWithoutFinal { public final function __construct() { parent::__construct(); } } class ChildClassB extends ParentClassWithFinal { } echo (new ChildClassB()); // output: ChildClassB 

Trying to declare __construct in a child class

 class ChildClassC extends ParentClassWithFinal { public function __construct() { } } // Fatal error: Cannot override final method ParentClassWithFinal::__construct() 

Attempting to declare a ClassName() constructor in a child class

 class ChildClassD extends ParentClassWithFinal { public function ChildClassD() { } } // Fatal error: Cannot override final ParentClassWithFinal::__construct() with ChildClassD::ChildClassD() // Also in PHP 7: Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; ChildClassD has a deprecated constructor 
+3
source share

After completing the constructor creation, you cannot pass any variables to the initialization function. This forces users of your class to use global variables as settings for their child classes.

The Zend Framework uses overridable init () as usual, but I never saw the completion of the constructor there.

-one
source share

All Articles