Polymorphism

Polymorphism meaning

Polymorphism is a Greek word constructed from two words, poly and morph. The word poly means many and morph means changing forms. polymorphism means having many forms. In computer science, It provides the ability to object to change the forms based on context usage.

“Polymorphism is an object-oriented programming concept that refers to the ability of a variable, function, or object to take on multiple forms. A language that features polymorphism allows developers to program in the general rather than program in the specific”

Polymorphism Definition by techopedia.com

To understand more about polymorphism, In the below picture, we can see all objects speak but each has a different way. A similar way in programming, all objects could have the same methods but based on an object type implementation change. So, can declare an action for a class and its following class but for each class, we can write exactly what we want.

polymorphism, polymorphism in java, polymorphism c++, runtime polymorphism, compiletime polymorphism, polymorphism in oop, types of polymorphism, polymorphism real time example, polymorphism computer science, polymorphism in object oriented programming

In simple words, we can say that polymorphism is the ability to change its form based on context. For example, in the below code snippet the add method performing integer addition, while the add method with string parameters performs concatenation of string, the add method in the float parameters returns the floating-point addition and so on.

Polymorphism example


public class Addition
{
    public int Add(int a, int b)
    {
        return a + b;
    }

    public string Add(string a, string b)
    {
        return a + " " + b;
    }

    public float Add(float a, float b)
    {
        return a + b;
    }

    public double Add(double a, double b)
    {
        return a + b;
    }

}

Types of Polymorphism

In object-oriented programming the Polymorphism has divided into two types

  • Compile-Time Polymorphism
  • Run-Time Polymorphism

Compile-Time Polymorphism

Compile-Time Polymorphism is also known as static or early binding. It is achieved by method overloading or operator overloading. In this type compiler already know what kind of object it is and which overloaded methods it holds the reference.

  • Method overloading
  • Operator overloading

Method Overloading

Method Overloading allows us to define multiple methods with the same name by changing the parameters of a method in one class or multiple subclasses (parent-child).


public class Message
{
    public void Print()
    {
        Console.WriteLine("Error Occurred!");
    }

    public void Print(Exception exception)
    {
        Console.WriteLine($"Error Occurred: {exception.Message}");
    }

    public void Print(Exception exception, string className)
    {
        Console.WriteLine($"Error Occurred in {className} \n error: {exception.Message}");
    }
}

In the above example, we notice that the Print() method is overload with different parameters. So, when we call method compiler will already know which method we are pointing too.

Method overloading in Parent-child relation

We can implement method overloading in Parent-child relation, consider below code snippet example

public class CommonExceptionMessage
{
    public void Print()
    {
        Console.WriteLine("Error Occurred!");
    }
}

public class KnownExceptionMessage : CommonExceptionMessage
{
    public void Print(Exception exception)
    {
        Console.WriteLine($"Error Occurred: {exception.Message}");
    }
}

In the above code snippet, we can see the parent class Print() method is without parameter but the child class print method required one input parameter. Now, if we create an instance of the Child class, we can see two Print() method available for child instance depending upon what parameters we are providing at the time of calling the Print() method, the appropriate Print() method gets called.

using System;

class Program
{

    static void Main()
    {
        KnownExceptionMessage knownExceptionMessage = new KnownExceptionMessage();
        knownExceptionMessage.Print();
        knownExceptionMessage.Print(new Exception("Test Exception"));
        Console.ReadLine();
    }
}

Does method overloading consider return type of a function?

public int Add(int a, int b)
{
    return a + b;
}

public string Add(int a, int b)
{
    return (a + b).ToString();
}

The above code will give generate compile-time errors in most of the object-oriented programming languages like C#, Java, C++. as it’s not allowed. Because it’s not sufficient for the compiler to figure out which function to call from the above add method. In general return, the type is the last part of any method and the ambiguity comes into the picture at the time of the calling of the methods.

Operator overloading

Operator overloading allows us to change the behaviors of operators (+, -, *, / etc.) to change the behaviors of the existing operator’s method based on the number and type of parameters passed to it in each implementation.

C# Syntax of Operator Overloading

[<modifier>] static <return type> operator <operator symbol>(<operand types>)
{

//logic

}

In the below code snippet we have a basic example of Operator overloading where we are overriding ‘+’ and ‘-‘ operator to add a fixed number to the result.

namespace Demo
{
    class OperatorOverloadingDemo
    {
        public readonly int Total;
        private readonly int _num1;
        private readonly int _num2;
        private const int FixedNum = 10;

        public OperatorOverloadingDemo(int num1, int num2)
        {
            _num1 = num1;
            _num2 = num2;
        }

        public OperatorOverloadingDemo(int total)
        {
            Total = total;
        }

        public  static OperatorOverloadingDemo operator +(OperatorOverloadingDemo operatorOverloadingDemo)
        {
            return new OperatorOverloadingDemo(operatorOverloadingDemo._num1 + operatorOverloadingDemo._num2 + FixedNum);
        }

        public static OperatorOverloadingDemo operator -(OperatorOverloadingDemo operatorOverloadingDemo)
        {
            return new OperatorOverloadingDemo(operatorOverloadingDemo._num1 - operatorOverloadingDemo._num2 - FixedNum);
        }
    }
}

Typically operator overloading is useful in performing an operation on user-defined types, for example I have a shape that has width and Hight and we want to add this kind of two objects. We can overload ‘+’ operator, in this case, refer below code snippet.


public class Shape
{
    public int Width;
    public int Hight;
    public Shape(int width, int hight)
    {
        Width = width;
        Hight = hight;
    }
    public Shape()
    {
        Width = 0;
        Hight = 0;
    }

    public static Shape operator +(Shape shape1, Shape shape2)
    {
        return new Shape(shape1.Width + shape2.Width, shape1.Hight + shape2.Hight);
    }
}

In the above code snippet “Shape” class which allow the user to add two shape

class Program
{

    static void Main()
    {
        Shape s1 = new Shape(10, 20);
        Shape s2 = new Shape(30, 40);
        Shape s3 = s1 + s2;

        Console.WriteLine($"Width: {s3.Width}, Hight: {s3.Hight}");
        Console.ReadLine();
    }
}

Output of the above code snippet

Width: 40, Hight: 60

Point to remember in operator overloading

  • Operator overload methods must return something it can’t be return void.
  • User-defined operator implementations always get preference over predefined implementations.
  • Not all languages support operator overloading.

Run-Time Polymorphism

Run time polymorphism is also known as dynamic or late binding. We can achieve run time polymorphism by method overriding. To understand run-time polymorphism, we must aware of the Inheritance concept of OOP.
Suppose we have a parent-child relation class where parent class and child class contain the same method with the same signature. Hence only based on object creation it will decide which method gets executed. As a compile-time compiler only checks whether the equivariant method is available in a class and at a run, time is able to decide whether the parent class method should be called or child class method to call.

  • Method Overriding

Method Overriding

It is the process of implementing specific behavior in child class for which general behavior is already defined in the parent class.
For example, In Car class speed method is already defined but based on car type speed might change hence the speed method is implemented in all child classes.

public class Car
{

    public virtual void Speed()
    {
       Console.WriteLine("Speed is 60kmh");
    }
}


public class Audi:Car
{

    public override void Speed()
    {
        Console.WriteLine("Speed is 120kmh");
    }
}

public class Mercedes : Car
{

    public override  void Speed()
    {
        Console.WriteLine("Speed is 150kmh");
    }
}

public class Jaguar : Car
{

    public override  void Speed()
    {
        Console.WriteLine("Speed is 180kmh");
    }
}

Observed in the above code snippet each child class has overridden the speed method to implement specific behavior of its type.

So, If we called this class using parent class object, compiler at the run time decides which method to be called

class Program
{

    static void Main()
    {
        Car car = new Audi();
        car.Speed();
        Console.ReadLine();
    }
}

Output of the above code snippet

Speed is 120kmh

We can state that it is an approach to redefine specific implementations of a subclass that is already present in the superclass.

Keywords in Method overriding

  • virtual
  • override
  • base

virtual

A virtual keyword mostly used in base/parent class and notifies compiler that the method might have an override in a subclass. It also specifies to the subclass that it can override this method and provide the class-specific implementation.

public class Car
{
    public virtual void Speed()
    {
       Console.WriteLine("Speed is 60kmh");
    }
}

In the above code snippet Car class has a virtual method, if any class derived from the Car class then the derived/subclass can override the speed method based on derived/subclass requirement.

override

An override keyword used to specify compiler that this method which is already declared in the parent class is has been overridden in a subclass.

public class Car
{

    public virtual void Speed()
    {
       Console.WriteLine("Speed is 60kmh");
    }
}


public class Audi:Car
{

    public override void Speed()
    {
        Console.WriteLine("Speed is 120kmh");
    }
}

In the above code snippet, we can see that Audi class is derived from the Car class. the Audi class has override speed method.
So, when someone call creates a car instance using Audi class it will call the override method from Audi class.

class Program
{

    static void Main()
    {
        Car car = new Car();
        car.Speed();
        Console.ReadLine();
    }
}

Note: we can only override abstract and virtual methods

Points to remember:

  • The method signature along with its order must be the same.
  • This can only be implemented between Parent-child relations.

base

A base keyword is used to call the super class methods from sub class

public class Car
{

    public virtual void Speed()
    {
        Console.WriteLine("Speed is 60kmh");
    }
}

public class Honda : Car
{

    public override void Speed()
    {
        base.Speed();
    }
}

in the above code snippet, Honda class has called the speed method of parent class using base keyword.

Method Hiding

Suppose we have a method that overrides from the parent class, but we want to hide its implantation whenever we create an instance using parent. Refer code snippet below

public class Car
{
    public virtual void Speed()
    {
        Console.WriteLine("Speed is 60kmh");
    }
}


public class Audi : Car
{
    public override void Speed()
    {
        Console.WriteLine("Speed is 120kmh");
    }
}

public class A6 : Audi
{
    public void Speed()
    {
        Console.WriteLine("Speed is 200kmh");
    }
}

In the above example, we can see multilevel inheritance. suppose we want to call Audi class speed method when we create an instance of A6 using Car class

Car car = new A6(); 

As we have not marked the A6 class’s speed method override so it will hide the implementation whenever we create an instance of the A6 using parent object.


class Program
{

    static void Main()
    {
        Car car = new A6();
        A6 a6 = new A6();
        car.Speed();
        a6.Speed();
        Console.ReadLine();
    }
}

Output of the above code snippet

Speed is 120kmh
Speed is 200kmh

Also, we get one warning message in IDE

A6.Speed()’ hides inherited member ‘Audi.Speed()’. To make the current member override that implementation, add the override keyword. Otherwise, add the new keyword

So, what is happening here, As we can see the A6 class does not use any keyword, so the speed method is hidden in A6 class when the parent class instance uses it. Compile not understanding whether the hiding is intended, or user has forgotten to override the method hence it generates the warning message.

Method hiding is also known as shadowing. We use the “new” keyword to implement method hiding/shadowing.


public class A6 : Audi
{
    public new void Speed()
    {
        Console.WriteLine("Speed is 200kmh");
    }
}

We have re-defined the speed method and used a “new” keyword, this will suppress the warning message. But will get the same input mentioned above.

Overloading vs Overriding

Method overloading is static or early binding polymorphism where the method with the same name can be created multiple times by changing the parameter signature. Method overloading can be implemented within the class only.


public int Add(int a, int b)
{
    return a + b;
}

public string Add(int a, int b)
{
    return (a + b).ToString();
}

Method overriding is dynamic or late binding polymorphism where we override the parent class method into child class using override keyword. Method overloading can be implemented in multiple classes in parent-child relations. It is used to override a default implementation of a base class method in the derived class.

public class Car
{
    public virtual void Speed()
    {
        Console.WriteLine("Speed is 60kmh");
    }
}


public class Audi : Car
{
    public override void Speed()
    {
        Console.WriteLine("Speed is 120kmh");
    }
}

public class A6 : Audi
{
    public override void Speed()
    {
        Console.WriteLine("Speed is 200kmh");
    }
}

Method Overloading vs Method Hiding

Method Hiding is a process when we need to hide the implementation of a method in a subclass using “new” keyword. So that parent class method implementation cannot be accessed through child class reference.

In object-oriented programming (OOP), concepts of Polymorphism remain the same in every object-oriented programming like polymorphism java, polymorphism in C++ or polymorphism in C# conceptual remains the same just programming language syntax will be changed.

OOPs Polymorphism Resource


Leave a Reply

Your email address will not be published. Required fields are marked *