1

See the comment inside ChildEntity ::__construct():

class ChildEntity extends ParentEntity
{
    /** @var int */
    protected $classParameter;

    function __construct(int $classParameter)
    {
        /**
         * Question
         *
         * Below are the two ways of initializing the variable of ChildEntity
         *
         * Are they both initializing the same child(?) variable?
         * Are they initializing the parent(?) variable?
         * Can the child and parent have different values at the same time,
         * perhaps in different contexts?
         */
        $this->classParameter = $classParameter; // init local(?) variable?
        parent::__construct($classParameter); // init parent(?) variable?
    }
}

class ParentEntity
{
    /** @var int */
    protected $classParameter;

    function __construct(int $classParameter)
    {
        $this->classParameter = $classParameter;
    }
}

$childEntity = new ChildEntity(100);

Why does the below work (slightly different code - parameter removed in parent, and child uses only parent constructor to initialize). It looks like the parent class manipulates a variable found in the child class, without that variable being present in parent. It is as if the variable in ChildEntity and ParentEntity become one, and the child and parent instances also serve as a single instance, for all intents and purposes. Is that what actually happens behind the scenes?

class ChildEntity extends ParentEntity
{
    /** @var int */
    protected $classParameter;

    function __construct(int $classParameter)
    {
        parent::__construct($classParameter); 
        print $this->classParameter;
    }
}

class ParentEntity
{
    function __construct(int $classParameter)
    {
        $this->classParameter = $classParameter;
    }
}

$childEntity = new ChildEntity(5);

closed as off-topic by Greg Burghardt, gnat, 8bittree, Laiv, TheCatWhisperer Feb 5 '18 at 0:49

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions asking for assistance in explaining, writing or debugging code are off-topic here. These can be asked on Stack Overflow if they include the desired behavior, a specific problem or error, and the shortest code necessary to reproduce it in the question (see Minimal, Complete, and Verifiable Example)." – Greg Burghardt, gnat, 8bittree, Laiv, TheCatWhisperer
If this question can be reworded to fit the rules in the help center, please edit the question.

4

Are they both initializing the same child(?) variable?

When the object is created, all the non-private properties of all parent classes belong to this newly created object. He doesn't know which properties belong to class it was created with, and which ones belong to a parent one.

Can the child and parent have different values at the same time, perhaps in different contexts?

Only if you create two different objects, like that (I added a getter method):

$childEntity = new ChildEntity(5);
var_dump($childEntity->getClassParameter());

$parentEntity = new ParentEntity(6);
var_dump($parentEntity->getClassParameter());

Why does the below work?

When you write the following code:

class ParentEntity
{
    function __construct(int $classParameter)
    {
        $this->classParameter = $classParameter;
    }
}

that is, you initialize a property in a constructor without declaring it, php internally declares it itself. And when you create a ChildEntity, everything happens exactly the same as I already described. I should mention that php assigns this undeclared property a public visibility -- despite of, however crazy, it contradicts Liskov Substitution Principle. Check it out:

class ChildEntity extends ParentEntity
{
    /** @var int */
    protected $classParameter;

    function __construct(int $classParameter)
    {
        parent::__construct($classParameter);
        var_dump($this->classParameter);
    }

    public function getClassParameter()
    {
        return $this->classParameter;
    }
}

class ParentEntity
{
    function __construct(int $classParameter)
    {
        $this->classParameter = $classParameter;
    }
}

$parentEntity = new ParentEntity(6);
var_dump($parentEntity->classParameter);

$childEntity = new ChildEntity(5);
var_dump($childEntity->classParameter); // oops, an error!
  • hmm so there is a way to trick PHP into breaking LSP ..... – Dennis Jan 16 '18 at 22:13
  • @Zapadlo That's a bad breach of LSP, wasn't aware of this one until now, thanks – e_i_pi Jan 17 '18 at 0:33
  • php is full of surprises :) – Zapadlo Jan 17 '18 at 6:03
  • @Dennis just in case, there is an Accept answer check mark :) – Zapadlo Jan 17 '18 at 13:37

Not the answer you're looking for? Browse other questions tagged or ask your own question.