Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

LSP states that classes should be substitutable for their base classes, meaning that derived and base classes should be semantically equivalent.

But does LSP also apply to classes implementing an interface? In other words, if an interface method implemented by a class is semantically different from what user expects it to be, would this be considered as a violation of LSP?

share|improve this question
6  
Yes. Exactly same reasons and results as violating LSP if it's an interface, an abstract class, a full class, doesn't matter. LSP is about setting and meeting expectations to allow consumers to treat your types in a general way. –  Jimmy Hoffa Oct 22 '12 at 18:55
5  
By and large (I know the differences, but I'm generalizing here), interfaces are somewhat analogous to pure abstract classes (C++ term) and therefore Liskov should apply to interfaces and the classes which implement them. –  Jesse C. Slicer Oct 22 '12 at 18:56
2  
NB the formulation of the LSP I'm familiar with speaks of subtypes rather than derived and base classes. With good reason, I assume, because none of the reasons is specific to inheritance and applies just as well for any other kind of subtyping. –  delnan Oct 22 '12 at 19:09
add comment

2 Answers

up vote 14 down vote accepted

if an interface method implemented by a class is semantically different from what user expects it to be, would this be considered as a violation of LSP?

If the implementation is semantically different from the behavior documented through the invariants of the interface and its methods' pre- and post-conditions, then the answer is "yes", it would be a violation of the LSP. The principle establishes the rules for the abstraction and its implementations, without requiring the abstraction side to be present in the form of a class.

However, if we talk about what users expect, the answer would be "not necessarily": the users are entitled to having wrong expectations.

share|improve this answer
    
"If the implementation is semantically different from the behavior documented through the invariants of the interface" Could you elaborate on what you mean by "invariants of the interface"? –  user1483278 Oct 22 '12 at 21:35
2  
@user1483278 Here is an article about type invariants. The article calls them "Class invariants", but the description applies to interfaces as well. Invariants are conditions that are established at construction, and maintained throughout the lifetime of an instance. For example, if an interface has a property Name that cannot be set to null, then obj.Name != null is said to be an invariant of that interface. –  dasblinkenlight Oct 22 '12 at 21:57
1  
Typically when invariants are discussed, it is possible to write a piece of code to verify that the invariant is upheld over the entire lifetime of the object. However, it is typically more straightforward to verbally describe the invariant in plain English. –  rwong Oct 23 '12 at 3:21
    
thank you all for your help –  user1483278 Oct 23 '12 at 12:40
add comment

Firstly, it's my belief that OO principles (such as the LSP) are called "principles" and not "laws" because, as opposed to laws, they can be subject to interpretation (check out the discussion here), and are something that it's more to be desired rather than a state that should always be so.

That being said, in the specific context of your question, I do believe that having various implementations of the same interface, which may result in either technically or functionally non-consistent behavior is a violation of the LSP and a thing not to be desired. Here's a small example :

Imagine you have some API that declares an interface like so:

public interface RightAngledShape {

    public void setWidth(int width);
    public void setHeight(int height);
    /**
     * This method calculates the perimeter of a shape having only right angles and the width and height as set
     * via the {@link RightAngledShape#setWidth(int)} and {@link 

RightAngledShape#setHeight(int)} methods 
     * 
     * @return the perimeter of the corresponing right-angled shape
     */
    public int getPerimeter();
}

Imagine then that there's also two implementations of the interface like so:

public class Rectangle implements RightAngledShape {

    private int width,height;

    @Override
    public void setWidth(int width) {
        this.width = width;
    }

    @Override
    public void setHeight(int height) {
        this.height = height;
    }

    @Override
    public int getPerimeter() {
        return 2*(width + height);
    }

}

and:

public class InvalidSquare extends Rectangle {

    public void setHeight(int height) {
        super.setWidth(height);
        super.setHeight(height);
    }
}

In certain contexts this might be a good thing. Someone might need Square and Rectangle implementations only to store the width and height values, for which case having a Square that simply overrides the Rectangle methods in order to enforce a single size for all sides is a good thing. But since these two implementations are also of type RightAngledShape the LSP says that they should fully obey its contract and have the getPerimeter() method return the correct perimeter all the time. In the above example this does not happen:

public static void main(String[] args) {
    RightAngledShape shape1 = randomFactoryMethod1();
    shape1.setWidth(10);
    shape1.setHeight(20);
    System.out.println(shape1.getPerimeter());//prints 60

    RightAngledShape shape2 = randomFactoryMethod2();
    shape2.setWidth(10);
    shape2.setHeight(20);
    System.out.println(shape2.getPerimeter());//prints 80
}

static RightAngledShape randomFactoryMethod1() {
    return new Rectangle();
}

static RightAngledShape randomFactoryMethod2() {
    return new InvalidSquare();
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.