By Jake


2011-06-06 18:35:21 8 Comments

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.).

4 comments

@John V 2018-10-11 09:33:07

It depends on the contract. That is, the code using your classes must get consistent behavior, regardless what derivation of your type is it using.

If the contract stated "getSpecialTreatment" always returns true, you would be violating that in your derived class.

If the contract states "getSpecialTreatment" returns a boolean value determining blabla., then you are not violating LSP.

You could violate LSP if you introduced additional constraint that is not present in the base class.

@irreputable 2011-06-06 19:33:13

First, strong objection to your discrimination against cats!

Now, when programmers invoke the so called "Liskov substitution principle", they are not really talking about it in its academic sense. We must be using it in some informal, vulgar, bastardized sense.

What sense is that? I find it nothing more than requiring that subclass must conform to the contract set by the super class. So it's really uninteresting. People invoke this phrase just to be fansy.

@umlcat 2011-06-06 20:14:30

I personally agree with the objection. But, I agree that the L.S.P., like Software Patterns, like "Best Practices", must be applied in a practical way, not just as "academic snob"

@irreputable 2011-06-06 20:44:49

I don't care about the academic "LSP". We should stop pretending to be computer scientists.

@Robin 2011-06-06 19:05:13

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.

@gpeche 2011-06-06 19:04:48

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.

@Nicolas Bousquet 2011-06-06 20:23:55

Even the last exemple is not always a violation of LSP. It depend of the intended design. Although you'll more likely want to declare a checked exception or explicitely state that the method can throw some exception in API documentation.

Related Questions

Sponsored Content

26 Answered Questions

[SOLVED] Why not inherit from List<T>?

34 Answered Questions

[SOLVED] What is the difference between an interface and abstract class?

27 Answered Questions

29 Answered Questions

34 Answered Questions

[SOLVED] Interface vs Abstract Class (general OO)

1 Answered Questions

3 Answered Questions

[SOLVED] Liskov substitution principle violation

Sponsored Content