Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do abstract properties violate the Liskov substitution principle?

Suppose I have an abstract class like:

public abstract class Pet {
    private final String name;
    public Pet(String name) { 
        this.name = name 
    };

    public abstract boolean getsSpecialTreatment();
}

public final class Dog extends Pet {
    @Override public boolean getsSpecialTreatment() { return true; }
}

public final class Cat extends Pet {
    @Override public boolean getsSpecialTreatment() { return false; }
}

My program will treat Pets differently depending on whether the special treatment flag is set. My question is whether this counts as violating the Liskov substitution principle, which states that:

[...] in a computer program if S is a subtype of T, then objects of type T may be replaced with objects of type S [...] without altering any of the desirable properties of that program (correctness, task performed, etc.).

like image 231
Jake Avatar asked Jun 06 '11 18:06

Jake


People also ask

Does Liskov Substitution Principle apply to abstract classes?

In short, yes. The LSP applies to essentially all public inheritance. The fact that a base class is abstract doesn't change that.

What violates Liskov Substitution Principle?

A very common violation of this principle is the partial implementation of interfaces or base class functionality, leaving unimplemented methods or properties to throw an exception (e.g. NotImplementedException).

What is the most accurate example of Liskov Substitution Principle?

A good example here is that of a bird and a penguin; I will call this dove-penguin problem. The below is a Java code snippet showing an example that violates the LSP principle. Here, the Dove can fly because it is a Bird. In this inheritance, much as technically a penguin is a bird, penguins do not fly.

Which OOP principle is absolutely important for the Liskov Substitution Principle?

The Open/Closed Principle To understand the Liskov Substitution Principle, we must first understand the Open/Closed Principle (the “O” from SOLID). The goal of the Open/Closed principle encourages us to design our software so we add new features only by adding new code.


2 Answers

In this case, users of those classes will probably write:

...
if (pet.getsSpecialTreatment()) {
    // special treatment
    ...
} else {
    // normal treatment
    ...
}
...

This code will work on both cases, so you would not be violating LSP. However, if you had

public class UnknownAnimal extends Pet {
    @Override public boolean getsSpecialTreatment() {
        throw new UnsupportedOperationException("Unknown species"); 
    }
}

then you would be violating LSP, because existing code will break when using UnknownAnimal instances.

like image 90
gpeche Avatar answered Sep 24 '22 20:09

gpeche


No. Any usage of the method in the program would base subsequent decisions on the return value, just like any other method. By the very nature of the existence of the method, no program should make assumptions as to its outcome. Therefore the change in the value returned by this method should not change the properties of the program.

like image 25
Robin Avatar answered Sep 21 '22 20:09

Robin