C# 最基礎(chǔ)知識(shí)介紹--多態(tài)
前言:👻🎄
學(xué)過(guò)編程的人都知道有個(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ū)ο缶幊谭妒街校鄳B(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è)類(lèi)型都是多態(tài)的,因?yàn)榘ㄓ脩?hù)定義類(lèi)型在內(nèi)的所有類(lè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ī)制被稱(chēng)為早期綁定,也被稱(chēng)為靜態(tài)綁定。C# 提供了兩種技術(shù)來(lái)實(shí)現(xiàn)靜態(tài)多態(tài)性。分別為:
- 函數(shù)重載
- 運(yùn)算符重載
三、函數(shù)重載
可以在同一個(gè)范圍內(nèi)對(duì)相同的函數(shù)名有多個(gè)定義。函數(shù)的定義必須彼此不同,可以是參數(shù)列表中的參數(shù)類(lèi)型不同,也可以是參數(shù)個(gè)數(shù)不同。不能重載只有返回類(lèi)型不同的函數(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ù)類(lèi)型:
實(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 來(lái)打印整數(shù) p.print(1); // 調(diào)用 print 來(lái)打印浮點(diǎn)數(shù) p.print(1.23); // 調(diào)用 print 來(lái)打印字符串 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)算符。因此,程序員也可以使用用戶(hù)自定義類(lèi)型的運(yùn)算符。重載運(yùn)算符是具有特殊名稱(chēng)的函數(shù),是通過(guò)關(guān)鍵字 operator
后跟運(yùn)算符的符號(hào)來(lái)定義的。與其他函數(shù)一樣,重載運(yùn)算符有返回類(lèi)型和參數(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ù)為用戶(hù)自定義的類(lèi) 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)算符來(lái)把兩個(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,類(lèi)型為 Box Box Box2 = new Box(); // 聲明 Box2,類(lèi)型為 Box Box Box3 = new Box(); // 聲明 Box3,類(lèi)型為 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)算符來(lái)把兩個(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,類(lèi)型為 Box Box Box2 = new Box(); // 聲明 Box2,類(lèi)型為 Box Box Box3 = new Box(); // 聲明 Box3,類(lèi)型為 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)建抽象類(lèi),用于提供接口的部分類(lèi)的實(shí)現(xiàn)。當(dāng)一個(gè)派生類(lèi)繼承自該抽象類(lèi)時(shí),實(shí)現(xiàn)即完成。 抽象類(lèi)
包含抽象方法,抽象方法可被派生類(lèi)實(shí)現(xiàn)。派生類(lèi)具有更專(zhuān)業(yè)的功能。
請(qǐng)注意,下面是有關(guān)抽象類(lèi)的一些規(guī)則:
- 不能創(chuàng)建一個(gè)抽象類(lèi)的實(shí)例。
- 不能在一個(gè)抽象類(lèi)外部聲明一個(gè)抽象方法。
- 通過(guò)在類(lèi)定義前面放置關(guān)鍵字
sealed
,可以將類(lèi)聲明為密封類(lèi)
。當(dāng)一個(gè)類(lèi)被聲明為sealed
時(shí),它不能被繼承。抽象類(lèi)不能被聲明為sealed
。
下面的程序演示了一個(gè)抽象類(lèi):
實(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 類(lèi)的面積:"); 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 類(lèi)的面積: 面積: 70
當(dāng)有一個(gè)定義在類(lèi)中的函數(shù)需要在繼承類(lèi)中實(shí)現(xiàn)時(shí),可以使用 虛方法 。
虛方法是使用關(guān)鍵字 virtual
聲明的。
虛方法可以在不同的繼承類(lèi)中有不同的實(shí)現(xiàn)。
對(duì)虛方法的調(diào)用是在運(yùn)行時(shí)發(fā)生的。
動(dòng)態(tài)多態(tài)性是通過(guò) 抽象類(lèi)
和 虛方法
實(shí)現(xiàn)的。
以下實(shí)例創(chuàng)建了 Shape
基類(lèi),并創(chuàng)建派生類(lèi) Circle
、 Rectangle
、Triangle
, Shape
類(lèi)提供一個(gè)名為 Draw
的虛擬方法,在每個(gè)派生類(lèi)中重寫(xiě)該方法以繪制該類(lèi)的指定形狀。
實(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í)行基類(lèi)的畫(huà)圖任務(wù)"); } } class Circle : Shape { public override void Draw() { Console.WriteLine("畫(huà)一個(gè)圓形"); base.Draw(); } } class Rectangle : Shape { public override void Draw() { Console.WriteLine("畫(huà)一個(gè)長(zhǎng)方形"); base.Draw(); } } class Triangle : Shape { public override void Draw() { Console.WriteLine("畫(huà)一個(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ì)該列表的派生類(lèi)進(jìn)行循環(huán)訪(fǎng)問(wè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é)果:
- 畫(huà)一個(gè)長(zhǎng)方形
- 執(zhí)行基類(lèi)的畫(huà)圖任務(wù)
- 畫(huà)一個(gè)三角形
- 執(zhí)行基類(lèi)的畫(huà)圖任務(wù)
- 畫(huà)一個(gè)圓形
- 執(zhí)行基類(lèi)的畫(huà)圖任務(wù)
- 按下任意鍵退出。
下面的程序演示通過(guò)虛方法 area()
來(lái)計(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("父類(lèi)的面積:"); return 0; } } class Rectangle: Shape { public Rectangle( int a=0, int b=0): base(a, b) { } public override int area () { Console.WriteLine("Rectangle 類(lèi)的面積:"); return (width * height); } } class Triangle: Shape { public Triangle(int a = 0, int b = 0): base(a, b) { } public override int area() { Console.WriteLine("Triangle 類(lèi)的面積:"); 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 類(lèi)的面積: 面積:70 Triangle 類(lèi)的面積: 面積:25
總結(jié)💬
到此這篇關(guān)于C# 最基礎(chǔ)知識(shí)介紹--多態(tài)的文章就介紹到這了,更多相關(guān)C# 多態(tài)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#動(dòng)態(tài)繪制多條曲線(xiàn)的方法
這篇文章主要為大家詳細(xì)介紹了C#動(dòng)態(tài)繪制多條曲線(xiàn)的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02c# 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的基本用法,通過(guò)Mask的原理分析實(shí)例代碼相結(jié)合給大家講解的非常詳細(xì),需要的朋友參考下吧2021-06-06WPF中的ListBox實(shí)現(xiàn)按塊顯示元素的方法
這篇文章主要介紹了WPF中的ListBox實(shí)現(xiàn)按塊顯示元素的方法,涉及ListBox屬性設(shè)置相關(guān)操作技巧,需要的朋友可以參考下2016-09-09C#實(shí)現(xiàn)Windows Form調(diào)用R進(jìn)行繪圖與顯示的方法
眾所周知R軟件功能非常強(qiáng)大,可以很好的進(jìn)行各類(lèi)統(tǒng)計(jì),并能輸出圖形。下面介紹一種R語(yǔ)言和C#進(jìn)行通信的方法,并將R繪圖結(jié)果顯示到WinForm UI界面上的方法,文中介紹的很詳細(xì),需要的朋友可以參考下。2017-02-02C#編程自學(xué)之?dāng)?shù)據(jù)類(lèi)型和變量三
C#語(yǔ)言類(lèi)型系統(tǒng)提出的一個(gè)核心概念裝箱(boxing)拆箱(unboxing)。裝箱和取消裝箱的概念是C#的類(lèi)型系統(tǒng)的核心。它在“值類(lèi)型”和“引用類(lèi)型”之間的架起了一座橋梁,使得任何“值類(lèi)型”的值都可以轉(zhuǎn)換為object類(lèi)型的值,反過(guò)來(lái)轉(zhuǎn)換也可以。2015-10-10