How does LSP interact with covariance and contravariance in type systems?
Answer
LSP has precise implications for how type parameters behave in subtyping relationships, expressed through variance. Covariance (safe for return types): if Cat is a subtype of Animal, a method returning Cat in a subclass is an acceptable override of one returning Animal — the postcondition is strengthened (more specific), not weakened. Contravariance (safe for parameter types): a method accepting Animal as parameter in a subclass is an acceptable override of one accepting Cat — the precondition is weakened (more permissive). Invariance: mutable generic containers (e.g., List<Cat>) cannot be treated as List<Animal> because you could add a Dog to what's actually a list of cats. TypeScript's structural typing with strict function parameter checking, Kotlin's in/out keywords, and Java's wildcards (? extends T, ? super T) are all implementations of variance rules derived from LSP requirements.
Previous
What is the relationship between SOLID and Clean Architecture?
Next
How do SOLID principles apply to event-driven architectures?
More SOLID Principles Questions
View all →- Advanced How do SOLID principles apply to domain-driven design?
- Advanced How do you balance SOLID principles with pragmatic software development?
- Advanced How does the Hexagonal Architecture (Ports and Adapters) apply DIP?
- Advanced What is the relationship between SOLID and Clean Architecture?
- Advanced How do SOLID principles apply to event-driven architectures?