{"id":414,"date":"2026-07-02T12:51:58","date_gmt":"2026-07-02T12:51:58","guid":{"rendered":"https:\/\/patryk-sobilo.profesjonalnyprogramista.pl\/?p=414"},"modified":"2026-07-02T12:52:52","modified_gmt":"2026-07-02T12:52:52","slug":"liskov-substitution-principle","status":"publish","type":"post","link":"https:\/\/patryk-sobilo.profesjonalnyprogramista.pl\/index.php\/2026\/07\/02\/liskov-substitution-principle\/","title":{"rendered":"Liskov Substitution Principle"},"content":{"rendered":"\n<h4 class=\"wp-block-heading\">A Subclass Must Be a Replaceable Substitute for Its Base Class<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>Liskov Substitution Principle (LSP)<\/strong> states that objects of a derived class should be able to replace objects of the base class without affecting the correctness of the program.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Simply put:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>If class B inherits from class A, then anywhere we use A, we should be able to use B and the program should continue to work correctly.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This principle is not only about method signatures but, more importantly, about behavior. A derived class must not change the expected semantics of methods inherited from the base class.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Real-Life Example: How to Understand It?<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine a car rental company.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A customer walks in and says:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">&#8220;I&#8217;d like to rent a car.&#8221;<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">The rental company hands over the keys and points to a vehicle in the parking lot.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The customer assumes that the car will:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>start when the key is turned,<\/li>\n\n\n\n<li>stop when the brake pedal is pressed,<\/li>\n\n\n\n<li>move when the accelerator is pressed.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Now imagine the rental company gives the customer a vehicle with the engine removed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It still looks like a car. It has a key, a steering wheel, and pedals. However, when the key is turned, nothing happens.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Is it still a &#8220;car&#8221; according to the agreement with the customer?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Technically, yes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Practically, absolutely not.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The customer has every right to expect that every vehicle provided by the rental company behaves like a car. The rental company violated that expectation by supplying an object that looks like a car but does not behave like one.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Programming works exactly the same way.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If we have a <code>Car<\/code> class with a <code>start()<\/code> method and create a subclass <code>CarWithoutEngine<\/code> that overrides the method and throws an exception, we violate LSP.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Any piece of code that expects a <code>Car<\/code> receives an object that does not fulfill the contract.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">A Thought Experiment<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Consider the classic programming example of a rectangle and a square.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At first glance, a square is a rectangle (every square is a rectangle).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But should a <code>Square<\/code> class inherit from a <code>Rectangle<\/code> class in code?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s see where things break down.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Example \u2014 LSP Violation<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose we are building a system for calculating the areas of geometric shapes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We start with a rectangle:<\/p>\n\n\n<pre style=\"padding-left: 80px;\"><!--ScriptorStartFragment--><\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\/\/ Base class: Rectangle with independent dimensions<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">class Rectangle {<\/div>\n<pre style=\"padding-left: 80px;\">\u00a0<\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 protected int width;<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 protected int height;<\/div>\n<pre style=\"padding-left: 80px;\">\u00a0<\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 public void setWidth(int width) {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.width = width;<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 }<\/div>\n<pre style=\"padding-left: 80px;\">\u00a0<\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 public void setHeight(int height) {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.height = height;<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 }<\/div>\n<pre style=\"padding-left: 80px;\">\u00a0<\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 public int calculateArea() {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return width * height;<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 }<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">}<!--ScriptorEndFragment--><\/div>\n\n\n<p class=\"wp-block-paragraph\">Mathematically, a square is a special type of rectangle, so we inherit from it:<\/p>\n\n\n<pre style=\"padding-left: 80px;\"><!--ScriptorStartFragment--><\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\/ Square inherits from Rectangle &#8211; seems logical at first<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">class Square extends Rectangle {<\/div>\n<pre style=\"padding-left: 80px;\">\u00a0<\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 \/\/ A square must have equal sides,<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 \/\/ so we override the setters<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 @Override<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 public void setWidth(int width) {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Set BOTH dimensions to preserve square properties<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.width = width;<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.height = width; \/\/ \u2190 problem starts here<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 }<\/div>\n<pre style=\"padding-left: 80px;\">\u00a0<\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 @Override<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 public void setHeight(int height) {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Both dimensions must remain equal<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.width = height; \/\/ \u2190 silently changes another field<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.height = height;<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 }<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">}<!--ScriptorEndFragment--><\/div>\n\n\n<p class=\"wp-block-paragraph\">Now let&#8217;s write a method that operates on a <code>Rectangle<\/code> and see what happens when we pass a <code>Square<\/code>.<\/p>\n\n\n<pre style=\"padding-left: 80px;\"><!--ScriptorStartFragment--><\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\/\/ According to LSP, a method expecting Rectangle<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\/\/ should also work with Square<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">public static void testArea(Rectangle r) {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 r.setWidth(5);<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 r.setHeight(3);<\/div>\n<pre style=\"padding-left: 80px;\">\u00a0<\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 \/\/ Expected: 5 * 3 = 15<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 int expected = 15;<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 int actual = r.calculateArea();<\/div>\n<pre style=\"padding-left: 80px;\">\u00a0<\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 System.out.println(&#8220;Expected: &#8221; + expected);<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 System.out.println(&#8220;Actual: &#8221; + actual);<\/div>\n<pre style=\"padding-left: 80px;\">\u00a0<\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 \/\/ Rectangle: prints 15\u00a0<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 \/\/ Square:\u00a0\u00a0\u00a0 prints 9\u00a0\u00a0<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">}<!--ScriptorEndFragment--><\/div>\n\n\n<p class=\"wp-block-paragraph\">Following:<\/p>\n\n\n<pre style=\"padding-left: 80px;\"><!--ScriptorStartFragment--><\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">public static void main(String[] args) {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 testArea(new Rectangle()); \/\/ works correctly<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 testArea(new Square());\u00a0\u00a0\u00a0 \/\/ incorrect result, LSP violated<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">}<!--ScriptorEndFragment--><\/div>\n\n\n<h5 class=\"wp-block-heading\">What&#8217;s Wrong with This Approach?<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">The derived class changes the behavior of base-class methods.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the <code>Rectangle<\/code> class, <code>setWidth()<\/code> changes only the width.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the <code>Square<\/code> class, the same method also changes the height, without the caller&#8217;s knowledge.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Code that trusted the contract of the base class no longer works correctly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>testArea()<\/code> method does not know that it received a <code>Square<\/code>, and it should not need to know.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That is the essence of an LSP violation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The inheritance hierarchy reflects a <strong>mathematical relationship<\/strong>, not a <strong>programming relationship<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In geometry, a square is a rectangle.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In object-oriented programming, that is not necessarily true if their behavior differs.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Example \u2014 LSP-Compliant Design<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Instead of forcing a square into a rectangle hierarchy, we extract a shared abstraction representing what both shapes truly have in common: the ability to calculate an area.<\/p>\n\n\n<pre style=\"padding-left: 80px;\"><!--ScriptorStartFragment--><\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\/ Common abstraction<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">abstract class Shape {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 public abstract int calculateArea();<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">}<!--ScriptorEndFragment--><\/div>\n\n\n<p class=\"wp-block-paragraph\">Then:<\/p>\n\n\n<pre style=\"padding-left: 80px;\"><!--ScriptorStartFragment--><br \/><br \/>\/\/ Rectangle - independent dimensions<br \/><br \/>class Rectangle extends Shape {<br \/><br \/><br class=\"scriptor-paragraph\" \/><br \/><br \/>\u00a0\u00a0\u00a0 private int width;<br \/><br \/>\u00a0\u00a0\u00a0 private int height;<br \/><br \/><br class=\"scriptor-paragraph\" \/><br \/><br \/>\u00a0\u00a0\u00a0 public Rectangle(int width, int height) {<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.width = width;<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.height = height;<br \/><br \/>\u00a0\u00a0\u00a0 }<br \/><br \/><br class=\"scriptor-paragraph\" \/><br \/><br \/>\u00a0\u00a0\u00a0 @Override<br \/><br \/>\u00a0\u00a0\u00a0 public int calculateArea() {<br \/><br \/>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return width * height;<br \/><br \/>\u00a0\u00a0\u00a0 }<br \/><br \/>}<!--ScriptorEndFragment--><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Add a class type:<\/p>\n\n\n<pre style=\"padding-left: 80px;\"><!--ScriptorStartFragment--><\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\/ Square &#8211; one side, its own logic<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">class Square extends Shape {<\/div>\n<pre style=\"padding-left: 80px;\">\u00a0<\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 private int side;<\/div>\n<pre style=\"padding-left: 80px;\">\u00a0<\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 public Square(int side) {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 this.side = side;<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 }<\/div>\n<pre style=\"padding-left: 80px;\">\u00a0<\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 @Override<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 public int calculateArea() {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return side * side;<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 }<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">}<!--ScriptorEndFragment--><\/div>\n\n\n<p class=\"wp-block-paragraph\">Now a method operating on <code>Shape<\/code> works correctly for both classes:<\/p>\n\n\n<pre style=\"padding-left: 80px;\"><!--ScriptorStartFragment--><\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">public static void printArea(Shape shape) {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 System.out.println(&#8220;Shape area: &#8221; + shape.calculateArea());<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">}<!--ScriptorEndFragment--><\/div>\n\n<pre style=\"padding-left: 80px;\"><!--ScriptorStartFragment--><\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">public static void main(String[] args) {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 printArea(new Rectangle(5, 3)); \/\/ Shape area: 15\u00a0<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 printArea(new Square(4));\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Shape area: 16\u00a0<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">}<!--ScriptorEndFragment--><\/div>\n\n\n<h4 class=\"wp-block-heading\">What Did We Gain?<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Each class is responsible for its own logic.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>Square<\/code> class no longer pretends to be a rectangle. It has its own consistent behavior.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The base-class contract is always honored.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>calculateArea()<\/code> in every subclass does exactly what the caller expects: it returns the area of the shape.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We can safely substitute subclasses.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Any code that accepts a <code>Shape<\/code> will work correctly whether it receives a <code>Rectangle<\/code>, a <code>Square<\/code>, or any other future shape.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Why Is LSP Important?<\/h4>\n\n\n\n<h5 class=\"wp-block-heading\">Inheritance Is a Promise<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">When we write:<\/p>\n\n\n<pre style=\"padding-left: 80px;\"><!--ScriptorStartFragment-->class B extends A<!--ScriptorEndFragment--><\/pre>\n\n\n<p class=\"wp-block-paragraph\">we are making a promise:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">&#8220;B behaves like A wherever A is expected.&#8221;<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Violating LSP breaks that promise and introduces bugs that are often difficult to debug because the code still compiles successfully.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Predictable Behavior<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">When LSP is respected, we can trust that subclasses will not introduce surprises.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A method that works for the base class will also work for every subclass without requiring special handling.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Eliminating <code>instanceof<\/code> Checks<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">The need to write code such as:<\/p>\n\n\n<pre style=\"padding-left: 80px;\">if (object instanceof Square)<br \/><br \/><!--ScriptorEndFragment--><\/pre>\n\n\n<p class=\"wp-block-paragraph\">is often a sign of an LSP violation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The code must distinguish between types because subclasses are not truly substitutable for their base class.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Better Team Collaboration<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">In large projects, LSP violations often surface months later.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Someone adds a new subclass and suddenly part of the system behaves differently.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Respecting LSP gives the team confidence that extending class hierarchies is safe.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Consequences in Large Systems<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Imagine a payment system with a base class <code>Payment<\/code> and dozens of subclasses representing different payment methods.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If one subclass throws:<\/p>\n\n\n<pre style=\"padding-left: 80px;\"><!--ScriptorStartFragment-->UnsupportedOperationException<!--ScriptorEndFragment--><\/pre>\n\n\n<p class=\"wp-block-paragraph\">for a method such as:<\/p>\n\n\n<pre style=\"padding-left: 80px;\"><!--ScriptorStartFragment-->refund()<!--ScriptorEndFragment--><\/pre>\n\n\n<p class=\"wp-block-paragraph\">the refund mechanism breaks for that payment type.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Customers do not receive their money back, and the bug may only be discovered in production.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">When Should You Apply LSP?<\/h4>\n\n\n\n<h5 class=\"wp-block-heading\">Whenever You Use Inheritance<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Before creating a subclass, ask yourself:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Can this subclass replace the base class in every scenario?<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">If the answer is:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">&#8220;Not always&#8221;<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">then the inheritance hierarchy is likely incorrect.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">When <code>instanceof<\/code> Appears in the Code<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Type checking is often a sign that subclasses are not true substitutes for the base class.<\/p>\n\n\n<pre style=\"padding-left: 80px;\"><!--ScriptorStartFragment--><\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">public void processShape(Shape shape) {<\/div>\n<pre style=\"padding-left: 80px;\">\u00a0<\/pre>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 if (shape instanceof Square) {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ special handling<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 } else {<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ standard handling<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">\u00a0\u00a0\u00a0 }<\/div>\n<div class=\"scriptor-paragraph\" style=\"padding-left: 80px;\">}<!--ScriptorEndFragment--><\/div>\n\n\n<h5 class=\"wp-block-heading\">In E-Commerce Systems<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Consider an <code>Order<\/code> class and an <code>ExportOrder<\/code> subclass.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If <code>ExportOrder<\/code> does not support <code>calculateDiscount()<\/code> in the same way as a normal order, it violates LSP and can cause failures in the discount system.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">In Spring Framework<\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">Spring heavily relies on LSP.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Any Bean can be replaced by a mock implementation during testing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That is one of the reasons dependency injection through interfaces is so powerful: every implementation acts as a valid substitute.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">&#8220;If it looks like a duck and quacks like a duck\u2014but requires batteries to quack\u2014you have a bad inheritance model.&#8221;<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">A subclass must not only look like the base class\u2014it must also behave like it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">No surprises.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">No exceptions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">No silent behavioral changes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inheritance is not just about sharing code\u2014it is a commitment to honoring a contract.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A derived class may extend the behavior of a base class, but it should never break that behavior.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A Subclass Must Be a Replaceable Substitute for Its Base Class The Liskov Substitution Principle (LSP) states that objects of a derived class should be able to replace objects of the base class without affecting the correctness of the program. Simply put: If class B inherits from class A, then anywhere we use A, we [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"saved_in_kubio":false,"footnotes":""},"categories":[12],"tags":[],"class_list":["post-414","post","type-post","status-publish","format-standard","hentry","category-solid"],"_links":{"self":[{"href":"https:\/\/patryk-sobilo.profesjonalnyprogramista.pl\/index.php\/wp-json\/wp\/v2\/posts\/414","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/patryk-sobilo.profesjonalnyprogramista.pl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/patryk-sobilo.profesjonalnyprogramista.pl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/patryk-sobilo.profesjonalnyprogramista.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/patryk-sobilo.profesjonalnyprogramista.pl\/index.php\/wp-json\/wp\/v2\/comments?post=414"}],"version-history":[{"count":2,"href":"https:\/\/patryk-sobilo.profesjonalnyprogramista.pl\/index.php\/wp-json\/wp\/v2\/posts\/414\/revisions"}],"predecessor-version":[{"id":416,"href":"https:\/\/patryk-sobilo.profesjonalnyprogramista.pl\/index.php\/wp-json\/wp\/v2\/posts\/414\/revisions\/416"}],"wp:attachment":[{"href":"https:\/\/patryk-sobilo.profesjonalnyprogramista.pl\/index.php\/wp-json\/wp\/v2\/media?parent=414"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/patryk-sobilo.profesjonalnyprogramista.pl\/index.php\/wp-json\/wp\/v2\/categories?post=414"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/patryk-sobilo.profesjonalnyprogramista.pl\/index.php\/wp-json\/wp\/v2\/tags?post=414"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}