Stefano Radaelli
Stefano Radaelli

Reputation: 1118

php: property inheritance on nested class structure

It's not clear to me how class inheritance is implemented in php 5.4.7 (almost old! I know!). Consider this example:

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";
    }
}

If I call in sequence

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

My expected behavior is to have...

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

...but I obtain instead...

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

So, what's wrong on my side? How can I add element from a Child to an array defined on Parent object?

Upvotes: 1

Views: 65

Answers (4)

Gufran Hasan
Gufran Hasan

Reputation: 9401

If you want to get the expected result then you need to change the code as per the PHP oops concept this will not work as you want.

You Updated Code

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);

Expected result:

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

When parent::__construct(); invokes then it maintains $property array variable for child class also.

Note: As we know OOPS concept, every object has a different instance.

Upvotes: 1

jeroen
jeroen

Reputation: 91792

You misunderstand how inheritance works in general: $classA is an instance of ClassA and has nothing to do with the instance $classB of ClassB you have generated.

An instance of ClassB inherits all public and protected properties and methods of ClassA but as long as you don't use them, you will not see them.

And all instances, whether from ClassA or from ClassB, are unrelated to each other, they only have the same "template" but each has its own property values.

Upvotes: 3

kitensei
kitensei

Reputation: 2530

In PHP, parent constructors aren't called automatically, to get your behaviour you need to do the following:

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

And, at most, you'll get this

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

as SetA() is never invoked

When you invoked the sequence you described, $classA and $classB are two different instances, so you will never get what you expect.

To get what you want, you need to do this:

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

Upvotes: 1

Nico Haase
Nico Haase

Reputation: 12130

That's really simple: why did you expect the parent constructor to run if you forgot to call it in ClassB? According to https://3v4l.org/keJ2a, this has not changed since PHP 5.0.0 and still works the same in recent PHP 7 versions

Upvotes: 1

Related Questions