C# 最基礎(chǔ)知識介紹--多態(tài)
前言:👻🎄
學(xué)過編程的人都知道有個名詞叫" O O P 思 想 " —— {"面向?qū)ο缶幊?/code>"} " 面 向 對 象 編 程 " (
Object Oriented Programming
,OOP,面向?qū)ο蟪绦蛟O(shè)計)是一種計算機編程架構(gòu)。OOP 的一條基本原則是計算機程序是由單個能夠起到子程序作用的單元或?qū)ο蠼M合而成。OOP 達到了軟件工程的三個主要目標(biāo):重用性、靈活性和擴展性。為了實現(xiàn)整體運算,每個對象都能夠接收信息、處理數(shù)據(jù)和向其它對象發(fā)送信息 核心思想:封裝
,繼承
,多態(tài).
一、C# 多態(tài)性
多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力。
多態(tài)性
意味著有多重形式。在面向?qū)ο缶幊谭妒街?,多態(tài)性往往表現(xiàn)為"一個接口,多個功能"。 多態(tài)性可以是靜態(tài)的或動態(tài)的。在 靜態(tài)多態(tài)性
中,函數(shù)的響應(yīng)是在編譯時發(fā)生的。在 動態(tài)多態(tài)性
中,函數(shù)的響應(yīng)是在運行時發(fā)生的。 在 C# 中,每個類型都是多態(tài)的,因為包括用戶定義類型在內(nèi)的所有類型都繼承自 Object
。 多態(tài)就是同一個接口,使用不同的實例而執(zhí)行不同操作,如圖所示:
現(xiàn)實中,比如我們按下 F1 鍵這個動作:
- 如果當(dāng)前在 Flash 界面下彈出的就是 AS 3 的幫助文檔;
- 如果當(dāng)前在 Word 下彈出的就是 Word 幫助;
- 在 Windows 下彈出的就是 Windows 幫助和支持。
- 同一個事件發(fā)生在不同的對象上會產(chǎn)生不同的結(jié)果。
二、靜態(tài)多態(tài)性
在編譯時,函數(shù)和對象的連接機制被稱為早期綁定,也被稱為靜態(tài)綁定。C# 提供了兩種技術(shù)來實現(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(); } } }
當(dāng)上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:
輸出整型: 1 輸出浮點型: 1.23 輸出字符串: Hello Runoob
四、C# 運算符重載
您可以重定義或重載 C# 中內(nèi)置的運算符。因此,程序員也可以使用用戶自定義類型的運算符。重載運算符是具有特殊名稱的函數(shù),是通過關(guān)鍵字 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(); } } }
當(dāng)上面的代碼被編譯和執(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(); } } }
當(dāng)上面的代碼被編譯和執(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# 允許您使用關(guān)鍵字 abstract
創(chuàng)建抽象類,用于提供接口的部分類的實現(xiàn)。當(dāng)一個派生類繼承自該抽象類時,實現(xiàn)即完成。 抽象類
包含抽象方法,抽象方法可被派生類實現(xiàn)。派生類具有更專業(yè)的功能。
請注意,下面是有關(guān)抽象類的一些規(guī)則:
- 不能創(chuàng)建一個抽象類的實例。
- 不能在一個抽象類外部聲明一個抽象方法。
- 通過在類定義前面放置關(guān)鍵字
sealed
,可以將類聲明為密封類
。當(dāng)一個類被聲明為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(); } } }
當(dāng)上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:
Rectangle 類的面積: 面積: 70
當(dāng)有一個定義在類中的函數(shù)需要在繼承類中實現(xiàn)時,可以使用 虛方法 。
虛方法是使用關(guā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í)行基類的畫圖任務(wù)"); } } 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(); } }
當(dāng)上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:
- 畫一個長方形
- 執(zhí)行基類的畫圖任務(wù)
- 畫一個三角形
- 執(zhí)行基類的畫圖任務(wù)
- 畫一個圓形
- 執(zhí)行基類的畫圖任務(wù)
- 按下任意鍵退出。
下面的程序演示通過虛方法 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(); } } }
當(dāng)上面的代碼被編譯和執(zhí)行時,它會產(chǎn)生下列結(jié)果:
Rectangle 類的面積: 面積:70 Triangle 類的面積: 面積:25
總結(jié)💬
到此這篇關(guān)于C# 最基礎(chǔ)知識介紹--多態(tài)的文章就介紹到這了,更多相關(guān)C# 多態(tài)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Unity中Mask和RectMask2D組件的對比與測試
本篇文章給大家介紹Unity中Mask和RectMask2D組件的對比與測試,包括組件用法及RectMask2D的基本用法,通過Mask的原理分析實例代碼相結(jié)合給大家講解的非常詳細,需要的朋友參考下吧2021-06-06C#實現(xiàn)Windows Form調(diào)用R進行繪圖與顯示的方法
眾所周知R軟件功能非常強大,可以很好的進行各類統(tǒng)計,并能輸出圖形。下面介紹一種R語言和C#進行通信的方法,并將R繪圖結(jié)果顯示到WinForm UI界面上的方法,文中介紹的很詳細,需要的朋友可以參考下。2017-02-02C#編程自學(xué)之?dāng)?shù)據(jù)類型和變量三
C#語言類型系統(tǒng)提出的一個核心概念裝箱(boxing)拆箱(unboxing)。裝箱和取消裝箱的概念是C#的類型系統(tǒng)的核心。它在“值類型”和“引用類型”之間的架起了一座橋梁,使得任何“值類型”的值都可以轉(zhuǎn)換為object類型的值,反過來轉(zhuǎn)換也可以。2015-10-10