C# 最基礎知識介紹--多態(tài)
前言:👻🎄
學過編程的人都知道有個名詞叫" O O P 思 想 " —— {"面向?qū)ο缶幊?/code>"} " 面 向 對 象 編 程 " (Object Oriented Programming,OOP,面向?qū)ο蟪绦蛟O計)是一種計算機編程架構(gòu)。OOP 的一條基本原則是計算機程序是由單個能夠起到子程序作用的單元或?qū)ο蠼M合而成。OOP 達到了軟件工程的三個主要目標:重用性、靈活性和擴展性。為了實現(xiàn)整體運算,每個對象都能夠接收信息、處理數(shù)據(jù)和向其它對象發(fā)送信息 核心思想:封裝,繼承,多態(tài).
一、C# 多態(tài)性
多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力。
多態(tài)性意味著有多重形式。在面向?qū)ο缶幊谭妒街校鄳B(tài)性往往表現(xiàn)為"一個接口,多個功能"。 多態(tài)性可以是靜態(tài)的或動態(tài)的。在 靜態(tài)多態(tài)性 中,函數(shù)的響應是在編譯時發(fā)生的。在 動態(tài)多態(tài)性 中,函數(shù)的響應是在運行時發(fā)生的。 在 C# 中,每個類型都是多態(tài)的,因為包括用戶定義類型在內(nèi)的所有類型都繼承自 Object。 多態(tài)就是同一個接口,使用不同的實例而執(zhí)行不同操作,如圖所示:

現(xiàn)實中,比如我們按下 F1 鍵這個動作:
- 如果當前在 Flash 界面下彈出的就是 AS 3 的幫助文檔;
- 如果當前在 Word 下彈出的就是 Word 幫助;
- 在 Windows 下彈出的就是 Windows 幫助和支持。
- 同一個事件發(fā)生在不同的對象上會產(chǎn)生不同的結(jié)果。
二、靜態(tài)多態(tài)性
在編譯時,函數(shù)和對象的連接機制被稱為早期綁定,也被稱為靜態(tài)綁定。C# 提供了兩種技術來實現(xiàn)靜態(tài)多態(tài)性。分別為:
- 函數(shù)重載
- 運算符重載
三、函數(shù)重載
可以在同一個范圍內(nèi)對相同的函數(shù)名有多個定義。函數(shù)的定義必須彼此不同,可以是參數(shù)列表中的參數(shù)類型不同,也可以是參數(shù)個數(shù)不同。不能重載只有返回類型不同的函數(shù)聲明。
下面的實例演示了幾個相同的函數(shù) Add() ,用于對不同個數(shù)參數(shù)進行相加處理:
實例:
using 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)
{
return a + 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);
}
}
}
下面的實例演示了幾個相同的函數(shù) print(),用于打印不同的數(shù)據(jù)類型:
實例:
using System;
namespace PolymorphismApplication
{
class Printdata
{
void print(int i)
{
Console.WriteLine("輸出整型: {0}", i );
}
void print(double f)
{
Console.WriteLine("輸出浮點型: {0}" , f);
}
void print(string s)
{
Console.WriteLine("輸出字符串: {0}", s);
}
static void Main(string[] args)
{
Printdata p = new Printdata();
// 調(diào)用 print 來打印整數(shù)
p.print(1);
// 調(diào)用 print 來打印浮點數(shù)
p.print(1.23);
// 調(diào)用 print 來打印字符串
p.print("Hello Runoob");
Console.ReadKey();
}
}
}
當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:
輸出整型: 1 輸出浮點型: 1.23 輸出字符串: Hello Runoob
四、C# 運算符重載
您可以重定義或重載 C# 中內(nèi)置的運算符。因此,程序員也可以使用用戶自定義類型的運算符。重載運算符是具有特殊名稱的函數(shù),是通過關鍵字 operator 后跟運算符的符號來定義的。與其他函數(shù)一樣,重載運算符有返回類型和參數(shù)列表。
例如,請看下面的函數(shù):
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;
}
上面的函數(shù)為用戶自定義的類 Box 實現(xiàn)了加法運算符(+)。它把兩個 Box 對象的屬性相加,并返回相加后的 Box 對象。
1、運算符重載的實現(xiàn)
下面的程序演示了完整的實現(xiàn):
實例:
using System;
namespace OperatorOvlApplication
{
class Box
{
private double length; // 長度
private double breadth; // 寬度
private double 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;
}
// 重載 + 運算符來把兩個 Box 對象相加
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;
}
}
class Tester
{
static void Main(string[] args)
{
Box Box1 = new Box(); // 聲明 Box1,類型為 Box
Box Box2 = new Box(); // 聲明 Box2,類型為 Box
Box Box3 = new Box(); // 聲明 Box3,類型為 Box
double volume = 0.0; // 體積
// Box1 詳述
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// Box2 詳述
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// Box1 的體積
volume = Box1.getVolume();
Console.WriteLine("Box1 的體積: {0}", volume);
// Box2 的體積
volume = Box2.getVolume();
Console.WriteLine("Box2 的體積: {0}", volume);
// 把兩個對象相加
Box3 = Box1 + Box2;
// Box3 的體積
volume = Box3.getVolume();
Console.WriteLine("Box3 的體積: {0}", volume);
Console.ReadKey();
}
}
}
當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:
Box1 的體積: 210 Box2 的體積: 1560 Box3 的體積: 5400
2、可重載和不可重載運算符
下表描述了 C# 中運算符重載的能力:

實例針對上述討論,讓我們擴展上面的實例,重載更多的運算符:
實例:
using System;
namespace OperatorOvlApplication
{
class Box
{
private double length; // 長度
private double breadth; // 寬度
private double 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;
}
// 重載 + 運算符來把兩個 Box 對象相加
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(); // 聲明 Box1,類型為 Box
Box Box2 = new Box(); // 聲明 Box2,類型為 Box
Box Box3 = new Box(); // 聲明 Box3,類型為 Box
Box Box4 = new Box();
double volume = 0.0; // 體積
// Box1 詳述
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// Box2 詳述
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// 使用重載的 ToString() 顯示兩個盒子
Console.WriteLine("Box1: {0}", Box1.ToString());
Console.WriteLine("Box2: {0}", Box2.ToString());
// Box1 的體積
volume = Box1.getVolume();
Console.WriteLine("Box1 的體積: {0}", volume);
// Box2 的體積
volume = Box2.getVolume();
Console.WriteLine("Box2 的體積: {0}", volume);
// 把兩個對象相加
Box3 = Box1 + Box2;
Console.WriteLine("Box3: {0}", Box3.ToString());
// Box3 的體積
volume = Box3.getVolume();
Console.WriteLine("Box3 的體積: {0}", volume);
//comparing the boxes
if (Box1 > Box2)
Console.WriteLine("Box1 大于 Box2");
else
Console.WriteLine("Box1 不大于 Box2");
if (Box1 < Box2)
Console.WriteLine("Box1 小于 Box2");
else
Console.WriteLine("Box1 不小于 Box2");
if (Box1 >= Box2)
Console.WriteLine("Box1 大于等于 Box2");
else
Console.WriteLine("Box1 不大于等于 Box2");
if (Box1 <= Box2)
Console.WriteLine("Box1 小于等于 Box2");
else
Console.WriteLine("Box1 不小于等于 Box2");
if (Box1 != Box2)
Console.WriteLine("Box1 不等于 Box2");
else
Console.WriteLine("Box1 等于 Box2");
Box4 = Box3;
if (Box3 == Box4)
Console.WriteLine("Box3 等于 Box4");
else
Console.WriteLine("Box3 不等于 Box4");
Console.ReadKey();
}
}
}
當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:
Box1: (6, 7, 5) Box2: (12, 13, 10) Box1 的體積: 210 Box2 的體積: 1560 Box3:(18, 20, 15) Box3 的體積: 5400 Box1 不大于 Box2 Box1 小于 Box2 Box1 不大于等于 Box2 Box1 小于等于 Box2 Box1 不等于 Box2 Box3 等于 Box4
五、動態(tài)多態(tài)性
C# 允許您使用關鍵字 abstract 創(chuàng)建抽象類,用于提供接口的部分類的實現(xiàn)。當一個派生類繼承自該抽象類時,實現(xiàn)即完成。 抽象類 包含抽象方法,抽象方法可被派生類實現(xiàn)。派生類具有更專業(yè)的功能。
請注意,下面是有關抽象類的一些規(guī)則:
- 不能創(chuàng)建一個抽象類的實例。
- 不能在一個抽象類外部聲明一個抽象方法。
- 通過在類定義前面放置關鍵字
sealed,可以將類聲明為密封類。當一個類被聲明為sealed時,它不能被繼承。抽象類不能被聲明為sealed。
下面的程序演示了一個抽象類:
實例:
using 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 類的面積:");
return (width * length);
}
}
class RectangleTester
{
static void Main(string[] args)
{
Rectangle r = new Rectangle(10, 7);
double a = r.area();
Console.WriteLine("面積: {0}",a);
Console.ReadKey();
}
}
}
當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:
Rectangle 類的面積: 面積: 70
當有一個定義在類中的函數(shù)需要在繼承類中實現(xiàn)時,可以使用 虛方法 。
虛方法是使用關鍵字 virtual 聲明的。
虛方法可以在不同的繼承類中有不同的實現(xiàn)。
對虛方法的調(diào)用是在運行時發(fā)生的。
動態(tài)多態(tài)性是通過 抽象類 和 虛方法 實現(xiàn)的。
以下實例創(chuàng)建了 Shape 基類,并創(chuàng)建派生類 Circle、 Rectangle、Triangle, Shape 類提供一個名為 Draw 的虛擬方法,在每個派生類中重寫該方法以繪制該類的指定形狀。
實例:
using 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; }
// 虛方法
public virtual void Draw()
{
Console.WriteLine("執(zhí)行基類的畫圖任務");
}
}
class Circle : Shape
{
public override void Draw()
{
Console.WriteLine("畫一個圓形");
base.Draw();
}
}
class Rectangle : Shape
{
public override void Draw()
{
Console.WriteLine("畫一個長方形");
base.Draw();
}
}
class Triangle : Shape
{
public override void Draw()
{
Console.WriteLine("畫一個三角形");
base.Draw();
}
}
class Program
{
static void Main(string[] args)
{
// 創(chuàng)建一個 List<Shape> 對象,并向該對象添加 Circle、Triangle 和 Rectangle
var shapes = new List<Shape>
{
new Rectangle(),
new Triangle(),
new Circle()
};
// 使用 foreach 循環(huán)對該列表的派生類進行循環(huán)訪問,并對其中的每個 Shape 對象調(diào)用 Draw 方法
foreach (var shape in shapes)
{
shape.Draw();
}
Console.WriteLine("按下任意鍵退出。");
Console.ReadKey();
}
}
當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:
- 畫一個長方形
- 執(zhí)行基類的畫圖任務
- 畫一個三角形
- 執(zhí)行基類的畫圖任務
- 畫一個圓形
- 執(zhí)行基類的畫圖任務
- 按下任意鍵退出。
下面的程序演示通過虛方法 area() 來計算不同形狀圖像的面積:
實例:
using 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("父類的面積:");
return 0;
}
}
class Rectangle: Shape
{
public Rectangle( int a=0, int b=0): base(a, b)
{
}
public override int area ()
{
Console.WriteLine("Rectangle 類的面積:");
return (width * height);
}
}
class Triangle: Shape
{
public Triangle(int a = 0, int b = 0): base(a, b)
{
}
public override int area()
{
Console.WriteLine("Triangle 類的面積:");
return (width * height / 2);
}
}
class Caller
{
public void CallArea(Shape sh)
{
int a;
a = sh.area();
Console.WriteLine("面積: {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();
}
}
}
當上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:
Rectangle 類的面積: 面積:70 Triangle 類的面積: 面積:25
總結(jié)💬
到此這篇關于C# 最基礎知識介紹--多態(tài)的文章就介紹到這了,更多相關C# 多態(tài)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳解Unity中Mask和RectMask2D組件的對比與測試
本篇文章給大家介紹Unity中Mask和RectMask2D組件的對比與測試,包括組件用法及RectMask2D的基本用法,通過Mask的原理分析實例代碼相結(jié)合給大家講解的非常詳細,需要的朋友參考下吧2021-06-06
C#實現(xiàn)Windows Form調(diào)用R進行繪圖與顯示的方法
眾所周知R軟件功能非常強大,可以很好的進行各類統(tǒng)計,并能輸出圖形。下面介紹一種R語言和C#進行通信的方法,并將R繪圖結(jié)果顯示到WinForm UI界面上的方法,文中介紹的很詳細,需要的朋友可以參考下。2017-02-02

