Quantcast
Channel: polymorphism
Viewing all articles
Browse latest Browse all 7

polymorphism

$
0
0

Hi NikitaJohnson,

As mentioned before, in C# you can have two different behaviors:

Overriding (using virtual in base class and override in subclass)

-> The method implementation is replaced -> Polymorphic Behavior

Hiding (specifying nothing in either class or using new in the subclass)

-> The method is hidden -> no Polymorphic behavior

The difference in behavior is only visible, when you assign the subclass to a variable that has the type of the baseclass. Lets make a quick example:

We first start with the polymorphic version with virtual and override:

//Example with overriding and thus polymorphic behavior
public class Employee
{
    public virtual void DoWork()
    { }
}

public class Manager : Employee
{
    public override void DoWork()
    { }
}

And the version with method hiding (Often this is unintentional).
//Example with Method Hiding 
public class Employee
{
    public void DoWork() 
    { }
}

public class Manager : Employee
{
    //You could use the NEW keyword here in order to clarify that the 
    //hiding was intentional. The compiler will actually suggest that to you.
    //however, NEW is not required.
    public void DoWork()
    { }
}

Now, lets look at the difference in behavior:

static void Main(string[] args)
{
    Employee emp = new Employee();
    emp.DoWork(); //The method of the Employee class is called

    Manager man = new Manager();
    man.DoWork(); //The method of the Manager class is called

    //So far, so good, everything works as expected in both cases.
    //But what if we do this:

    Employee emp2 = new Manager();
    emp2.DoWork(); //This leads to different results!

    //With Hiding: The method of the baseclass Employee is called -> No Polymorphism
    //With Overriding: The method of the subclass Manager is called -> Polymorphism
}

My personal definition of polymorphism is: "We want to work with objects of different types, that share a common method. Polymorphism means that when we call the DoWork method, every object itself knows what to do. From the viewpoint of the code that uses the objects and calls the method, there is absolutely no difference."

In other words: "The responsibility of what to do is delegated to the subclass".

Take an example scenario:

We have a List<Employee> that contains Managers, Secretaries and Consultants that are all subclasses of Employee.  We can now foreach through the list and call DoWork() on every object.

Snippet 1:

List<Employee> emps = new List<Employee>();
emps.Add(new Manager());
emps.Add(new Secretary());
emps.Add(new Consultant()); foreach (Employee emp in emps) { emp.DoWork(); }


We know that DoWork is there because all the classes inherit from Employee. However, what happens is delegated to the subclasses themselves. They have the option to override DoWork with an implementation of their own.

If we would not have polymorphism, we would have to solve the problem like this:

Snippet 2:

List<Employee> emps = new List<Employee>();
foreach (Employee emp in emps)
{
    if(emp is Manager)
    {
        //Manager implementation
    }
    else if (emp is Secretary)
    {
        //Secretary implementation
    }
    //and so forth...
}

I think These two code snippets Show the difference very well.

In snippet 1, the code that uses the objects decided on the implementation of DoWork.

In snippet 2, the objects themselves decide about the implementation of DoWork.

Imagine that the code in snippet 1 and 2 was in a library that is not under your control. You are just using it. Now, you have a requirement that you need to add a new TeamLeader object to your implementation. So you go ahead and create a new class that extends from the Employee class and overrides DoWork() with a custom implemenation.

With snippet 1, it will just work thanks to polymorphism.

Snippet 2 would need to be modified, which you couldn't because it is not your code.

This concept follows the open-closed principle. Your code should be closed for modification but open for Extension. Extending a class and overriding a method is a very common way to add functionality by extension. The objects can than be given to existing code and it will just work.

Probably the most famous example within the .NET Framework are the ADO.NET classes.

There are generic (= database agnostic) classes for DB Access such as DbConnection, DbCommand, etc.

And there are custom implementations, such as SqlConnection, SqlCommand or OracleConnection and OracleCommand.

The Beauty here is that you can implement your own MySelfCreatedDbConnection and MySelfCreatedDbCommand class by using inheritance and polymorphism and the framework classes would just know how to use your new classes. Your custom implementations are encapsulated in your classes. From the Framework perspective, it makes no difference whether it calls OpenConnection() on a SqlConnection, OracleConnection or MySelfCreatedDbConnection. However, what happens when the method is called would be very different.

Phew, that got kind of long. I hope that I could shed some light on this not so trivial concept!

Good night!



Viewing all articles
Browse latest Browse all 7

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>