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

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

實(shí)例針對(duì)上述討論,讓我們擴(kuò)展上面的實(shí)例,重載更多的運(yùn)算符:
實(shí)例:
using System;
namespace OperatorOvlApplication
{
class Box
{
private double length; // 長(zhǎng)度
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;
}
// 重載 + 運(yùn)算符來把兩個(gè) Box 對(duì)象相加
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() 顯示兩個(gè)盒子
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);
// 把兩個(gè)對(duì)象相加
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();
}
}
}
當(dāng)上面的代碼被編譯和執(zhí)行時(shí),它會(huì)產(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
五、動(dòng)態(tài)多態(tài)性
C# 允許您使用關(guān)鍵字 abstract 創(chuàng)建抽象類,用于提供接口的部分類的實(shí)現(xiàn)。當(dāng)一個(gè)派生類繼承自該抽象類時(shí),實(shí)現(xiàn)即完成。 抽象類 包含抽象方法,抽象方法可被派生類實(shí)現(xiàn)。派生類具有更專業(yè)的功能。
請(qǐng)注意,下面是有關(guān)抽象類的一些規(guī)則:
- 不能創(chuàng)建一個(gè)抽象類的實(shí)例。
- 不能在一個(gè)抽象類外部聲明一個(gè)抽象方法。
- 通過在類定義前面放置關(guān)鍵字
sealed,可以將類聲明為密封類。當(dāng)一個(gè)類被聲明為sealed時(shí),它不能被繼承。抽象類不能被聲明為sealed。
下面的程序演示了一個(gè)抽象類:
實(shí)例:
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();
}
}
}
當(dāng)上面的代碼被編譯和執(zhí)行時(shí),它會(huì)產(chǎn)生下列結(jié)果:
Rectangle 類的面積: 面積: 70
當(dāng)有一個(gè)定義在類中的函數(shù)需要在繼承類中實(shí)現(xiàn)時(shí),可以使用 虛方法 。
虛方法是使用關(guān)鍵字 virtual 聲明的。
虛方法可以在不同的繼承類中有不同的實(shí)現(xiàn)。
對(duì)虛方法的調(diào)用是在運(yùn)行時(shí)發(fā)生的。
動(dòng)態(tài)多態(tài)性是通過 抽象類 和 虛方法 實(shí)現(xiàn)的。
以下實(shí)例創(chuàng)建了 Shape 基類,并創(chuàng)建派生類 Circle、 Rectangle、Triangle, Shape 類提供一個(gè)名為 Draw 的虛擬方法,在每個(gè)派生類中重寫該方法以繪制該類的指定形狀。
實(shí)例:
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í)行基類的畫圖任務(wù)");
}
}
class Circle : Shape
{
public override void Draw()
{
Console.WriteLine("畫一個(gè)圓形");
base.Draw();
}
}
class Rectangle : Shape
{
public override void Draw()
{
Console.WriteLine("畫一個(gè)長(zhǎng)方形");
base.Draw();
}
}
class Triangle : Shape
{
public override void Draw()
{
Console.WriteLine("畫一個(gè)三角形");
base.Draw();
}
}
class Program
{
static void Main(string[] args)
{
// 創(chuàng)建一個(gè) List<Shape> 對(duì)象,并向該對(duì)象添加 Circle、Triangle 和 Rectangle
var shapes = new List<Shape>
{
new Rectangle(),
new Triangle(),
new Circle()
};
// 使用 foreach 循環(huán)對(duì)該列表的派生類進(jìn)行循環(huán)訪問,并對(duì)其中的每個(gè) Shape 對(duì)象調(diào)用 Draw 方法
foreach (var shape in shapes)
{
shape.Draw();
}
Console.WriteLine("按下任意鍵退出。");
Console.ReadKey();
}
}
當(dāng)上面的代碼被編譯和執(zhí)行時(shí),它會(huì)產(chǎn)生下列結(jié)果:
- 畫一個(gè)長(zhǎng)方形
- 執(zhí)行基類的畫圖任務(wù)
- 畫一個(gè)三角形
- 執(zhí)行基類的畫圖任務(wù)
- 畫一個(gè)圓形
- 執(zhí)行基類的畫圖任務(wù)
- 按下任意鍵退出。
下面的程序演示通過虛方法 area() 來計(jì)算不同形狀圖像的面積:
實(shí)例:
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();
}
}
}
當(dāng)上面的代碼被編譯和執(zhí)行時(shí),它會(huì)產(chǎn)生下列結(jié)果:
Rectangle 類的面積: 面積:70 Triangle 類的面積: 面積:25
總結(jié)💬
到此這篇關(guān)于C# 最基礎(chǔ)知識(shí)介紹--多態(tài)的文章就介紹到這了,更多相關(guān)C# 多態(tài)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c# in depth的泛型實(shí)現(xiàn)實(shí)例代碼
這篇文章主要介紹了c# in depth的泛型實(shí)現(xiàn)實(shí)例代碼,學(xué)C#的同學(xué)一定會(huì)用到泛型實(shí)現(xiàn)的,這里我們提供了泛型實(shí)現(xiàn)的程序代碼,大家參考使用2013-11-11
詳解Unity中Mask和RectMask2D組件的對(duì)比與測(cè)試
本篇文章給大家介紹Unity中Mask和RectMask2D組件的對(duì)比與測(cè)試,包括組件用法及RectMask2D的基本用法,通過Mask的原理分析實(shí)例代碼相結(jié)合給大家講解的非常詳細(xì),需要的朋友參考下吧2021-06-06
WPF中的ListBox實(shí)現(xiàn)按塊顯示元素的方法
這篇文章主要介紹了WPF中的ListBox實(shí)現(xiàn)按塊顯示元素的方法,涉及ListBox屬性設(shè)置相關(guān)操作技巧,需要的朋友可以參考下2016-09-09
C#實(shí)現(xiàn)Windows Form調(diào)用R進(jìn)行繪圖與顯示的方法
眾所周知R軟件功能非常強(qiáng)大,可以很好的進(jìn)行各類統(tǒng)計(jì),并能輸出圖形。下面介紹一種R語言和C#進(jìn)行通信的方法,并將R繪圖結(jié)果顯示到WinForm UI界面上的方法,文中介紹的很詳細(xì),需要的朋友可以參考下。2017-02-02
C#編程自學(xué)之?dāng)?shù)據(jù)類型和變量三
C#語言類型系統(tǒng)提出的一個(gè)核心概念裝箱(boxing)拆箱(unboxing)。裝箱和取消裝箱的概念是C#的類型系統(tǒng)的核心。它在“值類型”和“引用類型”之間的架起了一座橋梁,使得任何“值類型”的值都可以轉(zhuǎn)換為object類型的值,反過來轉(zhuǎn)換也可以。2015-10-10

