January 20, 2014
Liskov substitution principle
Definition: Objects in an application should be replaceable with instances of their subtypes without altering the correctness of that program.
To understand the Liskov principle is useful to understand the concepts of Contravariance and Covariance.
Contravariance is the conversion of a class from its sub class to a class higher up the hierarchy. An example is converting Rolls Royce to Car.
Covariance is the opposite conversion. It is converting from a class high up in the hierarchy to a more specific one. Using our above example, it is converting Car to Rolls Royce.
The requirements of class signatures to conform to the Liskov substitution principle are as follows:
- Methods of subtypes must be Contravariant. This means you should always be able to call methods on a base class or interface instead of the actual implementation and still get the same result.So calling ICar.Start() should be the same as calling RollsRoycle.Start() assuming RollsRoyce is an implementation of ICar at the time of calling.
- Return types should be Covariant.This allows you to pass an object out of a method as its more generic type such as ICar but still retain the reference to the more specific object and its implementation.
This principle is used in many design patterns such as the repository pattern and most notably in Test Driven Development where a class can be mocked by using its Interface and passed to a method so to remove concrete dependencies on that class.