Easy Tutorial
❮ Px Pt Em Convert Table Web Image Optimization ❯

Polymorphism in C

Category Programming Techniques

Everyone is familiar with the three characteristics of object-oriented programming: encapsulation, inheritance, and polymorphism, and everyone can talk about them, but most people only know what they are and do not know how the CLR implements them internally. Therefore, this article mainly talks about some concepts in polymorphism and the internal mechanisms of their implementation.

I. The Concept of Polymorphism

First, let's explain what polymorphism is: the same operation applied to different objects can have different interpretations and produce different results, which is polymorphism. In other words, it is actually the same type of instance calling the "same" method, and the result is different. The "same" here is in quotation marks because the same method here is just a method that looks the same, but in fact, the method they call is different.

Speaking of polymorphism, we cannot avoid mentioning the following concepts: overloading, overriding, virtual methods, abstract methods, and hidden methods. Let's introduce their concepts one by one.

  1. Overloading (overload): Two or more methods with the same function name but different parameter lists in the same scope (usually a class) are called overloaded. They have three characteristics (commonly known as two musts and one can):

    • The method name must be the same.

    • The parameter list must be different.

    • The return value type can be different.

    For example:

    public void Sleep()
    {
        Console.WriteLine("Animal sleeping");
    }
    public int Sleep(int time)
    {
        Console.WriteLine("Animal sleeps at {0} o'clock", time);
        return time;
    }
    
  2. Overriding (override): In the subclass, to meet its own needs, a method is redefined with a different implementation, and the override keyword is needed. The method to be overridden must be a virtual method, using the virtual keyword. Its characteristics are (three sames):

    • The same method name.

    • The same parameter list.

    • The same return value.

    For example, the definition in the parent class:

    public virtual void EatFood()
    {
        Console.WriteLine("Animal eating");
    }
    

The definition in the subclass:

public override void EatFood()
{
    Console.WriteLine("Cat eating");
    //base.EatFood();
}

>

Tip: Many students often ask about the difference between overloading and overriding, and the difference between the two is often used as a common interview question for C#. In fact, these two concepts have no relation at all, they just both have the word "over". They have no meaning to compare together, just distinguish their different definitions.

  1. Virtual Method: A method defined in the base class that allows overriding in the derived class, using the virtual keyword. For example:
    public virtual void EatFood()
    {
        Console.WriteLine("Animal eating");
    }
    

Note: Virtual methods can also be called directly. For example:

Animal a = new Animal();
a.EatFood();

The execution output is:

Animal eating
  1. Abstract Method: A method defined in the base class and must be overridden in the derived class, using the abstract keyword. For example:
    public abstract class Biology
    {
        public abstract void Live();
    }
    public class Animal : Biology
    {
        public override void Live()
        {
            Console.WriteLine("Animal's overridden Live method");
            //throw new NotImplementedException();
        } 
    }
    

Note: Abstract methods can only be defined in abstract classes. If not defined in an abstract class, the following error will occur:

>

The difference between virtual methods and abstract methods is: Because abstract classes cannot be instantiated, abstract methods cannot be called, that is to say, abstract methods can never be implemented.

  1. Hidden Method: A method defined in the derived class with the same name as a method in the base class, using the new keyword. For example, there is a method Sleep() in the base class Animal:
    public void Sleep()
    {
        Console.WriteLine("Animal Sleep");
    }
    

Then the code for defining the hidden method in the derived class Cat is:

new public void Sleep()
{
    Console.WriteLine("Cat Sleep");
}

Or:

public new void Sleep()
{
    Console.WriteLine("Cat Sleep");
}

Note:

It is possible that some students who have not read the relevant CLR books may not understand the above paragraph, so let's draw a picture to describe it:

The above diagram is what the CLR does before executing the Main function. Now let's start executing the Main function (for convenience, simplify the Main function):

//An instance of Animal
Animal a = new Animal();
//An instance of Animal, referencing a derived class Cat object
Animal ac = new Cat();
//An instance of Animal, referencing a derived class Dog object
Animal ad = new Dog();
a.Sleep();
a.EatFood();
ac.EatFood();
ad.EatFood();

The following three instances are instantiated, but they actually point to an Animal object, a Cat object, and a Dog object, as shown in the figure below:

Please note that although the variables ac and ad are both of type Animal, they point to a Cat object and a Dog object, respectively, which is the key point.

When executing a.Sleep(), since Sleep is a non-virtual instance method, the JIT compiler will find the type object corresponding to the type (Animal) of the variable that made the call (a) when making the call. Then it calls the Sleep method in that type object. If the type object does not have a Sleep method, the JIT compiler will trace back to the base class of the class (all the way to Object) to find the Sleep method.

When executing ac.EatFood, since EatFood is a virtual instance method, the JIT compiler will generate some additional code when calling, which first checks the variable that made the call (ac), then follows the reference address of the variable to find the object that made the call (Cat object), finds the type object corresponding to the object that made the call (Cat type object), and finally looks for the EatFood method in that type object. Similarly, if the EatFood method is not found in that type object, the JIT compiler will trace back to the base class of that type object.

The above describes the different execution methods of the JIT compiler when encountering calls to non-virtual instance methods and virtual instance methods of types, and this is how the different handling of these two types of methods has created one of the three characteristics of object orientation we see on the surface - polymorphism.

>

Original article link: https://www.cnblogs.com/zhangkai2237/archive/2012/12/20/2826734.html

**Click to share notes

Cancel

-

-

-

❮ Px Pt Em Convert Table Web Image Optimization ❯