我可以强制子类使用父类的构造函数吗?

Pla*_*ane 8 php inheritance constructor

我正在学习PHP并且在我试图弄清楚为什么没有调用构造函数时发现了一些令人惊讶的行为.

<?php
    class Shape {

        function __construct() { 
            echo 'Shape.';
        }
    }

    class Triangle extends Shape {

        function __construct() {        
            echo 'Triangle';
        }
    }

    $tri = new Triangle();
?>
Run Code Online (Sandbox Code Playgroud)

我习惯了java,所以我认为这会输出"Shape.Triangle".令人惊讶的是,它只输出"三角形".我搜索了这个问题,显然我可以通过parent::__construct();加入子类来解决这个问题,但这似乎并不理想.我可以对Shape类做些什么来确保子类总是调用父构造函数吗?parent::__construct();只要父母有一个构造函数,我真的必须在每个孩子的班级写作吗?

dec*_*eze 11

如果在子类中定义了同名的方法,则会覆盖父方法,并且在任何情况下都不会调用父方法,除非您明确地这样做.即:不,你无能为力,你必须parent::__construct()明确地打电话.


Mir*_*ate 10

从PHP 5开始,您可以使用final关键字来防止覆盖父方法.

<?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()
Run Code Online (Sandbox Code Playgroud)

您可以将此与预定义init()方法结合使用,以确保调用父构造函数.

<?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();
Run Code Online (Sandbox Code Playgroud)

这会输出

TriangleShape.
Run Code Online (Sandbox Code Playgroud)

如果您记录init()方法的作用以及在父级中调用它的位置,建议仅使用这样的设计.