On the charm of C # polymorphism (virtual method, abstraction, interface implementation)

Source: Internet
Author: User

Foreword: We all know the three main features of object-oriented: encapsulation, inheritance, polymorphism. Encapsulation and inheritance for beginners is better understanding, but to understand polymorphism, especially in-depth understanding, beginners often exist there are a lot of confusion, why so can? Sometimes the feeling is incredible, thus, the object-oriented charm embodies out, that is polymorphic, polymorphic use of good, can improve the extension of the program. Commonly used design patterns, such as simple factory design patterns, the core is polymorphic.

In fact, polymorphism is: Allows pointers of the subclass type to be assigned to a pointer of the parent class type. That is, the same operation works on different objects, and can have different interpretations, resulting in different execution results. At run time, you can invoke methods in the derived class by pointing to a pointer to the base class. If this side does not understand can first put, first look at the following cases, after reading to understand the sentence, it is easy to understand.
Before understanding polymorphism, we must first understand the object-oriented Richter substitution principle and the open closure principle.

The Richter substitution principle (Liskov Substitution Principle): derived class (subclass) objects are used to replace their base class (superclass) objects. The popular point of understanding is "subclass is the parent class", for example, "Man is human, man is not necessarily a man", when you need a parent class type of object can give a subclass type of object, when a subclass type object is required to give a parent class type object is not possible!

Open closure principle (open Closed Principle): Package changes, reduce coupling, software entities should be extensible, not modifiable. In other words, the extension is open, and the modification is closed. Therefore, the open closure principle is mainly embodied in two aspects: open to expansion, meaning that there are new requirements or changes, the existing code can be extended to adapt to the new situation. Enclosing a modification means that once the class is designed, it can do its work independently, rather than making any modifications to the class.

Having a good understanding of these two principles gives you a better understanding of polymorphism.

First, let's look at how to use virtual methods to achieve polymorphic

We all know that Magpie (Magpie), Eagle (Eagle), Penguin (Penguin) are belong to birds, we can according to the common characteristics of the three birds (Bird) as a parent, magpies like to eat insects, eagles like to eat meat, penguins like to eat fish.

Create the base class bird as follows, adding a virtual method eat ():

    <summary>    //birds: Parent//    </summary> public    class Bird    {        ///<summary>/ Eat: Virtual method///        </summary> public        virtual void Eat ()        {            Console.WriteLine ("I Am a little bird, I like to eat worms ~");        }    }

The subclass Magpie is created as follows, inheriting the parent class bird, overriding the virtual method eat () in the parent class bird:

    <summary>    //Magpie: Subclass///    </summary> public  class Magpie:bird    {        // <summary>        ///rewrite the parent class in the Eat method        ///</summary> public override void Eat ()        {            Console.WriteLine ("I am a magpie, I like to eat insects ~");        }    

Create a subclass eagle as follows, inheriting the parent class bird, overriding the virtual method eat () in the parent class bird:

    <summary>    //Eagle: Subclass///    </summary> public  class Eagle:bird {//        < Summary>        ///override Eat method in parent class        ///</summary> public override void Eat ()        {            Console.WriteLine ("I am an eagle, I like to eat meat ~");        }    

Create a subclass penguin as follows, inheriting the parent class bird, overriding the virtual method eat () in the parent class bird:

    <summary>    //Penguins: Subclass///    </summary> public  class Penguin:bird    {        // <summary>        ///rewrite the parent class in the Eat method        ///</summary> public override void Eat ()        {            Console.WriteLine ("I Am a little penguin, I like to eat fish ~");        }    

To this, a base class, three subclasses have been created, and then we see in the main function how the polymorphism is embodied.

    static void Main (string[] args)    {        //Create a Bird base class array, add base class Bird object, Magpie object, Eagle object, Penguin object        bird[] birds = { New                        Bird (),                       new Magpie (),                       new Eagle (),                       new Penguin ()        };        Iterate over the birds array        foreach (Bird Bird in birds)        {            Bird. Eat ();        }        Console.readkey ();    }

Operation Result:

Thus, the subclass Magpie,eagle,penguin object can be assigned to the parent class object, which means that the parent class type pointer can point to the subclass type object, which shows the Richter substitution principle.

The parent class object calls its own eat () method, which actually shows the parent class type pointer to the subclass type Object that overrides the parent class eat after the method. This is polymorphism.

What is the role of polymorphism?
In fact, the role of polymorphism is to consider different sub-class objects as the parent class, you can block the differences between different sub-objects, write generic code, make general programming to adapt to the changing needs.
The above procedure also embodies the principle of open closure, if the following colleagues need to expand my program, but also want to add another owl (owl), it is easy to add an owl class file, inherit bird, rewrite the Eat () method, add to the parent class object can be. At this point, the extension of the program has been improved without needing to see how the source code is implemented to extend the new functionality. This is the benefit of polymorphism.

Let's take a look at how abstraction can be used to achieve polymorphism.

As in the case of bird, we find that we do not need to use the object it creates at all, and the meaning of its existence is to be inherited by subclasses. So we can use abstract classes to optimize it.
We change the bird parent class to abstract, and the Eat () method to an abstract method. The code is as follows:

    <summary>    //birds: base class///    </summary> public    abstract class Bird {//        <summary >///        Eat: Abstract method        ///</summary> public abstract void Eat ();    }

Abstract class Bird Add a eat () abstract method, no method body. Nor can it be instantiated.
Other classes Magpie,eagle,penguin code, and subclasses use the Override keyword to override the abstract method in the parent class.
The main function bird cannot create the object, the code is slightly modified as follows:

        static void Main (string[] args)        {            //Create an array of Bird base classes, add Magpie object, Eagle object, Penguin object            bird[] birds = {                            new Magpie (),                           new Eagle (),                           new Penguin ()            };            Iterate over the birds array            foreach (Bird Bird in birds)            {                Bird. Eat ();            }            Console.readkey ();        }

Execution Result:

Therefore, we choose to use virtual methods to achieve polymorphism or abstract class abstract method to achieve polymorphism, depending on whether we need to use the base class instantiation of the object.

For example, now that there is an employee class as the base class, the Projectmanager class inherits from employee, this time we need to use the virtual method to implement polymorphism, because we want to use the object created by employee, these objects are ordinary employee objects.
For example, now that there is a person class as the base class, the Student,teacher class inherits the person, and we need to use objects created by Student and Teacher, without having to use the object created by person.
So in this case, the person can be completely written as abstract class.

All in all, the use of virtual methods, or abstract class abstract methods to achieve polymorphism, depending on the circumstances, what? The above two points I said ~

Next ~ ~ ~

I want to ask a question, magpies and eagles can fly, this ability to fly, how can I achieve it?

XXX Answer: "Adding a Fly method to the parent class bird is no good."

I ask again: "OK, according to you, the Penguin inherits the Father Class bird, but cannot the penguin cannot fly ah, such in the parent class bird to add the fly method is not suitable?" ”

XXX Answer: "That can fly in the birds to add fly method is not OK?" ”

Yes, this is possible, the function can be fully implemented, but this violates the object-oriented open closure principle, next time I want to expand a bird such as Owl (owl), I will go to the source code to see how fly is implemented, and then add the Fly method in Owl, the same function, duplicate code, This is unreasonable, the procedure is not easy to expand;

Secondly, if I also want to add an airplane class (Plane), I inherit the bird parent class, appropriate?

Obviously, it's not appropriate! So we need a rule, that is the interface, Magpies, eagles, airplanes, I have realized this interface, it can fly, and penguins I do not realize this interface, it can not fly ~ ~

OK, let's introduce how the interface implements polymorphism ~

Add an interface iflyable with the following code:

    <summary>    ///    /Fly Interface    ///</summary> public interface iflyable    {        void Fly ();    }

Magpie Magpie implements the Iflyable interface, the code is as follows:

    <summary>    ///Magpie: Sub-class, implement Iflyable interface///    </summary> public  class magpie:bird,iflyable    {        //<summary>        ///Rewrite parent class Bird in Eat method        ///</summary> public override void Eat ()        {            Console.WriteLine ("I am a magpie, I like to eat insects ~");        }        <summary>        ////Implement Iflyable interface method        ///</summary> public void Fly ()        {            Console.WriteLine ("I am a magpie, I can fly Oh ~ ~");        }    }

Eagle Eagle implements the Iflyable interface with the following code:

    <summary>    //Eagle: Subclass implements the Fly interface///    </summary> public  class eagle:bird,iflyable    {        //<summary>        ///Rewrite parent class Bird in Eat method        ///</summary> public override void Eat ()        {            Console.WriteLine ("I am an eagle, I like to eat meat ~");        <summary>        ////Implement Iflyable interface method        ///</summary> public void Fly ()        {            Console.WriteLine ("I am an eagle, I can fly Oh ~ ~");        }    }

In the main function of main, create an array of iflyable interfaces, the code is implemented as follows:

    static void Main (string[] args)    {        //Create an array of iflyable interfaces, add Magpie objects, Eagle object        iflyable[] flys = {                        new Magpie (),                       new Eagle ()        };        Iterate over the flys array        foreach (Iflyable fly in flys)        {            fly. Fly ();        }        Console.readkey ();    }

Execution Result:


Because Penguin Penguin does not implement Iflyable interface, so penguins can not be assigned to Iflyable interface object, so penguins, can not fly ~

Well, just now I mentioned that the plane can fly, inherit bird inappropriate problem, now has the interface, this problem can also be solved. As below, I add an airplane plane class, implement the Iflyable interface, the code is as follows:

    <summary>///    aircraft class, implement Iflyable interface///    </summary> public  class plane:iflyable    {        //        /<summary>///Implement Interface method        ///</summary> public void Fly ()        {            Console.WriteLine ("I am a plane, I can fly ~ ~");}    }

In the main function of main, the interface iflyable an array, adding plane objects:

    Class program    {        static void Main (string[] args)        {            //Create an array of iflyable interfaces, add Magpie object, Eagle object, plane object            iflyable[] flys = {                            new Magpie (),                           new Eagle (),                           new Plane ()            };            Iterate over the flys array            foreach (Iflyable fly in flys)            {                fly. Fly ();            }            Console.readkey ();        }    }

Execution Result:

Thus, it can be seen that using the interface to achieve the scalability of the polymorphic program has been greatly improved, whether it is to expand a butterfly (Butterfly), or the bird (birder) to create a class, implement this interface, in the main function to add the object can be.
Also do not need to see how the source code is implemented, embodies the principle of open closure!

Interface fully embodies the charm of polymorphism ~ ~

The above through some small cases, to introduce the object-oriented three ways to achieve polymorphism, perhaps some people will ask, how to use the multi-state in the project? How does the fascination of polymorphism manifest itself in the project?
So next I'm going to make a simple object-oriented calculator to show you how polymorphic is used in the project!

Subtraction operation, we can extract a calculation class according to the generality, which contains two attributes Number1 and Number2, there is an abstract method compute (); The code is as follows:

    <summary>//compute Parent///    </summary> public    abstract class Calculate    {public        int Number1        {            get;            Set;        }        public int Number2        {            get;            Set;        }        public abstract int Compute ();    }

Next, we add a adder that inherits the Calculate parent class:

    <summary>//Adder///    </summary> public    class Addition:calculate    {        //< Summary>///Implement Parent calculation method///</summary>///        <returns> addition calculation result </returns>        public override int Compute ()        {            return Number1 + Number2;        }    }

Add a subtraction and inherit the Calculate parent class:

    <summary>//subtraction device///    </summary> public    class Subtraction:calculate    {        //< Summary>///Implement Parent calculation method///</summary>///        <returns> Subtraction Calculation results </returns>        public Override int Compute ()        {            return number1-number2;        }    }

In the main form FormMain, write the Compute event Btn_compute_click, which is the following code:

    private void Btn_compute_click (object sender, EventArgs e) {//Get two parameters int number1 = Convert.ToInt32 (t        His.txt_Number1.Text.Trim ());        int number2 = Convert.ToInt32 (This.txt_Number2.Text.Trim ());        Gets the operator string operation = Cbb_Operator.Text.Trim ();        By operator, returns the parent class type Calculate Calculate = getcalculateresult (operation); Calculate.        Number1 = Number1; Calculate.        Number2 = number2; Using polymorphic, returns the result of the operation, string result = Calculate.compute ().        ToString ();    This.lab_Result.Text = Result;    }///<summary>///by operator, returns the parent class type///</summary>//<param name= "Operation" ></param> <returns></returns> Private Calculate Getcalculateresult (string operation) {Calculate Calc        Ulate = null;                Switch (operation) {case "+": Calculate = new addition ();            Break Case "-": Calculate = new Subtraction();        Break    } return calculate; }

In this event, the main call Getcalculateresult method, through the operator, create a corresponding subtraction calculator subclass, and then assign to the parent class, in fact, this is the design pattern of the simple factory design pattern, I give you an operator you give me a corresponding subtraction calculator sub-class, Return to me. In fact, most of the design patterns of the core is polymorphic, mastering a lot of states, design patterns are also easy to look at.

At this stage the work has been completed, but after a period of time, and add new requirements, I also want to expand a multiplication, that good, very simple just create a multiplication calculator inherit calculate parent class, see the code:

    <summary>///Multiplication Calculator///    </summary> public  class Multiplication:calculate    { Public        override int Compute ()        {            return number1*number2;        }    }

Then add a case to the Getcalculateresult function:

    Switch (operation)    {case        "+":            calculate = new addition ();            break;        Case "-":            calculate = new Subtraction ();            break;        Case "*":            calculate = new Multiplication ();            break;    }

Execution Result:

OK, so convenient, a new function is extended, I do not need to see how the source code is implemented, this is the benefits of polymorphism!

On the charm of C # polymorphism (virtual method, abstraction, interface implementation)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.