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