更改父类设置的变量而不修改构造函数

时间:2015-05-03 20:38:06

标签: php oop

我几天来一直在寻找这个,但没有找到解决办法。

这是我的代码:

// Main class
class My_Parent {

    private $foo = '';

    // The constructor is set. Now all extended classes will get it.
    function __construct() {
        var_dump( $foo );
    }

    function set_val( $value ) {
        $this->foo = $value;
    }

}

// Extended class
class My_Child extends My_Parent {

    // Here's the problem. I've modified the constructor
    function __construct() {
        parent::set_val( 'bar' );
        parent::__construct(); // I don't want to call the parent costructor again
    }

}

new My_Child();

这只是工作正常,但不如我所料。我不想修改构造函数,所以我需要再次从父级调用它。这看起来很奇怪。我将为我的项目制作一个可扩展的框架。所以,这件事很烦人。

我确实想要这样的事情:

class My_Child extends My_Parent {

    // Just set the value somehow. do not modify the constructor
    $this::set_val( 'bar' );

}

new My_Child();

所以,我不必再次调用构造函数。但上面的代码会引发语法错误。

对此有何希望?

2 个答案:

答案 0 :(得分:0)

刚刚找到了一个棘手的解决方案。

首先,我设置了一个空函数,并在父类的构造函数中调用它。然后我通过扩展类中的该函数修改了变量。代码如下所示:

// Main class
class My_Parent {

    private $foo = '';

    // The constructor is set. Now all extended classes will get it.
    function __construct() {

        // We open the portal so that the value can change
        $this->portal();

        // Then we use the value as we want
        var_dump( $foo );

    }

    function set_val( $value ) {
        $this->foo = $value;
    }

    // This function will play the role of constructor of extended classes
    function portal() {
    }

}

// Extended class
class My_Child extends My_Parent {

    // We just use portal to set the value. Constructor is still untouched!
    function portal() {
        parent::set_val( 'bar' );
    }

}

new My_Child();

这完全符合我的要求。一切都在评论中解释。

答案 1 :(得分:0)

也许你过分思考这个问题。如果要使用常量值初始化属性,可以简单地将其声明为 protected 并在子类中覆盖它:

class MyParent {
    protected $foo = 'bar';

    // ...

    public function getFoo() {
        return $this->foo;
    }
}

class MyChild extends MyParent {
    protected $foo = 'baz';
}

echo (new MyParent())->getFoo(); // "bar"
echo (new MyChild())->getFoo(); // "baz"