Сначала я был смущен, почему оба метода звонят в конструкторе, но теперь я думаю, что понимаю. Расширяющиеся классы наследуют методы родителя, как если бы они были объявлены в самом классе, и методы существуют в родительском, поэтому оба должны работать.
Теперь мне интересно, есть ли предпочтительный способ (например, передовая практика) вызова метода (через parent
или this
) и независимо от того, действительно ли это идентичные способы выполнения одного и того же кода или если есть какие-либо оговорки при использовании один над другим.
Извините, я, наверное, подумал об этом.
abstract class Animal { function get_species() { echo "test"; } } class Dog extends Animal { function __construct(){ $this->get_species(); parent::get_species(); } } $spike = new Dog;
Есть три сценария (я могу придумать), где вы бы вызвали метод в подклассе, где метод выходит из родительского класса:
Метод не перезаписывается подклассом, существует только в родительском.
Это то же самое, что и ваш пример, и обычно лучше использовать $this -> get_species();
Вы правы, что в этом случае два фактически одинаковы, но этот метод был унаследован подклассом, поэтому нет причин дифференцироваться. Используя $this
вы остаетесь согласованным между унаследованными методами и локально объявленными методами.
Метод перезаписывается подклассом и имеет полностью уникальную логику от родителя.
В этом случае вы, очевидно, захотите использовать $this -> get_species();
потому что вы не хотите, чтобы версия родительского метода выполнялась. Опять же, последовательно используя $this
, вам не нужно беспокоиться о различии между этим случаем и первым.
Метод расширяет родительский класс, добавляя к тому, что достигает родительский метод.
В этом случае вы все равно хотите использовать `$this -> get_species();
при вызове метода из других методов подкласса. Одно место, которое вы вызовете родительским методом, будет из метода, который переписывает родительский метод. Пример:
abstract class Animal { function get_species() { echo "I am an animal."; } } class Dog extends Animal { function __construct(){ $this->get_species(); } function get_species(){ parent::get_species(); echo "More specifically, I am a dog."; } }
Единственный сценарий, который я могу себе представить, когда вам нужно будет вызвать родительский метод непосредственно за пределами метода переопределения, будет, если они сделали две разные вещи, и вы знали, что вам нужна версия родительского метода, а не локальная. Это не должно быть так, но если бы это было само собой, то простой способ приблизиться к этому заключался бы в создании нового метода с именем типа get_parentSpecies()
где все, что он делает, это вызвать родительский метод:
function get_parentSpecies(){ parent::get_species(); }
Опять же, это сохраняет все хорошее и последовательное, что позволяет изменять / изменять локальный метод, а не полагаться на родительский метод.
Если я не ошибаюсь в вопросе, я бы почти всегда использовал $ this-> get_species, потому что подкласс (в данном случае собака) мог бы перезаписать этот метод, так как он его расширяет. Если собака класса не переопределяет метод, то оба способа функционально эквивалентны, но если в какой-то момент в будущем вы решите, что хотите, чтобы метод get_species на собаке печатал «собаку», вам нужно было бы пройти через весь код и Измени это.
Когда вы используете $ this, это фактически часть объекта, который вы создали, и поэтому всегда будет самым последним (если используемое свойство каким-то образом изменилось в течение жизни объекта), тогда как использование родительского класса вызывает метод статического класса.