Re: Protected inheritance hierarchies
| From: | Rob Landers | Date: | Sun, 03 Aug 2025 09:30:13 +0000 |
| Subject: | Re: Protected inheritance hierarchies | ||
| References: | 1 2 3 4 5 6 7 8 9 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-128380@lists.php.net to get a copy of this message | ||
On Sun, Aug 3, 2025, at 11:10, Rowan Tommins [IMSoP] wrote:
> On 2 August 2025 21:59:20 BST, Rob Landers <rob@bottled.codes> wrote:
> >If this were the case, then creating a base class with default values wouldn’t be
> >possible. The memory exists and is set aside for that.
>
> Sure it would: the default value is just an assignment that happens at a particular point of
> the object's lifecycle. For a child class which overrides the default of a parent (on a public
> or protected property), only the child class's assignment will ever be visible. So it would be
> perfectly valid for the class entry for the child class to only store that one assignment. I
> don't know if that actually happens; maybe the cost of de-duplicating is not seen as
> worthwhile, and the assignments are just run in sequence every time.
>
> Regardless, the philosophical question in this thread seems to be whether re-declaring a
> protected property should change the "ownership" of that property. I think it's
> natural that a protected property *only* declared in a sibling class can't be accessed, so some
> ownership needs to be tracked.
>
> What seems surprising is that the ownership changes if the same property is re-declared,
> especially since the new declaration has to match the original (e.g. you can't change the
> type), and every possible access tells the user the two declarations have been completely merged.
>
> Intuitively, an identical declaration with no change other than a default value looks like it
> would be the same as overwriting the default in a constructor, but that is not the case.
> (https://3v4l.org/5iIak vs https://3v4l.org/rL8pX)
>
> I'm inclined to agree that this is a bug, regardless of whether it's difficult to fix
> in the implementation.
>
>
> Rowan Tommins
> [IMSoP]
>
I'm not sure that this is a bug. You can redeclare the same type and add hooks (or change
them), which breaks all assumptions about substitutability.
class A {
protected int $v = 2;
}
class B extends A {
public function getValue(A $v): void {
echo $v->v;
}
}
class C extends A {
protected int $v { set => $this->v * 2; }
}
$b = new B;
$c = new C;
$b->getValue($b);
$b->getValue($c);
C changes all assumptions from B's point of view (technically C is a violation of LSP from the
perspective of A, thus it should not pretend to be substitutable as A from the perspective of B when
used in this way -- though other properties/methods may in fact be substitutable and be useful).
— Rob