在PHP中的构造函数中调用可覆盖的访问器和mutator方法是否可以接受

时间:2015-01-13 12:16:25

标签: php constructor

就构造函数而言,由于PHP中缺少访问器和更改器,我试图通过创建名为setX()和getX()的方法来模拟相同的功能:

<?php

class Example {
  protected $message; // Nullable

  public function setMessage (Message $message = NULL) {
    $this->message = $message;
  }

  public function getMessage () {
    return $this->message;
  }
}

?>

我已经读过使用构造函数设置属性应该与使用accessor和mutator方法设置属性相同。

但这会导致与构造函数有关的问题,因为我已经在许多位置读取了你不应该在构造函数中调用可覆盖的方法,因为在对象构造期间调用可覆盖的方法可能会导致使用未初始化数据,导致运行时异常或意外结果。

我的问题是,同样的规则是否适用,因为你不应该调用可重载的访问器和mutator方法,如下例所示:

<?php

class Example {
  protected $message; // Nullable

  public function __construct (Message $message = NULL) {
    $this->setMessage($message);
  }

  public function setMessage (Message $message = NULL) {
    $this->message = $message;
  }

  public function getMessage () {
    return $this->message;
  }
}

?>

我在哪里阅读此信息的来源包括:

3 个答案:

答案 0 :(得分:2)

是的,确实适用。只需将他们的一个示例移植到PHP,看看会发生什么:

<?php

class SuperClass {
  public function __construct() {
    $this->doLogic();
  }

  public function doLogic() {
    echo "This is superclass!";
  }
}

class SubClass extends SuperClass {
  private $color = null;

  public function __construct() {
    parent::__construct();
    $this->color = "Red";
  }

  public function doLogic() {
    echo "This is subclass! The color is: $this->color";
  }
}

$bc = new SuperClass();
$sc = new SubClass();

潜在解决方案

  1. 制作方法private,即不可覆盖的
  2. 制作方法final,即不可覆盖的
  3. parent::__construct作为子构造函数中的最后一个语句

答案 1 :(得分:0)

我认为这是可以接受的。

如果您无法将方法设置为final,则无法通过其他方式 我知道要防止这种情况发生。

我也是这样做的,如果有人决定延长课程,他有责任不打破它。

这肯定比将构造函数逻辑复制到构造函数更好。

答案 2 :(得分:0)

根据IonuţG。Stan所说的,这是不可接受的,应使用以下解决方案:

<?php

class SuperClass {
  private $_color;

  public function __construct (Color $color) {
    $this->_setColor($color);
  }

  private function _setColor (Color $color) {
    $this->_color = $color;
  }

  public function setColor (Color $color) {
    $this->_setColor($color);
    echo "This is superclass! The color is: $this->_color";
  }
}

class SubClass extends SuperClass {
  private $_color = null;

  public function setColor (Color $color) {
    parent::setColor($color);
    echo "This is subclass! The color is: $this->_color";
  }
}