This was asked to me in an interview.
I answered him by saying that for same set of input both parent and child should produce same set of output. If child wants to extend parent's functionality it should do only on new inputs outside the range supported by parent. In that way, child will maintain the contract made by it's parent.
I gave him example, that an api may be using a parent like this
if(parent.getOutput(10) == 5){/*do something */}
If child produced a different output here then that child has broken the contract made by it's parent.
He wasn't satisfied with my answer and told me that this is simple overriding and is not a violation of LSP.
So, I just want to confirm, if i understand this correct.
No, this is not correct.
The point of the Liskov Substitution Principle is that a child class should be able to be used in the same manner as the parent class, according to relevant contracts. It does not need to produce identical output for identical input.
In the inevitable animal theme, here's an example where the methods return different outputs for the same input:
class Dog {
String getNoise() {
return "WOOF WOOF!!!"
}
}
class FrenchBulldog extends Dog {
String getNoise() {
return "mrfff!"
}
}
FrenchBulldog
can stand in for any Dog
in any context and behaves in the same manner, and it's therefore not a violation of the LSP.
If you instead create something like this:
class Hotdog extends Dog implements Edible {
String getNoise() {
throw new NotImplementedException("I am actually a sausage");
}
String eat() {
return "Delicious";
}
}
then it can no longer stand in for a Dog
. Code that works perfectly with Dog
s and FrenchBulldog
s no longer behaves the way it should. Any dog groomer or kennel knows what to do regardless of the noise the Dog makes, but will be very confused if you bring a Hotdog. This is a violation of LSP.