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

Reply via email to