"Использование parent::parent в PHP: как это работает?"
Я ищу способ обратиться к методу родительского класса, не вызывая его напрямую. Это может звучать немного странно, поэтому приведу пример:
class myclass
{
public function test() { return 'level 1'; }
}
class myclass2 extends myclass
{
public function test() { return parent::test() . '-level 2'; }
}
class myclass3 extends myclass2
{
public function test() { return parent::test() . '-level 3'; }
}
$example = new myclass3();
echo $example->test(); // должно вывести "level 1-level 2-level 3"
Я хотел бы, чтобы выводилось "level 1-level 3", при этом нужно реализовать что-то вроде следующего:
class myclass3 extends myclass2
{
public function test() { return parent::parent::test() . '-level 3'; }
}
Есть ли у вас идеи, как я могу это сделать? Я не могу редактировать myclass
и myclass2
, так как они являются частью фреймворка...
5 ответ(ов)
Возможно, вы можете просто добавить myclass2
в качестве объекта-члена в myclass3
и попробовать написать код следующим образом:
class myclass3 {
myclass2 $obj2; // Обратите внимание на тип объекта
public function __construct() {
$this->obj2 = new myclass2(); // Инициализация объекта myclass2
}
public function test() {
return $this->obj2->callParentTest() . '-level3'; // Вызов метода из myclass2
}
}
Таким образом, myclass3
будет иметь доступ к методам myclass2
через переменную $obj2
. Не забудьте инициализировать объект myclass2
в конструкторе myclass3
.
Нет, это невозможно. К сожалению, нет возможности ссылаться непосредственно на оригинальный класс, только на его self
или на его parent
.
Вы не можете создавать цепочки родителей. Вместо этого создайте метод типа GetParent() в ваших родительских классах, который просто будет возвращать $this.
Если вы хотите использовать функцию test непосредственно в myclass
, вы должны расширить myclass
. Пожалуйста, ознакомьтесь с понятием полиморфизма.
Вы пробовали использовать parent::parent::parent::parent
для доступа к родительскому классу, когда у вас есть myclass3
?
Я думаю, вам стоит добавить параметр level
в метод test
и сначала проверить его.
Вот пример кода:
<?php
class myclass
{
public function test($level)
{
return 'level 1';
}
}
class myclass2 extends myclass
{
public function test($level)
{
return $level >= 2 ? parent::test($level) . '-level 2' : parent::test($level);
}
}
class myclass3 extends myclass2
{
public function test()
{
return parent::test(1) . '-level 3';
}
}
$example = new myclass3();
echo $example->test(); // должно вывести "level 1-level 3"
В данном примере метод test
в myclass3
вызывает метод test
родительского класса (myclass2
), передавая значение 1, в результате чего выводится "level 1-level 3". Убедитесь, что вы правильно используете полиморфизм и доступ к родительским методам.
В PHP нет оператора, который позволял бы получить корневой объект, но вы можете реализовать это с помощью методов классов. В приведенном вами коде, однако, есть небольшая ошибка, которая не позволит достичь ожидаемого результата.
Вот исправленная версия вашего кода:
class myclass
{
public function getRoot() { return __CLASS__; }
public function test() { return 'level 1'; }
}
class myclass2 extends myclass
{
public function getRoot() { return parent::getRoot(); }
public function test() { return parent::test() . '-level 2'; }
}
class myclass3 extends myclass2
{
public function getRoot() { return parent::getRoot(); }
public function test() {
$grandparent = $this->getRoot();
return $grandparent::test() . '-level 3';
}
}
$example = new myclass3();
echo $example->test(); // должен вернуть "level 1-level 2-level 3"
Теперь приведенный код корректно выводит результат "level 1-level 2-level 3"
.
Некоторые уточнения:
self::getRoot()
не будет работать так, как ожидается, потому чтоself::
ссылается на текущий класс, а не на класс родителя или предка. Вместо этого используйте$this->getRoot()
для доступа к методу.- В
myclass2
добавлен методtest()
, который также возвращает строку-level 2
.
Таким образом, сохранив иерархию, мы можем корректно получить корневой объект и построить цепочку вызовов.
Когда использовать 'self' вместо '$this'?
Разница между public, private и protected в ООП
Как должна быть структурирована модель в MVC? [закрыто]
Какова цель конструкторов и деструкторов в PHP?
Почему нельзя вызывать абстрактные функции из абстрактных классов в PHP?