Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we need to assign object of derived class to base class to call a method?

I have a base class called Shape and a derived class Rectangle which derives from Shape.

class Shape
{
    public virtual void Draw()
    { 
        //Draw the Shape
        Console.WriteLine("Draw the Shape");
    }
}
class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw Rectangle");
    }
}

I have a very basic doubt that when calling method of my derived class I do something like this.

Shape r1 = new Rectangle();
r1.Draw();

But if I want to invoke method of Rectangle class I can always do like this.

Rectangle r2 = new Rectangle();
r2.Draw();

My question is that why we need to use first method when we can always use the second one which is easy to understand and implement.?

like image 502
hemant Avatar asked Mar 19 '23 22:03

hemant


2 Answers

Both methods are correct and both will work. In both cases, the Draw-method of the Rectangle-class will be called.

The first scenario that springs to mind on why you would use the first approach, is when you have some sort of collection, and you want to draw them all at once. Say you add more derived classes like Circle and Triangle who also override the base implementation of Draw. Then the following would still be a valid scenario:

//We know that our collection will contain various shapes.
List<Shape> shapes = new List<Shape>();

//This is okay because all the specific shapes inherit from the Shape class.
shapes.Add(new Triangle());
shapes.Add(new Rectangle());
shapes.Add(new Circle());

//We can safely draw all shapes, because all shapes have a Draw-method.
//If they haven't implemented their own, the Draw-method of the Shape class will be called.
foreach(Shape shape in shapes)
  shape.Draw();

One thing to keep in mind is that in the above example we treat all specific objects as if they were of type Shape. This essentially means that in that usage each object does not know of any class specific implementation. Say you added a NumberOfCorners-property to your Rectangle:

class Rectangle : Shape
{
    public Rectangle() {
        NumberOfCorners = 4;
    }

    public override void Draw()
    {
        Console.WriteLine("Draw Rectangle");
    }

    public int NumberOfCorners { get; set; };
} 

Then the following would not work because the Shape-class does not have a NumberOfCorners-property:

Shape shape = new Rectangle();
Console.WriteLine(shape.NumberOfCorners); //This will cause an error.

However, the specific instance is still deep down below an instance of Rectangle meaning that this would work:

Console.WriteLine((shape as Rectangle).NumberOfCorners); //This is fine, provided that shape is not null.
like image 134
kaspermoerch Avatar answered Apr 25 '23 17:04

kaspermoerch


The underlying question seems to be is what is the purpose of polymorphism. Polymorphism allows for a single interface to a variety of types enabling methods to work against sets of class without having to reference each class.

For example, say you have a list of shapes and you want to render each one. You could do something like this:

list.ForEach(x => x.Draw()); //where list is, say, IList<Shape> 

rather that having a collection of Rects, and another collection of Circles and so on.

like image 35
JohnCampbellJr Avatar answered Apr 25 '23 15:04

JohnCampbellJr