Polymorphism in C is well understood

  • 2020-06-07 05:10:56
  • OfStack

The first two are relatively easy to understand, but it may be difficult for beginners to understand polymorphism, especially in depth. I have always believed that the best way to learn OO is to combine practice. Encapsulation and inheritance can be applied in practical work everywhere, but what about polymorphism? It may not be, it may not be used inadvertently and it doesn't correspond to the word "polymorphic." Here, we discuss, personal ability is limited, shortcomings also please correct.

I've seen this question before: If the interviewer asked you to describe polymorphism in 1 sentence, as succinct as possible, what would you say? Of course, there are many answers, and everyone understands and expresses them differently, but I tend to describe them this way: different objects implemented through inheritance call the same methods and behave differently, which is called polymorphism.

Case 1:


public class Animal
    {
        public virtual void Eat()
        {
            Console.WriteLine("Animal eat");
        }
    }
    public class Cat : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Cat eat");
        }
    }
    public class Dog : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Dog eat");
        }
    }
    class Tester
    {
        static void Main(string[] args)
        {
            Animal[] animals = new Animal[3];
            animals[0] = new Animal();
            animals[1] = new Cat();
            animals[2] = new Dog();
            for (int i = 0; i < 3; i++)
            {
                animals[i].Eat();
            }
        }
    }

The output is as follows:
Animal eat...
Cat eat...
Dog eat...

In the example above, inheritance causes different objects in the array of Animal objects to behave differently when calling the Eat() method.

The implementation of polymorphism seems simple, and it is not easy to fully understand and flexibly use the polymorphism mechanism of c#. There are many points to be paid attention to.

1. new
Let's look at the following example.

Example 2:


public class Animal
    {
        public virtual void Eat()
        {
            Console.WriteLine("Animal eat");
        }
    }
    public class Cat : Animal
    {
        public new void Eat()
        {
            Console.WriteLine("Cat eat");
        }
    }
    class Tester
    {
        static void Main(string[] args)
        {
            Animal a = new Animal();
            a.Eat();
            Animal ac = new Cat();
            ac.Eat();
            Cat c = new Cat();
            c.Eat();
        }
    }

The operation result is:
Animal eat...
Animal eat...
Cat eat...

As you can see, when the Eat() method of derived class Cat is decorated with new, the Cat object is converted to an Animal object, and the Eat() method in the Animal class is called. It is understood that the use of the new keyword makes the Eat() method in Cat and the Eat() method in Animal two unrelated methods that happen to have the same name. As a result, the Eat() method in the Animal class is not modified by virtual, with or without access rights, and does not affect the Eat() method of Cat () (just because the new keyword is used, the compiler prints a warning if the Cat class does not inherit from the Animal class).

I think it's intentional because sometimes that's what we do. Strictly speaking, we cannot say that polymorphic is achieved by using new, only that it happens to achieve polymorphic effects at certain times.

2.override achieves polymorphism
True polymorphism is achieved using override. Looking back to the previous example 1, in the base class Animal, the method Eat() is marked as a virtual method with virtual, and the derived classes Cat and Dog use override to modify Eat() to achieve polymorphism. Note that to decorate a method in a class with override, the class must inherit from its parent a corresponding virtual method decorated with virtual, or the compiler will report an error.

I think that's it. One more question, I don't know if you want to. It's how polymorphism is implemented in multi-layer inheritance. For example, class A is the base class with a virtual method method() (virtual modified), class B inherits from class A and overrides method() (override modified), now class C inherits from class B, can we continue to overwrite method() and implement polymorphism? Look at the following example.

Example 3:


public class Animal
    {
        public virtual void Eat()
        {
            Console.WriteLine("Animal eat");
        }
    }
    public class Dog : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Dog eat");
        }
    }
    public class WolfDog : Dog
    {
        public override void Eat()
        {
            Console.WriteLine("WolfDog eat");
        }
    }
    class Tester
    {
        static void Main(string[] args)
        {
            Animal[] animals = new Animal[3];
            animals[0] = new Animal();
            animals[1] = new Dog();
            animals[2] = new WolfDog();
            for (int i = 0; i < 3; i++)
            {
                animals[i].Eat();
            }
        }
}

The operation result is:
Animal eat...
Dog eat...
WolfDog eat...

In the example above, class Dog inherits from class Animal and overrides the method Eat(). Class WolfDog inherits from Dog and overrides the method Eat() once more, implementing polymorphism well. A method that has been overridden in a parent class can be overridden in a subclass regardless of how many layers it inherits, that is, if the superclass method is decorated with override and if the subclass inherits the method, it can be decorated with override, which is how polymorphism in multilayer inheritance is implemented. To terminate this overwriting, simply override the method with the sealed keyword.

3. abstract-override achieves polymorphism
Let's first discuss the abstract method decorated with abstract in 1. Abstract methods are defined, not implemented. If a class contains abstract methods, that class must also be declared abstract with abstract. An abstract class cannot be instantiated. For abstract methods in a class, the derived class can be overridden with override. If not overridden, the derived class will also be declared as an abstract class. Look at the following example.

Example 4:


public abstract class Animal
    {
      public abstract void Eat();
    }
    public class Cat : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Cat eat");
        }
    }
    public class Dog : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Dog eat");
        }
    }
    public class WolfDog : Dog
    {
        public override void Eat()
        {
            Console.WriteLine("Wolfdog eat");
        }
    }
    class Tester
    {
        static void Main(string[] args)
        {
            Animal[] animals = new Animal[3];
            animals[0] = new Cat();
            animals[1] = new Dog();
            animals[2] = new WolfDog();
            for (int i = 0; i < animals.Length; i++)
            {
                animals[i].Eat();
            }
        }
    }

The operation result is:
Cat eat...
Dog eat...
Wolfdog eat...

As you can see above, using abstract-override and ES134en-override1 can implement polymorphism in the same way, including multi-layer inheritance. The difference is that classes that contain virtual methods can be instantiated, while classes that contain abstract methods cannot be.

Above is my shallow understanding of polymorphism in c# 1, if there is any mistake, welcome to criticize and correct!


Related articles: