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.
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.
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.
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.
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?"
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.