5

Lets say we have this really trivial classes:

class A { virtual int Function(int number) { return number; } } class B : A { override int Function(int number) { return number + 1; } } class UseExample { void Foo(A obj) { A.Function(1); } } 

Would be this example a violation of the LSP?. If so, could you give me an example that does not break the principle and uses a different implementation?

What about this one:

class B : A { int variable; override int Function(int number) { return number + variable; } } 

As far as I understood the use of the variable "variable" causes a stronger pre-condition and therefore it violates the LSP. But i'm not completely sure how to follow the LSP when using Polymorphism.

5
  • 1
    your function has no contract in it's naming or outlook whatsoever, an implementation returning an arbitrary value is therefore perfectly acceptable. You would get in a gray zone however if you specify a contract in the name of the function, like: int Add1ToArgument(int argument) { ... } Commented Dec 21, 2011 at 2:53
  • Polity, implied semantics from method naming doesn't really come into it. It's from the type definition. Commented Dec 21, 2011 at 2:55
  • If the semantics has nothing to do with the principle, would you mind explaining me the Rectangle/Square example?. The mayor complain about this that i've found so far is that if you use a Rectangle obj = new Square() and assign height an width without previous knowledge that the object is an Square, you will get an unexpected result of the function getArea() just because you think a Rectangle has 2 different values for Height and Width. Thanks in advance Commented Dec 21, 2011 at 3:07
  • 1
    When your system supports pre / post conditions and invariants, then the rectangle / square thing kicks in. But in many language those constraints aren't specified and most likely a square can be used instead of a rectangle. (maybe, sometimes the in-variants/post and pre conditions are simply assumed and relied on) Commented Dec 21, 2011 at 3:40
  • PreConditions, Postconditions and Invariants are Conditions formalised by a programming contract ( Design by contract ). <br> Please see my blog design-principle-pattern.blogspot.in/2013/12/… Commented Dec 12, 2013 at 12:55

2 Answers 2

2

That's valid, in both cases it doesn't break the principle. B can be substituted for A. It just has different functionality.

a simple way to break the contract would be to throw an exception in Bs override if the number == 23 or something :)

Sign up to request clarification or add additional context in comments.

3 Comments

In the second example, lets say we call the function A.Function(1) and the variable "variable" is not initialized. In this case we have a runtime-error (if i'm not mistaken) therefore we have violated the LSP. I believe that you cannot exchange B/A because A has no definition for "variable"
an int is initialized by default, it can't not be initialized (though there is not language specified here, I'm assuming C# ish). Bs construction can be completely different from As construction, as long as it can be used as an A once constructed. exceptions are most likely things that can happen that subtly break LSP. But if you introduce the idea that A.Function can throw exceptions, you cover your ass :)
My mistake with the int initialization. You could work around the example and use an Object of a class C that does not have a default constructor and holds a magic number used in the equation of B's method. That way you could expect an exception thrown by A.Function() (should be obj.Function() instead, my bad). Thanks for the reply :P
0

From my understanding of it I would say that both your examples violate LSP as the subclass cannot be replaced by its superclass. Consider the following:

class UseExample { void Foo(A& obj, int number) { int retNumber = obj.Function(number); assert(retNumber==number); } } 

If you were to pass a reference to a B object into Foo the assert will fail. The B.Function is changing the poscondition of A.Function. The Foo client code shouldn't have to know about possible subtypes which may break their code.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.