I'm learning PHP and found some surprising behaviour when I was trying to figure out why a constructor wasn't getting called.
<?php
class Shape {
function __construct() {
echo 'Shape.';
}
}
class Triangle extends Shape {
function __construct() {
echo 'Triangle';
}
}
$tri = new Triangle();
?>
I'm used to java, so I thought this would output "Shape. Triangle." Surprisingly, it just outputs "Triangle." I searched for the problem and apparently I can kinda sorta fix it by putting parent::__construct();
in the child class, but that doesn't seem ideal. Is there anything I can do to the Shape class to ensure that child classes always call the parent constructor? Do I really have to write parent::__const开发者_Go百科ruct();
in the class of every child whenever the parent has a constructor?
As of PHP 5, you can use the final keyword to prevent a parent method from being overridden.
<?php
class BaseClass {
public function test() {
echo "BaseClass::test() called\n";
}
final public function moreTesting() {
echo "BaseClass::moreTesting() called\n";
}
}
class ChildClass extends BaseClass {
public function moreTesting() {
echo "ChildClass::moreTesting() called\n";
}
}
// Results in Fatal error: Cannot override final method BaseClass::moreTesting()
You could use this in combination with a pre-defined init()
method to ensure your parent constructor was called.
<?php
abstract class Shape {
final function __construct() {
$this->init();
echo 'Shape.';
}
abstract public function init();
}
class Triangle extends Shape {
function init() {
echo 'Triangle';
}
}
$tri = new Triangle();
This would output
TriangleShape.
It is advisable to only use a design like this if you document what the init()
method does, and where it is called in the parent.
If you define a method of the same name in a child class, the parent's method is overridden and will not be called under any circumstances, unless you do so explicitly. I.e.: No, there's nothing you can do about it, you have to call parent::__construct()
explictly.
According to the PHP manual:
Parent constructors are not called implicitly if the child class defines
a constructor. In order to run a parent constructor, a call to
parent::__construct() within the child constructor is required.
精彩评论