Добрый вечер! В общем, проблема состоит в том, что я, унаследовав класс, не могу обратиться к protected свойству родительского класса. Я уверен, что упустил какую-то мелочь, ночь уже. Код (Text): class First{ protected $_test; protected $_test2 = 'test2'; static $_instance; public static function getInstance(){ if (!(self::$_instance instanceof self)){ self::$_instance = new self(); } return self::$_instance; } private function __construct(){ $this->_test = 'test'; } public function test(){ return $this->_test; } } class Second extends First{ public function __construct(){} public function test(){ return $this->_test; } public function test2(){ return $this->_test2; } } $first = First::getInstance(); $second = new Second; var_dump($second->test()); //null var_dump($second->test2()); //test2 var_dump($first->test()); //test Почему при вызове $second->test() мне возвращается null, а не 'test'?
потому что у Second в классе свой конструктор. и там нет инициализации свойства $_test. Добавлено спустя 3 минуты 25 секунд: + приватные методы и свойства ненаследуются
В первом классе protected метод, он должен наследоваться и свойство $_test инициализируется при создание экземпляра первого класса, разве нет?
Ну, все правильно. В первом классе обычный синглтон, у которого конструктор не наследуется, но до него можно добраться через getInstnace(), и он срабатывает. Потому что в конструкторе первого классе написано, чтобы он присваивал $_test значение 'test'. Потом если я к этому свойству обращаюсь через экземпляр первого класса, оно вызывается, а если через экземпляр второго класса, то выводит null.
У тебя к $this->_test присваивается значение в конструкторе первого класса. А во втором классе ты конструктор похерил пустым. Соотв сюда ничего не вносится. Хочешь добраться до родительского свойства - используй обращение к свойствам родителя. Но это не $this будет.
Тогда почему, когда я обращаюсь к $second->test2(), оно вызывает свойство родительского класса? В методе test2 описан вызов return $this->_test2
Всё же элементарно: К private-членам (полям и методам) могут обратиться только методы того же класса (соответственно, конструктор First даже не доступен для вызова из Second) К protected-членам - методы класса и методы его наследников. Соответственно, поля First::$_test и First::_$test2 доступны для класса Second как обычно, через $this First::$_test2 у вас инициализирован при объявлении, поэтому он имеет значение для любого экземпляра First и Second, независимо от вызова конструктора First::$_test инициализируется в конструкторе First, который не вызывается для Second, да и не может быть вызван, поскольку он приватный, поэтому это поле для экземпляра Second остаётся пустым.