On 8/7/25 12:38 AM, Hans Krentel wrote:
> > From a child class's perspective, the "public interface" is both
protected + public of the parent. If you change or misuse a parent's
implementation or invariants, it violates LSP, even if it doesn't affect
external clients immediately.
Ah okay, that part is not in my book, this explains to me why in your
example it violates substitutability for you, and with that thinking it
also prevents or degrades implementability for me so to say, as
otherwise I could not make use of visibility in classes - it would take
away that tool from me or I would not treat it well, potentially leading
to defects in the program.
Don't believe everything you read on the internet.
If you weren't allowed to change a parent's implementation, then you
wouldn't be permitted to override methods at all, at which point
inheritance is pointless.
It's funny that he's starting to talk about invariants here. Seems he
doesn't realize every example he's given so far is covariant (Besides
the one at the beginning of the thread where he confused static and
non-static properties)
He's trying to argue that LSP is about implementation when it's not.
This is an interface with a function signature:
interface I {
function f(): string;
}
See a fruit anywhere? Me neither. That's because there isn't one. It's
not part of the signature. It's not part of the interface. It's not part
of the definition. It's not part of the contract.
This is a class with _the same function signature_:
class C {
function f(): string {
return "fruit";
}
}
In fact, this class could implement that interface without any problems,
because the signature is identical. The types are identical. There is no
LSP violation. There is also no contract that implies C::f() returns
"fruit".
If you made that assumption I'd call it a lack of error handling from
someone who only considered the happy path. Static analysis tools exist
to stop you from making these mistakes.
Once more, just to drive the point home. This is an interface with a
function signature:
interface I {
public int $p { get; }
}
This is a class with the same function signature (And one more for good
measure, because I::$p is covariant!):
class C {
public int $p;
}
In fact, this class could implement that interface without any problems,
because the signature is identical. The types are identical. There is no
LSP violation. There is no contract that implies that getting C->p will
return a certain value, other than that the value will be an int.
---
Back to the original issue: I'm going to open a github issue on this
since it's clearly a bug and I don't see fixing it breaking any existing
code.