C# 面向?qū)ο笕筇匦裕悍庋b、繼承、多態(tài)
面向?qū)ο笥蟹庋b、繼承、多態(tài)這三個(gè)特性,面向?qū)ο缶幊贪凑宅F(xiàn)實(shí)世界的特點(diǎn)來管理復(fù)雜的事物,把它們抽象為對(duì)象,具有自己的狀態(tài)和行為,通過對(duì)消息的反應(yīng)來完成任務(wù)。這種編程方法提供了非常強(qiáng)大的多樣性,大大增加了代碼的重用機(jī)會(huì),增加了程序開發(fā)的速度,將具備獨(dú)立性特制的程序代碼包裝起來,修改部分程序代碼時(shí)不至于會(huì)影響到程序的其他部分。
1.封裝
每個(gè)對(duì)象都包含它進(jìn)行操作所需要的所有信息,封裝只公開代碼單元的對(duì)外接口,而隱藏其具體實(shí)現(xiàn),盡量不對(duì)外公開代碼。使用封裝有很多好處,從設(shè)計(jì)角度來講,封裝可以對(duì)外屏蔽一些重要的信息,比如使用電腦的人只要知道怎么使用電腦就可以,不用知道這些功能具體是怎么實(shí)現(xiàn)的;從安全性考慮,封裝使對(duì)代碼的修改更加安全和容易,封裝明確的指出了哪些屬性和方法是外部可以訪問的,這樣當(dāng)需要調(diào)整這個(gè)類的代碼時(shí),只要保證公有屬性不變,公有方法的參數(shù)和返回值類型不變,那么就可以盡情的修改這個(gè)類,而不會(huì)影響到程序的其他部分;封裝還避免了命名沖突的問題,封裝有隔離作用,不同的類中可以有相同名稱的方法和屬性,但不會(huì)混淆,也可以減少耦合。
2.繼承
繼承可以使用現(xiàn)有類的所有功能,并在無須重新編寫原來的類的情況下,對(duì)這些功能進(jìn)行擴(kuò)展。使用繼承而產(chǎn)生的類被稱為派生類或子類,而被繼承的類則稱為基類或超類或父類。繼承表示一個(gè)類型派生于一個(gè)基類型,它擁有該基類型的所有成員字段和函數(shù),其子類是對(duì)父類的擴(kuò)展;接口繼承是表示一個(gè)類型只繼承了函數(shù)的簽名,沒有繼承任何實(shí)現(xiàn)代碼。繼承劃分了類的層次性,也可以說繼承是對(duì)類的分組,父類代表的是抽象的類,更常用的類,而子類代表的是更為具體,更為細(xì)化的類;繼承是實(shí)現(xiàn)代碼重用、擴(kuò)展的重要手段。所謂抽象的類是指與具體的事項(xiàng)相聯(lián)系,但只是表達(dá)整體而不是具體概念的類,比如說形狀包含正方形、長(zhǎng)方形、圓等,這時(shí)候形狀是一個(gè)抽象的概念,相當(dāng)于一個(gè)父類,而正方形、長(zhǎng)方形、圓是具體的形狀,相當(dāng)于是子類。
3.多態(tài)
多態(tài)是指程序中同名的不同方法共存的情況,主要通過子類對(duì)父類方法的覆蓋來實(shí)現(xiàn)多態(tài)。這樣,不同類的對(duì)象可以用同名的方法完成特定的功能,但具體的實(shí)現(xiàn)方法卻可以不同。比如說形狀包含正方形、長(zhǎng)方形、圓等,每個(gè)形狀都有面積和周長(zhǎng),但是不同的形狀計(jì)算面積和周長(zhǎng)的方法都不同。
下面就舉個(gè)例子來說明封裝、繼承、多態(tài):
這個(gè)例子的基類,就是上面描述概念的時(shí)候提到的形狀,形狀是基類,而這個(gè)基類是個(gè)抽象的概念,而不是具體的,因此是抽象類,此類包含屬性形狀名稱、輸出形狀周長(zhǎng)和面積的方法以及計(jì)算形狀周長(zhǎng)和面積的抽象方法:
/// <summary> /// 形狀基類 /// </summary> public abstract class Shape { /// <summary> /// 形狀名稱 /// </summary> public string ShapeName { get; private set; } public Shape(string shapeName) { ShapeName = shapeName; } /// <summary> /// 輸出形狀周長(zhǎng) /// </summary> public virtual void PrintPerimeter(double perimeter) { Console.WriteLine(ShapeName + " Perimeter: " + perimeter); } /// <summary> /// 輸出形狀面積 /// </summary> public virtual void PrintArea(double area) { Console.WriteLine(ShapeName + " Area: " + area); } /// <summary> /// 計(jì)算形狀周長(zhǎng) /// </summary> /// <returns></returns> public abstract double CalculatePerimeter(); /// <summary> /// 計(jì)算形狀面積 /// </summary> /// <returns></returns> public abstract double CalculateArea(); }
下面再來看具體的子類,子類是圓,包含屬性半徑、計(jì)算周長(zhǎng)和面積的方法:
/// <summary> /// 圓 /// </summary> public class Circle : Shape { /// <summary> /// 圓的半徑 /// </summary> public double R { get; set; } public Circle() : base("Circle") { this.R = 0; } /// <summary> /// 圓的周長(zhǎng) /// </summary> /// <returns></returns> public override double CalculatePerimeter() { return 2 * Math.PI * R; } /// <summary> /// 圓的面積 /// </summary> /// <returns></returns> public override double CalculateArea() { return Math.PI * R * R; } }
再來看看長(zhǎng)方形,包含屬性高度和寬度、計(jì)算周長(zhǎng)和面積的方法:
public class Rectangle : Shape { /// <summary> /// 長(zhǎng)方形的長(zhǎng)度 /// </summary> public double Width { get; set; } /// <summary> /// 長(zhǎng)方形的高度 /// </summary> public double Height { get; set; } public Rectangle() : base("Rectangle") { Width = 0; Height = 0; } /// <summary> /// 長(zhǎng)方形的周長(zhǎng) /// </summary> /// <returns></returns> public override double CalculatePerimeter() { return (Width + Height) * 2; } /// <summary> /// 長(zhǎng)方形的面積 /// </summary> /// <returns></returns> public override double CalculateArea() { return Width * Height; } }
以下是調(diào)用的代碼:
Circle circle = new Circle(); circle.R = 20; Square square = new Square(); square.Edge = 10; Rectangle rectangle = new Rectangle(); rectangle.Width = 20; rectangle.Height = 30; // 把子類賦給父類,能更好的體現(xiàn)多態(tài)性 IList<Shape> shapeList = new List<Shape>(); shapeList.Add(circle); shapeList.Add(square); shapeList.Add(rectangle); foreach (var shape in shapeList) { shape.PrintPerimeter(shape.CalculatePerimeter()); shape.PrintArea(shape.CalculateArea()); }
在此例子中,輸出形狀的周長(zhǎng)和面積的方法沒有太大作用,是因?yàn)榉椒ǖ木唧w實(shí)現(xiàn)比較簡(jiǎn)單,如果是復(fù)雜的方法時(shí)會(huì)有很大作用。比如說想要實(shí)現(xiàn)拖拽功能,每個(gè)形狀都是可以拖拽的,而且每個(gè)形狀拖拽的方法都會(huì)是一樣的,但是想要實(shí)現(xiàn)拖拽功能可不像輸出這么簡(jiǎn)單,這時(shí)候子類可以繼承父類的方法,直接調(diào)用。
相關(guān)文章
C#中使用WinRAR實(shí)現(xiàn)加密壓縮及解壓縮文件
這篇文章主要介紹了C#中使用WinRAR實(shí)現(xiàn)加密壓縮及解壓縮文件,本文直接給出實(shí)例代碼,代碼中包含詳細(xì)注釋,需要的朋友可以參考下2015-07-07DevExpress實(shí)現(xiàn)GridControl刪除所有行的方法
這篇文章主要介紹了DevExpress實(shí)現(xiàn)GridControl刪除所有行的方法,對(duì)于C#初學(xué)者有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-08-08如何在C#中使用 CancellationToken 處理異步任務(wù)
這篇文章主要介紹了如何在C#中使用 CancellationToken 處理異步任務(wù),幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下2021-03-03Unity Shader實(shí)現(xiàn)黑幕過場(chǎng)效果
這篇文章主要為大家詳細(xì)介紹了Unity Shader實(shí)現(xiàn)黑幕過場(chǎng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07C#中的文件路徑獲取函數(shù)和文件名字獲取函數(shù)小結(jié)
這篇文章主要介紹了C#中的文件路徑獲取函數(shù)和文件名字獲取函數(shù)小結(jié),本文講解了獲取絕對(duì)文件路徑、獲取文件名字、獲得包含 path 目錄信等內(nèi)容,需要的朋友可以參考下2015-01-01