top of page
Programming Console

L Is for Liskov, and Also for Lies We Tell Ourselves About Inheritance

  • Writer: Maryanne
    Maryanne
  • Apr 26
  • 3 min read

Updated: May 4

Because extending a class shouldn't feel like you're defusing a bomb.



The Liskov Substitution Principle (LSP) is the “L” in SOLID, but it might as well stand for “Look, this seems fine… until runtime.” If you’ve ever inherited from a class only to spend the next two weeks duct-taping behavior back together, you’ve danced with the devil that is LSP.

So what is the Liskov Substitution Principle, really? And why do so many otherwise competent developers blow right past it like it’s an optional stop sign?


LSP in Human Terms

Barbara Liskov coined this gem back in 1987. The formal definition goes something like:

“If S is a subtype of T, then objects of type T may be replaced with objects of type S without altering any of the desirable properties of that program.”

In plain English: if your subclass can’t be used exactly like the parent class without something breaking, your design has issues. And if you’re thinking, “Yeah, but I only overrode a couple of methods,” congrats, you might be the problem.


The Most Common (and Painful) Violations


1. Throwing Exceptions Where None Existed Before

Let’s say your base class method never throws exceptions, but your subclass adds new ones. Suddenly, the calling code that expected smooth sailing is on fire. Not cool.

2. Changing Behavior Instead of Extending It

A method that used to return a sorted list now returns an unsorted one. Or a method that worked asynchronously now blocks. You've technically extended the class, but semantically, you’ve rewritten the rules.

3. Ignoring Preconditions and Postconditions

If the base class method accepts a broad range of inputs and your subclass narrows that range—say, refusing nulls that the parent accepted—you’ve broken the contract.

4. Side Effects Galore

If your subclass starts logging, calling external services, or doing anything unexpected, you're turning reliable code into a chaotic mess.


Why Do We Keep Breaking LSP?

Because inheritance is deceptively easy. It feels like plug-and-play until it’s not.

Also, IDEs make subclassing look so tempting. Right-click > "Inherit" > boom, new class. What they don’t tell you is that every override you write is a potential landmine. Especially in large legacy codebases where one tiny change ripples into a tidal wave of regressions.

Let’s be honest how many times have you tested your subclass independently, but not in the full context of where the base class is used? Exactly.


The Real Fix: Favor Composition Over Inheritance

If you’ve heard this before and rolled your eyes, hear me out.

Composition forces you to define behavior explicitly. Instead of subclassing and overriding willy-nilly, you inject dependencies and behaviors. You think harder about what you’re building instead of assuming “It’ll just work because it compiles.”

In .NET? Use interfaces and strategy patterns to separate behavior from hierarchy. Composition works beautifully in C# when you give it a chance.


Practical Tips to Not Break LSP in Your Codebase

1. Don’t Inherit Unless You Have To

Is-a relationships are rare. Use-a or has-a relationships are often more accurate.

2. Write Contract Tests for Subclasses

Yes, seriously. If you’re going to subclass something, create tests that verify it behaves identically to the base class under the same conditions.

3. Watch for Code Smells

If your subclass is overriding more than a couple methods, that’s a red flag. You might be better off refactoring the base class or extracting interfaces.

4. Teach Your Team

Make LSP a thing in your code reviews. Don’t just ask “Does this work?” Ask, “Would this still work if I swapped in the base class?”


LSP isn’t just an academic concern—it’s a silent killer of maintainability. You may not see the damage the day you write the code, but future you (or worse, your team) will feel it.

Design your classes like they’ll be inherited by someone who doesn’t know your assumptions. Because someday, they will be.

 
 
 

Comentários


bottom of page