Solid Design. liskov substitution principal explained with examples in java principles software development understanding