1

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?

4 Answers 4

3

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.

Sign up to request clarification or add additional context in comments.

2 Comments

on other hands there's no possibility for classB to access to values of $property defined on classA. Isn't it?
@StefanoRadaelli Yes there is, if the property if public or protected or if there is a setter in ClassA to set a private property. However, the property is still specific for that instance of ClassB, it does not change anything in other objects of ClassA or ClassB.
1

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

Comments

1

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

1 Comment

Also you need to call SetA() somewhere in your class B instance to get [1] => ClassA.Set in your array.
1

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.

2 Comments

That's clear. But in this case ClassA->SetA() method cannot be called upon certain condition. My goal is to (#1) instanciate ClassA with some values from __construct, (#2) then call main.php -> ClassA->SetA() if "a certain condition is true" and (#3) then to allow to ClassB to get all the values of $property already set from ClassA.
Yes, you are right but can not go against rules. Also, we can not merge two instances into a single one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.