Liskov Substitution Principle
Child classes should never break the parent class’ type definitions.
The Liskov Substition Principle or LSP was introduced in 1987 in a keynote by Barbara Liskov. The technical description is:
Let q(x) be a property provable about objects x of type T. Then q(y) should be provable for objects y of type S where S is a subtype of T.
Or, simpler put by [[Robert C. Martin]]:
Subtypes must be substitutable for their base types.
This means that class A interacting with class B can interact with class C using the same code, if class C inherits from class B.
Code example
Let’s say we have the following classes:
classDiagram
Email <|-- PlainTextEmail
Email: +setSubject()
Email: +setBody()
Email: +setRecipient()
MailTransport <|-- SMTPMailTransport
MailTransport: +send()
If we now write code to send emails, these examples should all work:
$email = (new Email())
->setTransport(new MailTransport())
->send();
$email = (new PlainTextEmail())
->setTransport(new SMTPMailTransport())
->send();
I should be able to rely on PlainTextEmail behaving like Email in a way that doesn’t break contract.
Behavioral subtyping in PHP
There’s three types of behavioral subtyping in PHP, and they all pertain to LSP:
![[Behaviorial Subtyping in PHP#^sublinks]]
To summarize:
- Return types can be made narrower: Sub-classes can return sub-types or a smaller Union Types in the return type.
- Parameters can be widened: Sub-classes must accept and handle all parameter types the parent method handles. But it can be widened to accept more types or parent types.
- Property types cannot be changed.