On Sun, Aug 3, 2025, at 11:10, Rowan Tommins [IMSoP] wrote:
> On 2 August 2025 21:59:20 BST, Rob Landers <[email protected]> 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