开发者

Can I force a child class to use the parent's constructor?

开发者 https://www.devze.com 2023-01-23 18:52 出处:网络
I\'m learning PHP and found some surprising behaviour when I was trying to figure out why a constructor wasn\'t getting called.

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. 
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号