How does inheritance work with "Constructor Property Promotion" in PHP 8?

Asked

Viewed 104 times

2

PHP 8 now supports constructor Property Promotion to declare class properties in constructor arguments:

class Foo {
    public function __construct(
        public $foo,
    ){}
}

By making the inheritance by overwriting the constructor of this class and nay call the inherited class constructor like this:

class Bar extends Foo {
    public function __construct(
        public $bar,
    ){}
}

$obj = new Bar('valor');

As the builder of Foo was not called the property $obj->foo will still exist (regardless of the value)? Because the impression I have is that by not calling the builder there is no opportunity for the "property promotion" to happen.

  • 1

    yes, it will be at your disposal.

3 answers

3

The estate ->foo will be accessible, because each one belongs to one of them, however ->foo will have the value NULL, because simply overwriting a method within the "child method" will need to call the parent method (equivalent to the "super" of Java and Python), in PHP it is like this:

class Bar extends Foo {
    public function __construct(
        public $bar,
    ){
        parent::__construct($bar);
    }
}

Of course, if your wish is to pass the value of $bar for the parent method, if the goal is another then do so by pointing out the value you want:

class Bar extends Foo {
    public function __construct(
        public $bar,
    ){
        parent::__construct('qualquer outro valor');
    }
}

The point is that simply if the parent class has the need to always run the constructor for some reason of "setting" values, it will be necessary for the child class to do the necessary procedures with parent:: for the superscripted methods.

It is also worth remembering that if your goal is simply something like this:

    public function __construct(
        public $bar,
    ){
        parent::__construct($bar);
    }

Without the constructor doing anything else, it would just pass the value in the same order of parameters or "named parameters" equally, there is no reason to overwrite, just do this:

<?php

class Foo {
    public function __construct(
        public $foo,
    ){}
}

class Bar extends Foo {
}

$obj = new Bar('valor');

var_dump($obj->foo); // exibe "valor"

See that we passed the valor in class Bar() and was accessible in ->foo

2

I set up an environment with PHP 8 and performed some experiments and discovered the following.

Define the visibility (public, protected, private) of the arguments in the class constructor generates 2 results:

  1. A class property is created with the same argument name, whenever the class is created (even without calling the builder);
  2. The argument is assigned to the property, only on the call of the constructor.

To reach this conclusion I used only one class and created an instance using Reflection not to call the builder:

class Foo {
    public function __construct(
        public string $foo,
    ){}
}

$reflection = new ReflectionClass(Foo::class);
$obj = $reflection->newInstanceWithoutConstructor();
var_dump($obj);
/*
object(Foo)#2 (1) {
  ["foo"]=>
  NULL
}
*/

With this it is possible to state that a property defined through constructor Property Promotion does not depend on the call of the constructor and a property defined in a superscript constructor will always exist.

  • 1

    Recalling that the behavior of superscript has always existed, even before properties via argument, since the question of the problem of understanding is in what "is superscripted" and how it works.

-3

Browser other questions tagged

You are not signed in. Login or sign up in order to post.