php: наследование свойств на структуре вложенных классов - PullRequest
0 голосов
/ 14 ноября 2018

Мне не ясно, как наследование классов реализовано в php 5.4.7 (почти старый! Я знаю!). Рассмотрим этот пример:

Class ClassA {
    public $property = array();
    function __construct() {
        $this->property[] = "ClassA.construct";
    }
    public function SetA() {
        $this->property[] = "ClassA.Set";
    }
}

Class ClassB extends ClassA {
    function __construct() {
        $this->property[] = "ClassB.construct";
    }
    function SetB() {
        $this->property[] = "ClassB.Set";
    }
}

Если я позвоню по очереди

$classA = new ClassA();
$classA->SetA();
$classB = new ClassB();
$classB->SetB();
print_r($classB->property);

Мое ожидаемое поведение должно иметь ...

Array
(
    [0] => ClassA.construct
    [1] => ClassA.Set
    [2] => ClassB.construct
    [3] => ClassB.Set
)

... но я получаю вместо ...

Array
(
    [0] => ClassB.construct
    [1] => ClassB.Set
)

Так, что не так на моей стороне? Как добавить элемент из дочернего элемента в массив, определенный для родительского объекта?

Ответы [ 4 ]

0 голосов
/ 14 ноября 2018

Если вы хотите получить ожидаемый результат, вам нужно изменить код в соответствии с концепцией PHP oops, это не будет работать так, как вы хотите.

Вы обновили код

Class ClassA {
    public $property = array();
    function __construct() {
        $this->property[] = "ClassA.construct";
        $this->SetA();
    }
    public function SetA() {
        $this->property[] = "ClassA.Set";
    }
}

Class ClassB extends ClassA {
    function __construct() {

        parent::__construct();//invoke parent constructor       
        $this->property[] = "ClassB.construct";
    }
    function SetB() {
        $this->property[] = "ClassB.Set";
    }
}


$classB = new ClassB();
$classB->SetB();
print_r($classB->property);

Ожидаемый результат:

Array
(
    [0] => ClassA.construct
    [1] => ClassA.Set
    [2] => ClassB.construct
    [3] => ClassB.Set
)

При вызове parent::__construct(); сохраняется также $property переменная массива для дочернего класса.

Примечание: Как мы знаем концепцию OOPS, каждый объект имеет свой экземпляр.

0 голосов
/ 14 ноября 2018

Вы неправильно понимаете, как наследование работает вообще: $classA является экземпляром ClassA и не имеет ничего общего с сгенерированным вами экземпляром $classB из ClassB.

Экземпляр ClassB наследует все открытые и защищенные свойства и методы ClassA, но если вы их не используете, вы их не увидите.

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

0 голосов
/ 14 ноября 2018

В PHP родительские конструкторы не вызываются автоматически, чтобы получить ваше поведение, вам нужно сделать следующее:

Class ClassB extends ClassA {
    function __construct() {
        parent::__construct();
        $this->property[] = "ClassB.construct";
    }
    function SetB() {
        $this->property[] = "ClassB.Set";
    }
}

И, самое большее, вы получите это

Array
(
    [0] => ClassA.construct
    [2] => ClassB.construct
    [3] => ClassB.Set
)

как SetA() никогда не вызывается

Когда вы вызывали описанную вами последовательность, $classA и $classB - это два разных случая, поэтому вы никогда не получите того, что ожидаете.

Чтобы получить то, что вы хотите, вам нужно сделать следующее:

$classB = new ClassB();
$classB->SetB();
$classB->SetA();
print_r($classB->property);
0 голосов
/ 14 ноября 2018

Это действительно просто: почему вы ожидали запуска родительского конструктора, если забыли вызвать его в ClassB? Согласно https://3v4l.org/keJ2a, это не изменилось с PHP 5.0.0 и все еще работает в последних версиях PHP 7

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