如何在PHP中使用原始参数调用父类构造函数

5

我有这段代码:

class A {
  var $arr = array();

  function __construct($para) {
    echo 'Not called';
  }
}

class B extends A {
  function __construct() {
    $arr[] = 'new Item';
  }
}

由于B有自己的构造函数construct($para),所以A的构造函数construct($para)从未被调用。

现在我可以调用parent::__construct($para),但这样类B就需要知道类A需要哪些参数。

我更喜欢这种方式:

class A {
  var $arr = array();

  function __construct($para) {
    echo 'Not called';
  }
}

class B extends A {
  function __construct() {
    parent::__construct(); // With the parameters class B was created.

    // Additional actions that do not need direct access to the parameters
    $arr[] = 'new Item';
  }
}

这样的方案可行吗?

我不喜欢这个事实,即所有继承类A的类都需要定义一个新的构造函数,一旦类A更改其参数,而我希望他们像当类B没有使用自己的__construct()方法覆盖它时那样调用类A的构造函数。

2个回答

6

有一种方式可以几乎完全按照您最初描述的方式来实现,方法是使用call_user_func_array()func_get_args()函数:

class B extends A {
    function __construct() {
        // call the parent constructor with whatever parameters were provided
        call_user_func_array(array('parent', '__construct'), func_get_args());

        // Additional actions that do not need direct access to the parameters
        $arr[] = 'new Item';
    }
}

虽然这是一个有趣的练习,但我个人不建议实际使用它 - 我认为使用单独的init()方法是更好的设计。


我实际上更喜欢这种方法,而不是init()方法,因为它不会重新发明构造函数。 - Gordon
这绝对是个人喜好的问题。就我而言,我不喜欢看到包含方法名称的字符串——这有点像 eval,也是 PHP 的弱点之一,还有可变变量等。 - jcsanyi

5

一个解决方案是不要在第一次重写父类构造函数。相反,定义一个单独的(最初为空的)init()方法,该父类构造函数自动调用。然后可以在子类中重写该方法以执行额外的处理。

class A {
    public function __construct($para) {
        // parent processing using $para values

        // ..and then run any extra child initialization
        $this->init();
    }
    protected function init() {
    }
}

class B extends A {
    protected function init() {
        // Additional actions that do not need direct access to the parameters
    }
}

是的,那看起来就像我在寻找的东西。谢谢! - JochenJung
1
我在一个项目中广泛使用了这种方法,虽然它确实有效,但我从来没有太喜欢它,因为它有点重新发明构造函数。它会将您的对象转换为某种基本对象,这会妨碍重用。 - Gordon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接