深入解析C#中的abstract抽象類(lèi)
抽象類(lèi)和類(lèi)成員
通過(guò)在類(lèi)定義前面放置關(guān)鍵字 abstract,可以將類(lèi)聲明為抽象類(lèi)。例如:
public abstract class A { // Class members here. }
抽象類(lèi)不能實(shí)例化。抽象類(lèi)的用途是提供一個(gè)可供多個(gè)派生類(lèi)共享的通用基類(lèi)定義。例如,類(lèi)庫(kù)可以定義一個(gè)抽象類(lèi),將其用作多個(gè)類(lèi)庫(kù)函數(shù)的參數(shù),并要求使用該庫(kù)的程序員通過(guò)創(chuàng)建派生類(lèi)來(lái)提供自己的類(lèi)實(shí)現(xiàn)。
抽象類(lèi)也可以定義抽象方法。方法是將關(guān)鍵字 abstract 添加到方法的返回類(lèi)型的前面。例如:
public abstract class A { public abstract void DoWork(int i); }
抽象方法沒(méi)有實(shí)現(xiàn),所以方法定義后面是分號(hào),而不是常規(guī)的方法塊。抽象類(lèi)的派生類(lèi)必須實(shí)現(xiàn)所有抽象方法。當(dāng)抽象類(lèi)從基類(lèi)繼承虛方法時(shí),抽象類(lèi)可以使用抽象方法重寫(xiě)該虛方法。例如:
// compile with: /target:library public class D { public virtual void DoWork(int i) { // Original implementation. } } public abstract class E : D { public abstract override void DoWork(int i); } public class F : E { public override void DoWork(int i) { // New implementation. } }
如果將 virtual 方法聲明為 abstract,則該方法對(duì)于從抽象類(lèi)繼承的所有類(lèi)而言仍然是虛方法。繼承一個(gè)抽象方法的類(lèi)不能訪問(wèn)該方法的原始實(shí)現(xiàn)。在上一個(gè)示例中,類(lèi) F 中的 DoWork 不能調(diào)用類(lèi) D 中的 DoWork。通過(guò)這種方式,抽象類(lèi)可以強(qiáng)制派生類(lèi)為虛方法提供新的方法實(shí)現(xiàn)。
定義抽象屬性
下面的示例演示如何定義抽象屬性。抽象屬性聲明不提供屬性訪問(wèn)器的實(shí)現(xiàn),它只聲明該類(lèi)支持屬性,而將訪問(wèn)器實(shí)現(xiàn)留給派生類(lèi)。下面的示例演示如何實(shí)現(xiàn)從基類(lèi)繼承的抽象屬性。
此示例由三個(gè)文件組成,其中每個(gè)文件都單獨(dú)編譯,產(chǎn)生的程序集由下一次編譯引用:
- abstractshape.cs:包含抽象 Area 屬性的 Shape 類(lèi)。
- shapes.cs:Shape 類(lèi)的子類(lèi)。
- shapetest.cs:測(cè)試程序,它顯示某些 Shape 派生對(duì)象的面積。
若要編譯該示例,請(qǐng)使用以下命令:
csc abstractshape.cs shapes.cs shapetest.cs
這樣將生成可執(zhí)行文件 shapetest.exe。
該文件聲明的 Shape 類(lèi)包含 double 類(lèi)型的 Area 屬性。
// compile with: csc /target:library abstractshape.cs public abstract class Shape { private string name; public Shape(string s) { // calling the set accessor of the Id property. Id = s; } public string Id { get { return name; } set { name = value; } } // Area is a read-only property - only a get accessor is needed: public abstract double Area { get; } public override string ToString() { return Id + " Area = " + string.Format("{0:F2}", Area); } }
屬性的修飾符就放置在屬性聲明中。例如:
public abstract double Area
聲明抽象屬性時(shí)(如本示例中的 Area),指明哪些屬性訪問(wèn)器可用即可,不要實(shí)現(xiàn)它們。在此示例中,只有一個(gè) get 訪問(wèn)器可用,因此該屬性是只讀的。
下面的代碼演示 Shape 的三個(gè)子類(lèi),并演示它們?nèi)绾沃貙?xiě) Area 屬性來(lái)提供自己的實(shí)現(xiàn)。
// compile with: csc /target:library /reference:abstractshape.dll shapes.cs public class Square : Shape { private int side; public Square(int side, string id) : base(id) { this.side = side; } public override double Area { get { // Given the side, return the area of a square: return side * side; } } } public class Circle : Shape { private int radius; public Circle(int radius, string id) : base(id) { this.radius = radius; } public override double Area { get { // Given the radius, return the area of a circle: return radius * radius * System.Math.PI; } } } public class Rectangle : Shape { private int width; private int height; public Rectangle(int width, int height, string id) : base(id) { this.width = width; this.height = height; } public override double Area { get { // Given the width and height, return the area of a rectangle: return width * height; } } }
下面的代碼演示一個(gè)測(cè)試程序,它創(chuàng)建若干 Shape 派生對(duì)象,并輸出它們的面積。
// compile with: csc /reference:abstractshape.dll;shapes.dll shapetest.cs class TestClass { static void Main() { Shape[] shapes = { new Square(5, "Square #1"), new Circle(3, "Circle #1"), new Rectangle( 4, 5, "Rectangle #1") }; System.Console.WriteLine("Shapes Collection"); foreach (Shape s in shapes) { System.Console.WriteLine(s); } } }
輸出:
Shapes Collection Square #1 Area = 25.00 Circle #1 Area = 28.27 Rectangle #1 Area = 20.00
相關(guān)文章
Unity使用LineRender實(shí)現(xiàn)簽名效果
這篇文章主要為大家詳細(xì)介紹了Unity使用LineRender實(shí)現(xiàn)簽名效果,制作簽名功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10WPF調(diào)用WindowsAPI實(shí)現(xiàn)屏幕錄制
這篇文章主要為大家詳細(xì)介紹了WPF如何調(diào)用WindowsAPI實(shí)現(xiàn)屏幕錄制,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定幫助,感興趣的小伙伴可以了解一下2023-05-05C# Winform 讓整個(gè)窗口都可以拖動(dòng)
Windows 的 API 果然強(qiáng)大啊.以前要實(shí)現(xiàn)全窗口拖動(dòng), 要寫(xiě)鼠標(biāo)按下和抬起事件, 很是麻煩, 偶爾還會(huì)出現(xiàn) BUG2011-05-05C#單例模式(Singleton Pattern)實(shí)例教程
這篇文章主要介紹了C#單例模式(Singleton Pattern)的實(shí)現(xiàn)方法,主要講述了即時(shí)加載的單例模式、延遲加載的單例模式與線程安全的單例模式,需要的朋友可以參考下2014-09-09C# OpenCvSharp利用白平衡技術(shù)實(shí)現(xiàn)圖像修復(fù)功能
這篇文章主要為大家詳細(xì)介紹了C# OpenCvSharp如何利用白平衡技術(shù)實(shí)現(xiàn)圖像修復(fù)功能,文中的示例代碼講解詳細(xì),希望對(duì)大家有一定的幫助2024-02-02C#如何提取經(jīng)緯度文件中的經(jīng)緯度數(shù)據(jù)
近期開(kāi)發(fā)時(shí)需要獲取當(dāng)前的經(jīng)緯度坐標(biāo),下面這篇文章主要給大家介紹了關(guān)于C#如何提取經(jīng)緯度文件中經(jīng)緯度數(shù)據(jù)的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08C#導(dǎo)入導(dǎo)出Excel數(shù)據(jù)的兩種方法
這篇文章主要為大家詳細(xì)介紹了C#導(dǎo)入導(dǎo)出Excel數(shù)據(jù)的兩種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03C#如何獲取文件全路徑、目錄、擴(kuò)展名、文件名稱(chēng)
這篇文章主要介紹了C#如何獲取文件全路徑、目錄、擴(kuò)展名、文件名稱(chēng)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07