Liskov Substitution Principle

🔗 SOLID Principles

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.