How to implement polymorphism in C#

Polymorphism

Polymorphism

Take advantage of polymorphism to isolate interface from implementation and promote flexibility in your designs

RELATED TOPICS

Polymorphism refers to the ability to present the same interface for different forms. Although the concept of polymorphism is the same in all programming languages that support it, its implementation differs from one language to another.

The three types of polymorphism are overloading, parametric, and inclusion. Polymorphism helps to promote flexibility in designs by allowing the same method to have different implementations. In essence, you can leverage polymorphism to separate interface from implementation. It promotes code reuse and separation of concerns in your application.

Overloading polymorphism is a type that exists in classes that are independent of each other -- they are not related (inheritance, dependency, etc.) to each other in any way. As an example, you can have two distinct classes not related in any way with each other and having a method with the same name. Operator overloading is an example of this type of polymorphism.

Parametric polymorphism, or template polymorphism, is a type where you have more than one method in your class with identical names but varying parameters, i.e., they all have the same method names, but they differ in the parameters.

Inclusion polymorphism is also known as redefinition or method overriding. In this type of polymorphism, a sub class can redefine a method of the base class. This ability is also known as specialization.

Parametric polymorphism

This refers to the form of polymorphism where you have more than one method in your class that has the same name but they differ in their method signatures. A method signature comprises of the return type of the method, the type of the parameters to the method and the sequence of these parameters. Hence, a method that accepts an integer and a character as an argument differs in the signature from another method that accepts a character and an integer as arguments even though the return types of both these methods (having identical method names) are the same. The compiler determines the exact method to be called by comparing the method signatures of the overloaded methods.

The following code listing illustrates how method overloading can be implemented.

public enum Severity

    {

        Informational, Warning, Critical

    }

    public class Logger

    {

        public void Log(string message)

        {

            //Some code

        }

        public void Log(string message, Severity severity)

        {

            //Some code

        }

    }

Refer to the code listing above. Note how the Log() method has been overloaded.  This is an example of compile time polymorphism.

Inclusion polymorphism

Inclusion polymorphism, or method overriding, can be achieved in C# using virtual methods. In method overriding, you have methods having identical signatures present in both the base and the derived classes. You would typically want to use virtual methods to implement run-time polymorphism or late binding. Note that a virtual method is one that is declared as virtual in the base class and you can allow the subclasses of the type to override the virtual method(s).

The following code snippet shows two classes -- the base class named Logger that contains a virtual method called Log and a derived class named FileLogger that extends the Logger class and overrides the Log method of the base class.

public class Logger

    {

        public virtual void Log(string message)

        {

            Console.WriteLine("Inside the Log method of the base class Logger");

        }

    }

    public class FileLogger : Logger

    {

        public override void Log(string message)

        {

            Console.WriteLine("Inside the Log method of the FileLogger class");

        }

    }

This is an example of method overriding. Both the base and the derived classes have the same method with identical signatures. We use method overriding to implement run time polymorphism or late binding. The following code snippet shows how the Log method can be called using a reference of the base class.

static void Main(string[] args)

        {

            Logger logger = new FileLogger();

            logger.Log("Hello World!");

            Console.ReadKey();

        }

When you execute the above code snippet, the Log method of the derived class, i.e., the Filelogger class would be invoked. If the Log method wasn’t declared as virtual in the base class, the base version of the Log method would have been called instead. Since this binding occurs late at run-time, this type of polymorphism is known as run-time polymorphism or late binding.

This article is published as part of the IDG Contributor Network. Want to Join?

RELATED TOPICS
From CIO: 8 Free Online Courses to Grow Your Tech Skills
View Comments
Join the discussion
Be the first to comment on this article. Our Commenting Policies