Вызов конструктора внутри метода - PullRequest
3 голосов
/ 03 марта 2011

Каким-то образом мой разум ушел далеко от текущей проблемы, и я совершил ужасную ошибку .. Я вызвал родительский конструктор внутри метода, который просто инициализирует свойства классов. Или я сделал это. Задачей родительского конструктора было установить значение идентификатора. Ну, PHP позволил мне сделать это. Но разве это не так? И, похоже, я могу вызывать собственный конструктор классов таким же образом ... Разве не так, что конструкторам разрешается вызывать только при создании экземпляров класса ... И они вызываются только при создании экземпляров ..

<?php

    class A {

        public function __construct() {
            echo "Test<br />";
        }

    }

    class B extends A {

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

    }

    $b = new B();
    $b->test();

    // OUTPUT:
    // Test
    // Test

?>

РЕДАКТИРОВАТЬ: Итак, вывод таков: PHP позволяет вам вызывать конструктор внутри метода, но на самом деле он ничего не делает. И эта другая строка «TEST» происходит из конструктора базового класса.

Ответы [ 4 ]

3 голосов
/ 03 марта 2011

Одно слово точно описывает ситуацию.

Переопределение

Что происходит, когда родитель имеет метод, такой как __construct, а дочерний класс делаетне имеет этого метода, когда метод вызывается в дочернем классе, он вызывает метод parent.

Например:

class Parent
{
     public function start(){}
}
class Child extends Parent
{

}

, если я вызываю метод start в классе Child, еговыполняет Parent::Start(), но если у класса Child есть метод с именем Start(), он будет вызываться как Overriding родительская версия.

Каждый класс имеет метод конструктора и phpвыполняет это для компиляции класса в объект, теперь, если у вас есть метод с именем __construct() в классе, PHP вызывает внутреннюю конструкцию, которая компилирует класс, а затем вызывает конструктор переопределения.

Если вы делаетене имеет __construct метода в дочернем классе PHP выполняет родительский __construct

Это причина, почему вы получаете 2 x Test в вашей инициализации объекта.

Единственный тиЕсли вы используете parent:__cosntruct(), если ваш дочерний класс требует определенного пользователем конструктора, вы явно вызываете родительскую конструкцию для подготовки родительского объекта.

Например:

class Parent
{
     public function __construct()
     {
         //Do work on Parent Class
     }
}

class Child extends Parent
{
    public function __construct()
    {
         //Do Work on Child Class

         parent::__construct();
    }
}

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

1 голос
/ 03 марта 2011

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

Если php допускает иное, то это просто артефакт того, как классы реализованы в языке, и не следует понимать, что это всегда полезно.

0 голосов
/ 03 марта 2011

Я бы предложил использовать метод init для обработки такого поведения.Вот пример:

class A {
    public function __construct() {
        $this->init();
    }
    protected function init() {
        echo "Test<br />";
    }
}

class B extends A {
    public function __construct() {
        // suppress parent constructor 
    }
    public function test() {
        $this->init();
    }
}
0 голосов
/ 03 марта 2011

Это не очень хорошая практика, и хорошо функционирующие языки ООП обычно не позволяют вам этого делать. Хотя это совершенно нормально, если вы точно знаете, что делаете. (И вы можете задокументировать, что другие программисты, работающие с этим кодом, понимают вашу концепцию).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...