Переопределение private в дочернем классе (PHP)

191
01 ноября 2018, 15:30

Не знаю, как точнее озаглавить проблему, но суть в следующем:
В родительском классе я описал три свойства с разными областями видимости (public, protected, private).
В дочернем классе я пытаюсь переопределить эти три свойства.
Затем, из дочернего класса я вызываю унаследованный метод, который выводит все три свойства.
На выходе я получаю измененные свойства public и protected, однако private выводит родительский.
Точно так же происходит, если вместо свойств использовать методы public protected private.

Однако, при переопределении метода (выводящего значения свойств) в дочернем классе, на выходе я получаю все три измененных свойства.

Почему при переопределении метода вывод правильный, а при его наследовании - нет?

<?php
class MyClass
{
    function Foo()
    {
        echo $this->public . " " . $this->protected . " " . $this->private;
    }
    public $public = "public";
    protected $protected = "protected";
    private $private = "private";
}
class NewClass extends MyClass {
    public $public = "New_public";
    protected $protected = "New_protected";
    private $private = "New_private";   
}
(new NewClass())->Foo(); //Выводит New_public New_Protected private
?>
Answer 1

Ну собсна вы и столкнулись с тем, зачем нужен private. Смысл в том что private - родителя не доступен для ребенка и наоборот.

Private может вызвать только сам класс, в котором он указан.

В вашем случае, если не трогать MyClass. А изменить NewClass на:

class NewClass extends MyClass {
    public $public = "New_public";
    protected $protected = "New_protected";
    //private $private = "New_private";
    function Foo() {
        echo $this->public . " " . $this->protected . " " . $this->private;
    }
}

Вы можете увидеть, что родительский private вы не получите. Однако убрав комментарии // с private вы его получите в ответе.

Дело в том что у них разные области видимости:

object(NewClass) {
    ["$public"]                     => "New_public"
    ["$protected":protected]        => "New_protected"
    ["$private":"NewClass":private] => "New_private"
    ["$private":"MyClass":private]  => "private"
}

Т.к. вы вызываете Foo() из родителя, в его области видимости отсутствует private $private = "New_private";, однако есть свой, поэтому и берет.

Если переопределить Foo() в ребенке, то теперь Foo() будет работать с областью видимости ребенка, и приватные методы родителя - будут недоступны.

Как-то так...

Answer 2

Наткнулся случайно на форум, где еще в 2015 году обсуждали этот вопрос. Здесь мне стало понятно, почему вообще приватное свойство наследуется и почему к нему можно обращаться.

https://php.ru/forum/threads/oop-nasledovanie-private-svojstv.51487/#post-411494

READ ALSO
Laravel PHP. Error 419

Laravel PHP. Error 419

На локалке одинаковые токены, а на хостинге другие, из-за этого ошибка 419Что делать?

161
Блокировка действий мыши с помощью хука

Блокировка действий мыши с помощью хука

Есть консольное приложение

174
Не менять цвет QPushButton при установке disabled

Не менять цвет QPushButton при установке disabled

Если кнопке QPushButton установить setDisabled(true) то текст\картинка установленная на поверхности кнопки обесцветитсяКак этого избежать?

222
Вопрос про Terminal blynk

Вопрос про Terminal blynk

Как бы реализовать запись с терминала в переменную?

226