Если я использую продвижение свойств конструктора, я могу вызвать конструктор автоматически. Мне не нужно писать parent::_constructor()
. Но дочерний класс может получить доступ к атрибуту Private. Эту ошибку можно устранить, просто не используя Propery Promotion. Я в чем-то ошибаюсь?
class Parent {
public function __construct(
protected $protected,
private $private
) {
}
}
class Child extends Parent {
public function __construct(
protected $protected,
private $private
) {
}
function myFunc() {
echo $this->private; // This works!!
}
}
Продвижение свойства конструктора означает просто «одновременное объявление свойства и аргумента конструктора». Это не меняет того, как работают наследование и частные свойства.
Ваш код эквивалентен этому:
class Parent {
protected $protected;
private $private;
public function __construct(
$protected,
$private
) {
$this->protected = $protected;
$this->private = $private;
}
}
class Child extends Parent {
protected $protected;
private $private;
public function __construct(
$protected,
$private
) {
$this->protected = $protected;
$this->private = $private;
}
function myFunc() {
echo $this->private; // This works!!
}
}
Дочерний класс никогда не затрагивает частное свойство родительского класса, он просто объявляет свое собственное частное свойство, имеющее то же имя. Если вы попытаетесь повторить $this->private
в методе, определенном в Parent
, вы обнаружите, что он не инициализирован: вы не запускали конструктор Parent
, поэтому в него ничего не записывалось.
Продвижение свойств конструктора — это всего лишь ярлык для объявления свойств и их назначения. Итак, Child
объявляет свои собственные свойства $protected
и $private
, которые переопределяют свойства, унаследованные от Parent
. Таким образом, Child::$private
является частным для класса Child
и к нему можно получить доступ из методов класса Child
.
Обратите внимание, что вам еще нужно вызвать Parent::__construct()
. Инициализация свойств Child
не инициализирует свойства Parent
с такими же именами. Если вы не вызовете его, методы Parent
, пытающиеся получить доступ к $this->private
или $this->protected
, получат ошибку для неопределенной переменной.
Дочерний элемент объявил собственное
$private
свойство, независимое от родительского. Так почему же это не должно сработать?