PHP вызывает метод родителей внутреннего класса без расширения родительского

#php #class #parent #overloading

#php #класс #родительский #перегрузка

Вопрос:

возможно ли вызвать родительский метод в дочернем классе, который не распространяется на его родительский класс? У меня есть что-то вроде этого:

 <?php

class wrapper {

    private $inner;

    public function __construct() {
        $this->inner = new inner();
    }

    // this will never get called :(
    public function foo() {
        echo "foo called in parent";
    }

    public function bar() {
        return $this->inner->bar();
    }

    public function getOtherStuff() {
        return $this->inner->blafasel;
    }
}

class inner { // would only be created in class wrapper, never outside

    public $blafasel;

    public function __construct() {
        // do something
        $this->blafasel = "other stuff";
    }

    public function bar() {
        // do stuff
        echo "bar called in inner";

        $this->foo();  // fatal error, method not declared
        parent::foo(); // fatal error, class has no parent
        // ??
        return "something"
    }
}

$test      = new wrapper();
$something = $test->bar();

?>
  

пожалуйста, не спрашивайте, почему я не использую class inner extends wrapper . я должен использовать его так из-за старых вещей и других необходимых вещей. Так можно ли вызвать wrapper::foo без статичности? оболочка использует некоторые общедоступные переменные inner и прочее.
Я пытался добавить $this при вызове конструктора inner, но это приводит только к переполнению памяти или просто к отражению оболочки.
Итак, можно ли вызвать метод foo () обертки в inner’b bar() или мне нужно переписать все это, чтобы он мог использовать расширенные классы? Я знаю, что мне нужно его переписать, но это займет недели, и мне это нужно.. хорошо.. Вчера.

Спасибо за любую помощь / подсказки / исправления 🙂

Редактировать

Существует больше inner классов, которые будут вызываться в конструкторе оболочек, и все они имеют (вроде) одинаковые методы, но выполняют разные функции, зависит от самого внутреннего класса. (весь код слишком длинный, даже для pastebin)

некоторые фрагменты:

 class wrapper {
    public function __construct($loadclass=1) {
        if($loadstuff==1)
            $this->inner = new inner();
        else
            $this->inenr = new otherinner();
    }
}
  

и затем

 class otherinner {
    public function bar() {
        // doing different stuff than inner::bar()
        // but call wrappers foo() may with possible args
    }
}
  

я надеюсь, что это прояснит вопрос «почему не использовать extends»

Комментарии:

1. Ваш «Внутренний» класс не расширяет класс, поэтому что он наследует? Проверьте документацию, прежде чем спрашивать

2. Вы не ищете parent::foo() , поскольку оболочка не является родительской. На самом деле в вашем примере нет никакой связи между внутренним классом и классом-оболочкой. В этом случае вам нужно что-то внедрить, поэтому при вызове передавайте либо ссылку на содержащий объект (оболочку), либо на его метод inner::foo() . Но, честно говоря, это пахнет плохим дизайном.

3. Я не уверен, что здесь полезны черты php . Чтобы связать оба класса, вам нужно будет использовать либо extend или use .

4. @KyleThomas inner класс ничего не наследует, он может быть автономным, но никогда не будет вызываться как автономный в этом проекте.

5. @arkascha это точная проблема, между этими двумя классами нет связи, за исключением того, что wrapper знает что-то о inner, но внутри ничего о wrapper — уже пробовал вводить $this в конструктор, но безуспешно

Ответ №1:

 class Inner extends Wrapper {

    public function __construct() {
         parent::foo();
    }

}

new Inner();
  

Ваша текущая оболочка ожидает внедрения внутреннего объекта, эта оболочка теперь является частичным объектом, который внутренний завершит или расширит

Расширяя частичный класс, класс расширения наследует частичный класс. Без расширения нет «родительского».

Вы просто используете оболочку как внедрение зависимостей в свой код, а не как расширение.

Комментарии:

1. как я уже сказал, я знаю, как работают расширения, черты и пространства имен, но в этом случае не может быть расширенных классов, которые просто вызывают оболочку с n аргументами, и это разбивает беспорядок на собственные внутренние классы, для совместного использования идентичных функций я уже использую черты, и это работает идеально, но не «посторонние» функции

2. Вы просто ответили на свой собственный вопрос, это невозможно.. Чтобы наследовать методы класса, он должен быть частичным классом и расширенным. Вы используете внедрение зависимостей, поэтому вы не можете использовать ‘parent’, вы должны сделать каждый метод общедоступным и вызывать if с момента ($this-> inner-> bar(); или self::foo();) @UnskilledFreak

3. принят ваш ответ, потому что это так, как все должно быть сделано без «взлома». Спасибо!

4. Ну, вы могли бы использовать отражение или внедрение зависимостей только в этом случае, вы используете оболочку, а не контейнер, поэтому лучше всего расширить его функциональность.

5. Вы правы, но, например, отражения не делают код более читаемым. Расширение — лучшее решение для такого варианта использования.