[.net 面向對象編程基礎] (15) 抽象類


[.net 面向對象編程基礎] (15) 抽象類

     前面我們已經使用到了虛方法(使用 Virtual修飾符)和抽象類及抽象方法(使用abstract修飾符)我們在多態一節中說到要實現類成員的重寫必須定義為一個虛方法或抽象方法。這節單獨把抽象類提出來,是因為抽象是.net實現面向對象編程重要的重要思想,定義抽象類就象一個模板一個提綱,它可以理解為中央的指導思想,我們通過派生類去具體實現它。由此可見,抽象類本身沒有任何作用,也不能被實例化,因為他本身就不具有具體的事物。比如上節的動物類的例 子,我們實例化一個動物類並沒有意義,我們需要實例的類是具體的動物,比如Dog、Cat、Sheep這些。

     而我們使用面向對象編程,就要在具體的應用過程中,學會抽象出事物的共同點,形成一個基類,其它類去繼承他,實現他。為我們提高編程、學習設計模式很有益處。

1.什么是抽象類

如果一個類不與具體的事物相聯系,而只是表達一種抽象的概念,僅僅是作為其派生類的一個基類,這樣的類就是抽象類,在抽象類中聲明方法時,如果加上abstract時就是抽象方法

1.抽象類的聲明

抽象類使用abstract 關鍵詞進行聲明。

2.抽象類的特點:

A.抽象類不能被實例化

B.抽象類是一種特殊的類,具有類的特性,其成員可以是抽象的,也可以不是抽象的。

C.抽象方法必須定義在抽象類中,而不能定義在非抽象類中

D.抽象類可以繼承一個抽象類,其派生類仍然是一個抽象類

E.抽象類不能被密封(不能使用sealed(sealed指該類不可被繼承))

3.抽象方法的特點:

A.抽象方法是隱式的虛方法

B.抽象方法只允許聲明在抽象類中

C.抽象方法不能提供實際的實現,所以沒有方法體;抽象方法的實現是在非抽象的派生類中以override重寫實現的

D.抽象方法聲明中不可以使用static或者virtual修飾符

E.abstract關鍵字不能修飾靜態方法或靜態屬性

6.抽象類的構造函數

A.不要再抽象類中定義public或protected internal訪問權限的構造函數

B.應在抽象類中定義protected或private訪問權限的構造函數

C.如果在抽象類中定義一個protected構造函數,則在實例化派生類時,基類可以執行初始化任務

7.抽象方法和虛方法的區別

虛方法(使用Virtual修飾符)有實現部分,並且派生類對其重寫是可選的;抽象方法沒有實現部分,並且強制非抽象派生類對其重寫

8.抽象類和接口的區別

其實這個區別,本來是要在下一節,接口中講的,在這里提前說一下,有點印象也好。

A.它們的派生類只能繼承一個基類,即只能繼承一個抽象類,但是可以繼承多個接口。

B.抽象類中可以定義成員的實現,但接口中不可以。

C.抽象類中包含字段、構造函數、析構函數、靜態成員或常量等,接口中不可以。

D.抽象類中的成員可以私有的(只要不是抽象的)、受保護的、內部的或受保護的內部成員,但接口中的成員必須是公共的。

PS:抽象類和接口這兩種類型用於完全不同的目的。抽象類主要用作對象系列的基類,共享某些主要特性,例如共同的目的和結構。接口則主要用於類,這些類在基礎水平上有所不同,但仍然可以完成某些相同的任務。

7. 舉例

     我們舉一個例子來說明一下抽象類的使用,還是我們前面的例子,基類動物(Animal),我們定義成一個抽象類,有幾個派生類狗、貓、羊,假如我們貓還有波斯貓,狗還有牧羊犬,那么我們還可以讓它們再次繼承,因為貓和狗本身也是動物,我們可以不定義為抽象類,讓他們支持實例化。下面看一下UML圖:

 

關於UML圖我會在后面抽時間寫的,里面的成員+表示公有,-表示私有,字段、屬性、方法使用分割線

下面是具體實現代碼:

  1 /// <summary>
  2 /// 動物類(父類 抽象類)
  3 /// </summary>
  4 abstract class Animal
  5 {
  6     /// <summary>
  7     /// 名字
  8     /// 說明:類和子類可訪問
  9     /// </summary>
 10     protected string name;
 11 
 12 
 13     /// <summary>
 14     /// 構造函數
 15     /// </summary>
 16     /// <param name="name"></param>
 17     public Animal(string name)
 18     {
 19         this.name = name;
 20     }
 21 
 22     private int shoutNum = 3;
 23     public int ShoutNum
 24     {
 25         get { return shoutNum; }
 26         set { shoutNum = value; }
 27     }
 28 
 29     /// <summary>
 30     /// 名字(虛屬性)
 31     /// </summary>
 32     public virtual string MyName
 33     {
 34         get { return this.name; }
 35 
 36     }
 37 
 38     /// <summary>
 39     /// 叫聲,這個方法去掉虛方法,把循環寫在這里
 40     /// </summary>
 41     public void Shout()
 42     {
 43         string result = "";
 44         for (int i = 0; i < ShoutNum; i++)
 45             result += getShoutSound()+"";
 46 
 47         Console.WriteLine(MyName);
 48         Console.WriteLine(result);
 49     }
 50 
 51     /// <summary>
 52     /// 創建一個叫聲的虛方法,子類重寫
 53     /// </summary>
 54     /// <returns></returns>
 55     public  virtual string  getShoutSound()
 56     {
 57         return "";
 58     }
 59 
 60            
 61 }
 62 
 63 /// <summary>
 64 /// 狗(子類)
 65 /// </summary>
 66 class Dog : Animal
 67 {
 68     string myName;
 69     public Dog(string name)
 70         : base(name)
 71     {
 72         myName = name;
 73     }
 74 
 75     /// <summary>
 76     /// 名字(重寫父類屬性)
 77     /// </summary>
 78     public override string MyName
 79     {
 80         get { return "我是:狗狗,我叫:" + this.name; }
 81     }
 82 
 83     /// <summary>
 84     /// 叫(重寫父類方法)
 85     /// </summary>
 86     public override string getShoutSound()
 87     {
 88         return "汪!";
 89     }
 90 }
 91 
 92 /// <summary>
 93 /// 狗(子類)
 94 /// </summary>
 95 class ShepherdDog : Dog
 96 {
 97     string myName;
 98     public ShepherdDog(string name): base(name)
 99     {
100         myName = name;
101     }
102 
103     /// <summary>
104     /// 名字(重寫父類屬性)
105     /// </summary>
106     public override string MyName
107     {
108         get { return "我是:牧羊犬,我叫:" + this.name; }
109     }
110 
111     /// <summary>
112     /// 叫(重寫父類方法)
113     /// </summary>
114     public override string getShoutSound()
115     {
116         return "汪~嗚!";
117     }
118 }
119 
120 /// <summary>
121 /// 貓(子類)
122 /// </summary>
123 class Cat : Animal
124 {
125     string myName;
126     public Cat(string name)
127         : base(name)
128     {
129         myName = name;
130     }
131     /// <summary>
132     /// 名字(重寫父類屬性)
133     /// </summary>
134     public override string MyName
135     {
136         get { return "我是:貓咪,我叫:" + this.name; }
137 
138     }
139 
140     /// <summary>
141     /// 叫(重寫父類方法)
142     /// </summary>
143     public override string getShoutSound()
144     {
145         return "喵!";
146     }
147 }
148 
149     /// <summary>
150 /// 貓(子類)
151 /// </summary>
152 class PersianCat : Cat
153 {
154     string myName;
155     public PersianCat(string name): base(name)
156     {
157         myName = name;
158     }
159     /// <summary>
160     /// 名字(重寫父類屬性)
161     /// </summary>
162     public override string MyName
163     {
164         get { return "我是:波斯貓,我叫:" + this.name; }
165 
166     }
167 
168     /// <summary>
169     /// 叫(重寫父類方法)
170     /// </summary>
171     public override string getShoutSound()
172     {
173         return "喵~嗚!";
174     }
175 }
176 
177     
178 /// <summary>
179 /// 羊(子類)
180 /// </summary>
181 class Sheep : Animal
182 {
183     string myName;
184     public Sheep(string name)
185         : base(name)
186     {
187         myName = name;
188     }
189     /// <summary>
190     /// 名字(重寫父類屬性)
191     /// </summary>
192     public override string MyName
193     {
194         get { return "我是:羊羊,我叫:" + this.name; }
195 
196     }
197     /// <summary>
198     /// 叫(重寫父類方法)
199     /// </summary>
200     public override string getShoutSound()
201     {
202         return "咩!";
203     }
204 }

 

調用及結果如下:

//調用
Animal persianCat = new PersianCat("好貓");
persianCat.Shout();
Console.ReadLine();
//結果如下:
//我是:波斯貓,我叫:好貓
//喵~嗚!!喵~嗚!!喵~嗚!!

 

10要點:

抽象類是指:一個類不與具體的事物相聯系,而只是表達一種抽象的概念,僅僅是作為其派生類的一個基類。

抽象類是一種特殊類,使用abstract聲明

抽象類不可被實例化

抽象類可以繼承一個抽象類

抽象方法只能存在於抽象類中,可以和虛方法一樣,在派生類中重寫。

抽象類的存在就是被繼承用的,因此不允許被密封(即不能使用sealed修飾)

最后,抽象,是面向對象程序設計的重要思想。。

 

============================================================================================== 

返回目錄

 <如果對你有幫助,記得點一下推薦哦,有不明白的地方或寫的不對的地方,請多交流>
 

==============================================================================================  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM