Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does overloading violate Liskov Substitution Principle?

I am newbie in OOP. Recently I have read about Liskov Substitution Principle.

In the code given below, Square class inherits Give_Area. Suppose Square class has something to do related to a square(like validity check). Give_Area gives area of square(4 vertex are on the perimeter of a circle) and area of a circle. So, If I am given a Radius, I've to print area of the circle and square(consists of vertexes placed on the perimeter of that circle). To get the area of a circle, I have used a parameter. But there is no parameter when getting area of square. Thus I have done overloading here.

#include<iostream>
#include<cmath>
using namespace std;

class Give_Area
{
    public:
    double Radius;

    double Area(double pi)
    {
        return pi*Radius*Radius;
    }

    double Area()
    {
        double temp = sqrt(2.0)*Radius;
        return temp*temp;
    }
};

class Square : public Give_Area
{
    public:
    bool Validity()
    {
        //checking validity
    }
};

int main()
{
    Give_Area* area = new Square();
    area->Radius = 3.0;
    cout<< "Area of Circle: " << area->Area(3.14159) <<endl;
    cout<< "Area of Square: " << area->Area() <<endl;
    return 0;
}

My question is..

Is this overloading violating Liskov Substitution Principle?

If this code is violating, then would anybody please give me an example of an overloading which will not violate Liskov Substitution Principle?

I googled my query but have found nothing. :(

Thanks in advance.

like image 803
Mukit09 Avatar asked Nov 01 '22 12:11

Mukit09


1 Answers

The LSP

Liskov's Substitution Principle (or LSP) is about abstraction. Imagine a class Shape and two classes Square and Rectangle deriving from Shape. Now Shape has a (virtual) method getArea(). You would expect it to return the area that is covered by the (concrete, instanced!) shape regardless of what type it actually is. So if you call getArea() on a Shape instance, you don't care whether it is a rectangle, a square or any other shape you could think of.

The Answer

Without overloading there wouldn't even be the need for something like the LSP, i.e. the answer is no, overloading and LSP doesn't contradict.

The Design

On the other hand, as paxdiablo pointed out, applying LSP depends on the design. In terms of the example above this means, maybe for some reason you actually do care wether you have a rectangle or not. Well, in that case the LSP says you should think about your design.

Your Code

I have to admit at this point, I don't really get where your code is aiming at. There is a class Give_Area which calculates the area of a cirle depending on the value of, uh, pi. A second method calculates a square that has Radius as its diagonal? Then there is the Square class. If Validity() returns false, what would that mean? A degenerated square maybe? My suggestions is: Reconsider your design. Ask yourself "what are the classes and objects I want to deal with?" and "what are the real-world objects I want do model?"

The Counterexample

How to violate the LSP is demonstrated at Wikipedia (link above). I will try to make up a second example. Say you have a class Car with a method drive(). Deriving classes (RacingCar, Van, ...) could specify speed, accelaration, etc. When a car drives into water (deep water, a lake, the sea) the car will break and the next garage is called. Now you derive a class AmphibiousVehicle. This one doesn't break on water and the garage would be called with no use. Did you expect that? Maybe yes. But if not, depending on further context I would think about a class Vehicle which is the base of Car. It would have a method move(). And drive() which belongs still to Car would call move() and might call (again ;-)) the garage in case of trouble. And so on.

like image 93
TobiMcNamobi Avatar answered Nov 04 '22 09:11

TobiMcNamobi