This is the 26th day of my participation in the August Text Challenge.More challenges in August

Preface 👻

Anyone who has studied programming knows the term “OOP thought “-” object-oriented programming “\color{FF66FF}{“OOP thought “}”OOP thought “-” Object Oriented programming “\color{FF66FF}{” Object Oriented programming “}” Object Oriented programming” Object Oriented Programming (OOP) is a computer Programming architecture. A basic principle of OOP is that a computer program is composed of a single unit or object that acts as a subroutine. OOP achieves the three main goals of software engineering: reuse, flexibility, and extensibility. In order to realize global operation, each object can receive information, process data and send information to other objects. Core idea: encapsulation, inheritance, polymorphism.

Previous posts have covered the basics of C#, including basic syntax, operators, arrays, and more.

Polymorphic \color{00ff00}{polymorphic} polymorphisms are the most common concepts in C#


C# polymorphism 🎄

Polymorphism is the ability to have many different manifestations or forms of the same behavior.

polymorphismIt means multiple forms. In the object-oriented programming paradigm, polymorphism is often expressed as “one interface, many functions”. Polymorphism can be static or dynamic. inStatic polymorphismIn, the response of a function occurs at compile time. inDynamic polymorphismIn, the response of a function occurs at run time. In C#, every type is polymorphic because all types, including user-defined types, inherit from Object. Polymorphism is the same interface, using different instances to perform different operations, as shown in the figure below:

In real life, for example, we press F1:

  • The help document for AS 3 is displayed in the Flash interface.
  • If the current popup under Word is Word help;
  • What pops up under Windows is Windows Help and Support.
  • The same event occurring on different objects produces different results.

Static polymorphism

At compile time, the mechanism by which functions and objects are joined is called early binding, also known as static binding. C# provides two techniques for implementing static polymorphism. Are:

  • Function overloading
  • Operator overloading

Function overloading

You can have multiple definitions of the same function name in the same scope. Functions must be defined differently from each other, either by different types of arguments in the argument list or by different numbers of arguments. You cannot overload function declarations that have only different return types.

The following example shows the same function Add() that adds different numbers of arguments:

The instanceusing System;
namespace PolymorphismApplication
{
    public class TestData  
    {  
        public int Add(int a, int b, int c)  
        {  
            return a + b + c;  
        }  
        public int Add(int a, int b)  
        {  
            returna + b; }}class Program  
    {  
        static void Main(string[] args)  
        {  
            TestData dataClass = new TestData();
            int add1 = dataClass.Add(1.2);  
            int add2 = dataClass.Add(1.2.3);

            Console.WriteLine("add1 :" + add1);
            Console.WriteLine("add2 :"+ add2); }}}Copy the code

The following example demonstrates several of the same functions print() to print different data types:

The instanceusing System;
namespace PolymorphismApplication
{
   class Printdata
   {
      void print(int i)
      {
         Console.WriteLine("Output integer: {0}", i );
      }

      void print(double f)
      {
         Console.WriteLine("Output floating point: {0}" , f);
      }

      void print(string s)
      {
         Console.WriteLine(Output string: {0}, s);
      }
      static void Main(string[] args)
      {
         Printdata p = new Printdata();
         // Call print to print integers
         p.print(1);
         // Call print to print floating point numbers
         p.print(1.23);
         // Call print to print the string
         p.print("Hello Runoob"); Console.ReadKey(); }}}Copy the code

When the above code is compiled and executed, it produces the following results:

Output integer: 1 Output floating point: 1.23 Output string: Hello Runoob


C# operator overloading

You can redefine or overload the built-in operators in C#. Therefore, programmers can also use operators of user-defined types. Overloaded operators are functions with special names defined by the keyword operator followed by the operator’s symbol. Like other functions, overloaded operators have return types and argument lists.

For example, look at the following function:

public static Box operator+ (Box b, Box c)
{
   Box box = new Box();
   box.length = b.length + c.length;
   box.breadth = b.breadth + c.breadth;
   box.height = b.height + c.height;
   return box;
}
Copy the code

The above function implements the addition operator (+) for the user-defined class Box. It adds the properties of the two Box objects and returns the added Box object.


Implementation of operator overloading

The following program demonstrates the complete implementation:

The instanceusing System;

namespace OperatorOvlApplication
{
   class Box
   {
      private double length;      / / the length
      private double breadth;     / / width
      private double height;      / / height

      public double getVolume()
      {
         return length * breadth * height;
      }
      public void setLength( double len )
      {
         length = len;
      }

      public void setBreadth( double bre )
      {
         breadth = bre;
      }

      public void setHeight( double hei )
      {
         height = hei;
      }
      // Override the + operator to add two Box objects
      public static Box operator+ (Box b, Box c)
      {
         Box box = new Box();
         box.length = b.length + c.length;
         box.breadth = b.breadth + c.breadth;
         box.height = b.height + c.height;
         returnbox; }}class Tester
   {
      static void Main(string[] args)
      {
         Box Box1 = new Box();         // declare Box1 of type Box
         Box Box2 = new Box();         // declare Box2 of type Box
         Box Box3 = new Box();         // declare Box3 of type Box
         double volume = 0.0;          / / volume

         / / Box1 elaborate
         Box1.setLength(6.0);
         Box1.setBreadth(7.0);
         Box1.setHeight(5.0);

         / / Box2 elaborate
         Box2.setLength(12.0);
         Box2.setBreadth(13.0);
         Box2.setHeight(10.0);

         // The volume of Box1
         volume = Box1.getVolume();
         Console.WriteLine("Box1 volume: {0}", volume);

         // The volume of Box2
         volume = Box2.getVolume();
         Console.WriteLine("Box2 volume: {0}", volume);

         // Add the two objects
         Box3 = Box1 + Box2;

         // The volume of Box3
         volume = Box3.getVolume();
         Console.WriteLine("Box3 volume: {0}", volume); Console.ReadKey(); }}}Copy the code

When the above code is compiled and executed, it produces the following results:

Box1 volume: 210 Box2 volume: 1560 Box3 volume: 5400


Overloaded and unoverloaded operators

The following table describes the operator overloading capabilities in C# :

The operator describe
The +, -,! , ~ + + and – These unary operators have only one operand and can be overloaded
+, -, *, /, % These binary operators take two operands and can be overloaded
= =,! =, <, >, <=, >= These comparison operators can be overloaded
&&, These conditional logic operators cannot be overridden directly
+=, -=, *=, /=, %= These assignment operators cannot be overloaded
=,.,? :, ->, new, is, sizeof, typeof These operators cannot be overloaded

For the above discussion, let’s extend the above example to overload more operators:

The instanceusing System;

namespace OperatorOvlApplication
{
    class Box
    {
       private double length;      / / the length
       private double breadth;     / / width
       private double height;      / / height
     
       public double getVolume()
       {
         return length * breadth * height;
       }
      public void setLength( double len )
      {
          length = len;
      }

      public void setBreadth( double bre )
      {
          breadth = bre;
      }

      public void setHeight( double hei )
      {
          height = hei;
      }
      // Override the + operator to add two Box objects
      public static Box operator+ (Box b, Box c)
      {
          Box box = new Box();
          box.length = b.length + c.length;
          box.breadth = b.breadth + c.breadth;
          box.height = b.height + c.height;
          return box;
      }
     
      public static bool operator == (Box lhs, Box rhs)
      {
          bool status = false;
          if (lhs.length == rhs.length && lhs.height == rhs.height
             && lhs.breadth == rhs.breadth)
          {
              status = true;
          }
          return status;
      }
      public static bool operator! =(Box lhs, Box rhs) {bool status = false;
          if(lhs.length ! = rhs.length || lhs.height ! = rhs.height || lhs.breadth ! = rhs.breadth) { status =true;
          }
          return status;
      }
      public static bool operator <(Box lhs, Box rhs)
      {
          bool status = false;
          if (lhs.length < rhs.length && lhs.height
              < rhs.height && lhs.breadth < rhs.breadth)
          {
              status = true;
          }
          return status;
      }

      public static bool operator >(Box lhs, Box rhs)
      {
          bool status = false;
          if (lhs.length > rhs.length && lhs.height
              > rhs.height && lhs.breadth > rhs.breadth)
          {
              status = true;
          }
          return status;
      }

      public static bool operator <=(Box lhs, Box rhs)
      {
          bool status = false;
          if (lhs.length <= rhs.length && lhs.height
              <= rhs.height && lhs.breadth <= rhs.breadth)
          {
              status = true;
          }
          return status;
      }

      public static bool operator >=(Box lhs, Box rhs)
      {
          bool status = false;
          if (lhs.length >= rhs.length && lhs.height
             >= rhs.height && lhs.breadth >= rhs.breadth)
          {
              status = true;
          }
          return status;
      }
      public override string ToString()
      {
          return String.Format("({0}, {1}, {2})", length, breadth, height); }}class Tester
   {
      static void Main(string[] args)
      {
        Box Box1 = new Box();          // declare Box1 of type Box
        Box Box2 = new Box();          // declare Box2 of type Box
        Box Box3 = new Box();          // declare Box3 of type Box
        Box Box4 = new Box();
        double volume = 0.0;   / / volume

        / / Box1 elaborate
        Box1.setLength(6.0);
        Box1.setBreadth(7.0);
        Box1.setHeight(5.0);

        / / Box2 elaborate
        Box2.setLength(12.0);
        Box2.setBreadth(13.0);
        Box2.setHeight(10.0);

       // Display two boxes using overloaded ToString()
        Console.WriteLine("Box1: {0}", Box1.ToString());
        Console.WriteLine("Box2: {0}", Box2.ToString());
       
        // The volume of Box1
        volume = Box1.getVolume();
        Console.WriteLine("Box1 volume: {0}", volume);

        // The volume of Box2
        volume = Box2.getVolume();
        Console.WriteLine("Box2 volume: {0}", volume);

        // Add the two objects
        Box3 = Box1 + Box2;
        Console.WriteLine("Box3: {0}", Box3.ToString());
        // The volume of Box3
        volume = Box3.getVolume();
        Console.WriteLine("Box3 volume: {0}", volume);

        //comparing the boxes
        if (Box1 > Box2)
          Console.WriteLine("Box1 is greater than the Box2");
        else
          Console.WriteLine("Box1 is not greater than Box2");
        if (Box1 < Box2)
          Console.WriteLine("Less than Box2 Box1");
        else
          Console.WriteLine("Box1 is not less than Box2");
        if (Box1 >= Box2)
          Console.WriteLine("Box1 is greater than or equal to Box2");
        else
          Console.WriteLine("Box1 is not greater than or equal to Box2");
        if (Box1 <= Box2)
          Console.WriteLine(Box1 is less than or equal to Box2);
        else
          Console.WriteLine(Box1 is not less than or equal to Box2.);
        if(Box1 ! = Box2) Console.WriteLine("Box1 is not equal to Box2");
        else
          Console.WriteLine("Box1 equals Box2");
        Box4 = Box3;
        if (Box3 == Box4)
          Console.WriteLine("Box3 equals Box4");
        else
          Console.WriteLine("Box3 is not Box4."); Console.ReadKey(); }}}Copy the code

When the above code is compiled and executed, it produces the following results:

Box1: (6, 7, 5) Box2: (12, 13, 10) Box1 volume: 210 Box2 volume: 1560 Box3: (18, 20, 15) Box3 volume: (18, 20, 15) 5400 Box1 is not greater than Box2, Box1 is less than or equal to Box2, Box1 is not equal to Box2, Box3 is equal to Box4


Dynamic polymorphism

C# allows you to use the keyword abstract to create abstract classes that provide partial class implementations of the interface. Implementation is complete when a derived class inherits from the abstract class. Abstract classes contain abstract methods that can be implemented by derived classes. Derived classes have more specialized functionality.

Note that here are some rules for abstract classes:

  • Cannot create an instance of an abstract class.
  • You cannot declare an abstract method outside of an abstract class.
  • You can declare a class to be sealed by placing the keyword sealed before the class definition. When a class is declared sealed, it cannot be inherited. An abstract class cannot be declared as sealed.

The following program demonstrates an abstract class:

The instanceusing System;
namespace PolymorphismApplication
{
   abstract class Shape
   {
       abstract public int area();
   }
   class Rectangle:  Shape
   {
      private int length;
      private int width;
      public Rectangle( int a=0.int b=0)
      {
         length = a;
         width = b;
      }
      public override int area ()
      {
         Console.WriteLine("Rectangle class size:");
         return(width * length); }}class RectangleTester
   {
      static void Main(string[] args)
      {
         Rectangle r = new Rectangle(10.7);
         double a = r.area();
         Console.WriteLine("Area: {0}",a); Console.ReadKey(); }}}Copy the code

When the above code is compiled and executed, it produces the following results:

Rectangle class size: area: 70

Virtual methods can be used when a function defined in a class needs to be implemented in an inherited class.

Virtual methods are declared using the keyword virtual.

Virtual methods can have different implementations in different inherited classes.

Calls to virtual methods occur at run time.

Dynamic polymorphism is implemented through abstract classes and virtual methods.

The following example creates the Shape base class and its derived classes Circle, Rectangle, and Triangle. Shape provides a virtual method called Draw that is overridden in each derived class to Draw the specified Shape of that class.

The instanceusing System;
using System.Collections.Generic;

public class Shape
{
    public int X { get; private set; }
    public int Y { get; private set; }
    public int Height { get; set; }
    public int Width { get; set; }
   
    / / virtual method
    public virtual void Draw()
    {
        Console.WriteLine("Perform base class drawing tasks"); }}class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw a circle.");
        base.Draw(); }}class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw a rectangle.");
        base.Draw(); }}class Triangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw a triangle.");
        base.Draw(); }}class Program
{
    static void Main(string[] args)
    {
        // Create a List
      
        object and add Circle, Triangle, and Rectangle to it
      
        var shapes = new List<Shape>
        {
            new Rectangle(),
            new Triangle(),
            new Circle()
        };

        // Use the foreach loop to loop through the derived classes of the list and call the Draw method on each Shape object in it
        foreach (var shape in shapes)
        {
            shape.Draw();
        }

        Console.WriteLine("Press any key to exit."); Console.ReadKey(); }}Copy the code

When the above code is compiled and executed, it produces the following results:

  • Draw a rectangle
  • Perform the drawing task of the base class
  • Draw a triangle
  • Perform the drawing task of the base class
  • Draw a circle
  • Perform the drawing task of the base class
  • Press any key to exit.

The following program shows how to calculate the area of images with different shapes using the virtual method area() :

The instanceusing System;
namespace PolymorphismApplication
{
   class Shape
   {
      protected int width, height;
      public Shape( int a=0.int b=0)
      {
         width = a;
         height = b;
      }
      public virtual int area()
      {
         Console.WriteLine("Area of parent class:");
         return 0; }}class Rectangle: Shape
   {
      public Rectangle( int a=0.int b=0) :base(a, b){}public override int area ()
      {
         Console.WriteLine("Rectangle class size:");
         return(width * height); }}class Triangle: Shape
   {
      public Triangle(int a = 0.int b = 0) :base(a, b){}public override int area()
      {
         Console.WriteLine("Triangle class area:");
         return (width * height / 2); }}class Caller
   {
      public void CallArea(Shape sh)
      {
         int a;
         a = sh.area();
         Console.WriteLine("Area: {0}", a); }}class Tester
   {
     
      static void Main(string[] args)
      {
         Caller c = new Caller();
         Rectangle r = new Rectangle(10.7);
         Triangle t = new Triangle(10.5); c.CallArea(r); c.CallArea(t); Console.ReadKey(); }}}Copy the code

When the above code is compiled and executed, it produces the following results:

Rectangle class area: area: 70 Triangle class area: area: 25


Conclusion 💬

This article covers some of the basics of C#, following up on a previous blog that covered methods, encapsulation, inheritance, and polymorphism in C#

Maybe it’s not all there, but that’s about it. I will continue to update when I have time