Intereting Posts
Ошибка анализа: неожиданные двойные кавычки в массиве Не удалось запустить сервер разработки laravel на linux Почему я не могу использовать индекс массива для возвращаемого значения функции? Symfony 2.3: Как обновить аутентифицированный пользователь из базы данных? PHP-выпуск проблемы Функция PHP с открытым исходным кодом для преобразования координат UTM в широту и долготу? расшифровать зашифрованный текст as3crypto в PHP Как устранить неполадку пакета при попытке заставить композитора получить последние версии пакетов? php pagination, ограничение на страницу Простое рекурсивное дерево в PHP / MySQL У проблемы $ _REQUEST проблемы с безопасностью? Laravel 4 Создатель форм Пользовательские поля Макро Использовать данные сеанса по рукопожатию websocket PHP. Получайте данные из страницы Facebook, используя только графику facebook. Защищенный метод для хранения / получения секретного ключа PGP и кодовой фразы?

Вызов статического метода из класса B (который расширяет класс A) класса A

В практическом тесте был интересный вопрос, на который я не понял ответа. Каков результат следующего кода:

<?php class Foo { public $name = 'Andrew'; public function getName() { echo $this->name; } } class Bar extends Foo { public $name = 'John'; public function getName() { Foo::getName(); } } $a = new Bar; $a->getName(); ?> 

Первоначально я думал, что это вызвало ошибку, потому что статические методы не могут ссылаться на $ this (по крайней мере, на PHP5). Я испытал это сам, и на самом деле он выводит Джона.

Я добавил Foo :: getName (); в конце скрипта и получил ошибку, которую я ожидал. Итак, что изменяется, когда вы вызываете статический метод из класса, который расширяет класс, из которого вы звоните?

Кто-нибудь мог бы объяснить подробно, что здесь происходит?

$ this к объекту, в контексте которого был вызван метод. Итак: $ это $ a-> getName () – $ a. $ this в $ fooInstance-> getName () будет $ fooInstance. В случае, когда $ this задан (в вызове метода объекта $ a), и мы вызываем статический метод, $ this остается назначенным на $ a.

Похоже, довольно много путаницы может возникнуть из-за использования этой функции. 🙂

Foo :: getName () использует более старый PHP4-тип оператора разрешения области видимости, позволяющий вызывать переопределенный метод.

В PHP5 вы должны использовать parent :: getName () вместо

Это полезно, если вы хотите расширить, а не полностью переопределить поведение базового класса, например, это может сделать его более ясным

 class Bar extends Foo { public $name = 'John'; public function getName() { echo "My name is "; parent::getName(); } } 

Если вы вызываете статический метод, связанный с другим объектом, метод выполняется в контексте текущего объекта. Это позволяет получить доступ к $ this-объекту.

Лучшим способом вызова суперкласса-метода из подкласса будет:

 parent::getName(); 

Когда вы вызываете $a->getName() вы ссылаетесь на определенный объект, $a , который имеет класс Bar и поэтому возвращает «John».

Foo::getName() недействителен вне функции, потому что нет конкретного объекта.

Я не уверен, что он работает на PHP, но если вы (Foo)$a->getName() объект в суперкласс, как в (Foo)$a->getName() вы получите «Andrew» в качестве своего результата. Вы все равно будете говорить об определенном объекте ( $a ), но в этом случае типа Foo . ( Обратите внимание, что вы вообще не захотите этого делать )

Иногда программисты лучше разбираются в коде, чем на английском!

Первое, что происходит здесь, – это концепция перегрузки. Когда вы создаете экземпляр Bar, метод getName () перегружает метод с тем же именем в Foo.

Перегрузка является важной и важной частью OOD.

Однако часто бывает полезно вызвать версию метода, который существует в классе Parent (Foo).

Вот пример:

 class Dog { public function getTag() { return "I'm a dog."; } } class Skip extends dog { public function getTag() { return Dog::getTag() . " My name is Skip."; // I'm using Dog:: because it matches your example. However, you should use parent:: instead. } } $o = new Skip(); echo $o->getTag(); // Echo's: "I'm a dog. My name is Skip." 

Ясно, что это очень узкий пример, но он иллюстрирует точку.

Ваш базовый класс является наиболее общей реализацией типа. В этом случае это «Собака». Вы хотите поместить информацию в этот базовый класс, который является общим для всех экземпляров этого типа. Это предотвращает дублирование в каждом из классов Derived (например, «Skip»).

Ваш скрипт использует эту функцию, возможно, непреднамеренно.