С точки зрения конструкторов, из-за отсутствия в PHP аксессоров и мутаторов, я пытаюсь эмулировать ту же функциональность, создавая методы с именами setX () и getX (), например так:
<?php
class Example {
protected $message; // Nullable
public function setMessage (Message $message = NULL) {
$this->message = $message;
}
public function getMessage () {
return $this->message;
}
}
?>
Я читал, что установка свойств с помощью конструктора должна совпадать с настройкой свойств с помощью методов доступа и мутатора.
Но это приводит к проблеме в отношении конструкторов, поскольку я прочитал в ряде мест, что вы не должны вызывать переопределяемые методы внутри конструктора, потому что вызов переопределяемого метода во время конструирования объекта может привести к использованию неинициализированных данных, что приводит к исключения во время выполнения или непредвиденные результаты.
Мой вопрос заключается в том, применимо ли то же правило в том, что вы не должны вызывать перегружаемые методы доступа и мутатора, как показано в следующем примере:
<?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;
}
}
?>
Мои источники, где я прочитал эту информацию, включают:
Да, это действительно так. Просто перенесите один из их примеров в 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();
private
то есть не переопределяемыйfinal
то есть не переопределяемыйparent::__construct
как последнее утверждение в дочернем конструктореЯ думаю, что это приемлемо.
Когда вы не можете / не хотите установить метод final
другого пути просто нет
что я знаю, чтобы предотвратить это.
Я также делаю это, и если кто-то решает продлить класс, его обязанность не сломать его.
Это, безусловно, лучше, чем дублирование логики сеттера в вашем конструкторе.
Исходя из того, что сказал 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";
}
}