The term polymorphism means multiple forms. In the world of programming, it refers to the ability of an object to exist in multiple forms. Polymorphism is one one of the key concepts of Object Oriented Programming.

Why do we need polymorphism?

Polymorphism is there to increase the complexity of the already complex world of programming. Just kidding! By using functions, we break down the program into smaller logical parts that are easier to understand, implement and thereby maintain. In this sense, the function is the smallest self sufficient (ideally) logical block of a program. As you get to know more about the real world programming, you’ll find that even these small logical blocks are often very big and rather complex. Consider the following function which is used to calculate the area of a circle from the radius entered as integer.

1
2
3
4
5
double CalcArea(int Radius)
{
    double Area = Math.PI * Radius * Radius;
    return Area;
}

This function can only handle integers as input. What if the Radius was in double? The function would fail in such a case. We can create another function named CalcAreaDouble to handle the input in double.

1
2
3
4
5
double CalcAreaDouble(double Radius)
{
    double Area = Math.PI * Radius * Radius;
    return Area;
}

While, this works, there’s something wrong about this method. The name of a function should describe(in brief) what it does and not the type of values it returns or takes as input. Both these functions do the same job, Calculate Area. Hence, they should have the same name. Thanks to Polymorphism, we can declare two functions with the same name, inside the same class.

1
2
3
4
5
6
7
8
9
10
11
double CalcArea(int Radius)
{
    double Area = Math.PI * Radius * Radius;
    return Area;
}
 
double CalcArea(double Radius)
{
    double Area = Math.PI * Radius * Radius;
    return Area;
}

This is called function overloading. For two functions with the same name to co-exist, they must follow certain rules:-

  • The functions must differ in either the type, the sequence or the number of input parameters i.e they must have different function signatures. The CalcArea functions have different types of parameters.

    These two functions differ in the number of parameters:-

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    int SumOfNum(int Num1, int Num2)
    {
        return Num1 + Num2;
    }
     
    int SumOfNum(int Num1, int Num2, int Num3)
    {
        return Num1 + Num2 + Num3;
    }

    While, these have different sequence:-

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    float SumOfNum(int Num1, float Num2)
    {
        return Num1 + Num2;
    }
     
    float SumOfNum(float Num1, int Num2)
    {
        return Num1 + Num2;
    }
  • Return type has no influence on function overloading. Hence, these two functions cannot co-exist:-
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    double CalcArea(int Radius)
    {
        double Area = Math.PI * Radius * Radius;
        return Area;
    }
     
    int CalcArea(int Radius)
    {
        double Area = Math.PI * Radius * Radius;
        return Area;
    }
Static Polymorphism

Function overloading along with operator overloading which we shall look at in the next tutorial are ways of implementing static polymorphism. Static polymorphism inturn, is one of the two types of Polymorphism, the other being Dynamic polymorphism. Also called as early binding, this concept refers to an entity existing in different forms. Just like a teacher who carries on the role of a father, a husband, a comrade besides being a teacher, the functions exist in different forms, each specializing in handling one type of role. In static polymorphism, the response to a function is decided at compile time and hence it is also called early binding.

Overloading Constructors

Since constructors are also functions and can be parameterized(takes parameters as input), they can be overloaded. This allows flexibility while creating an object. Consider the Rectangle class declared in the System.Drawing namespace. It can be instantiated by either of the two methods.

Method 1: Using default constructor

In this method, the bounds of the rectangle object Rect are individually set.

1
2
3
4
5
Rectangle Rect = new Rectangle();
Rect.X = 10;
Rect.Y = 20;
Rect.Width = 30;
Rect.Height = 40;

Method 2: Using the Parametrized Constructor

Rectangle Rect = new Rectangle(10, 20, 30, 40);

Notice, how much easier this method is. The initialization in this case is handled by the constructor of the Rectangle class.

The rectangle class would have an implementation similar to this one:-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Rectangle
{
    public int X;
    public int Y;
    public int Width;
    public int Height;
 
    Rectangle()
    {
        this.X = 0;
        this.Y = 0;
        this.Width = 0;
        this.Height = 0;
    }
 
    Rectangle(int x, int y, int width, int height)
    {
        this.X = x;
        this.Y = y;
        this.Width = width;
        this.Height = height;
    }
}

As you can see, the class has two overloaded constructors, one being the default constructor which takes no parameter and initializes the values of X, Y, Width and Height to 0. The other one initializes these values based on the inputs to it.

Note: This code is just to give you an idea of how the constructors are implemented. In actual fact, the rectangle class would be a lot more complex than this and would require further codes inside the constructors.

No votes yet.
Please wait...