The Liskov Substitution Principle (LSP) is a fundamental concept in object-oriented programming. It states that objects of a superclass should be replaceable with objects of a subclass without affecting the correctness of the program. In other words, subclasses should honor the contracts established by their parent classes.
Consider a base class Bird
with a method fly()
:
class Bird { void fly() { System.out.println("Flying"); } } class Sparrow extends Bird { @Override void fly() { System.out.println("Sparrow flying"); } }
Here, the Sparrow
class adheres to LSP because it behaves consistently with the base Bird
class.
Now, consider a Penguin
class:
class Penguin extends Bird { @Override void fly() { throw new UnsupportedOperationException("Penguins can't fly"); } }
This violates LSP because the subclass Penguin
does not adhere to the behavior expected from the Bird
class.
To resolve this, use a better abstraction that respects the different capabilities of subclasses:
interface Bird { void makeSound(); } interface FlyingBird extends Bird { void fly(); } class Sparrow implements FlyingBird { public void fly() { System.out.println("Sparrow flying"); } public void makeSound() { System.out.println("Chirp chirp"); } } class Penguin implements Bird { public void makeSound() { System.out.println("Honk honk"); } }
By adhering to the Liskov Substitution Principle, you ensure that your inheritance hierarchies are robust, predictable, and maintainable, leading to a more reliable software design.