0

"Использование parent::parent в PHP: как это работает?"

12

Я ищу способ обратиться к методу родительского класса, не вызывая его напрямую. Это может звучать немного странно, поэтому приведу пример:

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 ответ(ов)

0

Возможно, вы можете просто добавить 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.

0

Нет, это невозможно. К сожалению, нет возможности ссылаться непосредственно на оригинальный класс, только на его self или на его parent.

0

Вы не можете создавать цепочки родителей. Вместо этого создайте метод типа GetParent() в ваших родительских классах, который просто будет возвращать $this.

0

Если вы хотите использовать функцию 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". Убедитесь, что вы правильно используете полиморфизм и доступ к родительским методам.

0

В 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".

Некоторые уточнения:

  1. self::getRoot() не будет работать так, как ожидается, потому что self:: ссылается на текущий класс, а не на класс родителя или предка. Вместо этого используйте $this->getRoot() для доступа к методу.
  2. В myclass2 добавлен метод test(), который также возвращает строку -level 2.

Таким образом, сохранив иерархию, мы можем корректно получить корневой объект и построить цепочку вызовов.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь