天天看點

【C#小知識】C#中一些易混淆概念總結(七)---------解析抽象類,抽象方法

目錄:

<a href="http://yisuowushinian.blog.51cto.com/4241271/1352834" target="_blank">【C#小知識】C#中一些易混淆概念總結--------資料類型存儲位置,方法調用,out和ref參數的使用</a>

<a href="http://www.cnblogs.com/qq731109249/p/3525271.html" target="_blank"></a>

<a href="http://yisuowushinian.blog.51cto.com/4241271/1357174" target="_blank">【C#小知識】C#中一些易混淆概念總結(六)---------解析裡氏替換原則,虛方法</a>

-----------------------------------------分割線----------------------------------------------

我筆記本上C#方面的知識基本上整理的差不多了,是以這個關于《C#小知識》的系列估計就要完結了,這個過程中謝謝大家一直來對于我的支援,你們給我的寶貴的意見對我幫助很大。

在介紹抽象類和抽象方法之前還是先提一下多态的基本概念。

其實在上一篇關于裡氏替換原則就已經說明了多态的精髓“子類對象可以替換父類對象的位置,而程式的功能不受影響”。還是來看一段代碼吧:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<code>/// &lt;summary&gt;</code>

<code>    </code><code>/// Create By:ZhiQiang</code>

<code>    </code><code>/// Create Time:2014-2-9</code>

<code>    </code><code>/// &lt;/summary&gt;</code>

<code>    </code><code>class</code> <code>Person</code>

<code>    </code><code>{</code>

<code>                                                                                           </code> 

<code>       </code><code>//定義虛方法以備子類重寫,當子類替換父類對象的位置時,可以表現出多态</code>

<code>        </code><code>public</code> <code>virtual</code> <code>void</code> <code>Run()</code>

<code>        </code><code>{</code>

<code>            </code><code>Console.WriteLine(</code><code>"我是人,我會跑!"</code><code>);</code>

<code>        </code><code>}</code>

<code>        </code><code>public</code> <code>virtual</code> <code>void</code> <code>Say()</code>

<code>            </code><code>Console.WriteLine(</code><code>"我是人,我會說話!"</code><code>);</code>

<code>    </code><code>}</code>

子類的代碼如下:

18

19

20

21

22

23

24

25

<code>//定義Teacher類繼承Person</code>

<code>    </code><code>class</code> <code>Teacher:Person</code>

<code>        </code><code>public</code> <code>override</code> <code>void</code> <code>Run()</code>

<code>            </code><code>Console.WriteLine(</code><code>"我是老師,我必須慢速跑"</code><code>);</code>

<code>        </code><code>public</code> <code>override</code> <code>void</code> <code>Say()</code>

<code>            </code><code>Console.WriteLine(</code><code>"我是老師,我得說表揚的話!"</code><code>);</code>

<code>    </code><code>//定義Student類繼承Person</code>

<code>    </code><code>class</code> <code>Student : Person</code>

<code>        </code><code>//子類重寫了父類的虛方法</code>

<code>            </code><code>Console.WriteLine(</code><code>"我是學生,我會加速跑!"</code><code>);</code>

<code>            </code><code>Console.WriteLine(</code><code>"我是學生,我會說英語!"</code><code>);</code>

下面需要一個實作多态的類,代碼如下:

<code>//實作多态的類</code>

<code>    </code><code>class</code> <code>FeatureHuman</code>

<code>        </code><code>/// &lt;summary&gt;</code>

<code>        </code><code>/// 這個方法就提現了多态,當傳入的是子類的對象的時候,p指向的是子類對象,就可以調用子類重寫父類方法後的方法</code>

<code>        </code><code>/// &lt;/summary&gt;</code>

<code>        </code><code>/// &lt;param name="p"&gt;父類或者子類對象&lt;/param&gt;</code>

<code>        </code><code>public</code> <code>void</code> <code>OutPutFeature(Person p)</code>

<code>            </code><code>p.Run();</code>

<code>            </code><code>p.Say();</code>

主體代碼和實作多态的方法如下:

<code>static</code> <code>void</code> <code>Main(</code><code>string</code><code>[] args)</code>

<code>       </code><code>{</code>

<code>           </code><code>FeatureHuman fea = </code><code>new</code> <code>FeatureHuman();</code>

<code>           </code><code>//人的特點</code>

<code>           </code><code>Person p = </code><code>new</code> <code>Person();</code>

<code>           </code><code>Program pro = </code><code>new</code> <code>Program();</code>

<code>           </code><code>fea.OutPutFeature(p);</code>

<code>           </code><code>//學生的特點</code>

<code>           </code><code>Student s = </code><code>new</code> <code>Student();</code>

<code>           </code><code>fea.OutPutFeature(s);</code>

<code>           </code><code>//老師的特點</code>

<code>           </code><code>Teacher t = </code><code>new</code> <code>Teacher();</code>

<code>           </code><code>fea.OutPutFeature(t);</code>

<code>           </code><code>Console.ReadKey();</code>

<code>       </code><code>}</code>

運作,列印結果如下:

【C#小知識】C#中一些易混淆概念總結(七)---------解析抽象類,抽象方法

這裡可以發現,我們outputFeature方法根據傳入的實體對象不同(父類變量指向了子類的對象),而列印出了不同人物的特點,這就是多态。

代碼圖解如下:

【C#小知識】C#中一些易混淆概念總結(七)---------解析抽象類,抽象方法

多态總結如下:

【C#小知識】C#中一些易混淆概念總結(七)---------解析抽象類,抽象方法

二,抽象類和抽象方法

在C#中使用abstract關鍵字修飾的類和方法,叫做抽象類和抽象方法。

1)抽象類中可以擁有沒抽象成員,為了繼承給他的子類調用 (抽象類就是為了定義抽象成員,繼承給子類去實作,同時子類也可以調用父類的非抽象成員)

<code>abstract</code>  <code>class</code> <code>Person</code>

<code>       </code><code>//private int nAge;</code>

<code>       </code><code>//abstract string strName;</code>

<code>       </code><code>//抽象類可以包含不抽象的成員,可以給繼承的子類使用</code>

<code>       </code><code>public</code> <code>void</code> <code>Say()</code>

<code>           </code><code>Console.WriteLine(</code><code>"我是父類,我是人!"</code><code>);</code>

<code>       </code><code>public</code> <code>virtual</code> <code>void</code> <code>Sing()</code>

<code>           </code><code>Console.WriteLine(</code><code>"我是父類,我是人,我可以唱歌!"</code><code>);</code>

<code>       </code><code>//Run的抽象方法</code>

<code>       </code><code>public</code> <code>abstract</code> <code>void</code> <code>Run();</code>

2)抽象類中可以有virtual修飾的虛方法

如上面的代碼,在抽象類中定義了virtual修飾的方法,編譯通過。抽象類就是為了定義抽象成員,繼承給子類去實作,是以子類也可以實作抽象類中的虛方法。

3)抽象類不能執行個體化,因為有抽象成員,而抽象成員沒有方法體,如下圖,

【C#小知識】C#中一些易混淆概念總結(七)---------解析抽象類,抽象方法

4)抽象成員不能私有,如果私有子類沒有辦法通路

我們可以在抽象類中定義私有成員,但是沒有意義。因為子類根本通路不到這些私有成員,而抽象類本身也不能執行個體化,是以私有成員通路不到。

5)子類必須重寫父類的抽象方法

在上面代碼的基礎上,我們定義一個Student類,繼承抽象類,但是不實作抽象類的抽象方法,編譯報錯。代碼如下:

【C#小知識】C#中一些易混淆概念總結(七)---------解析抽象類,抽象方法

6)在子類中沒有辦法通過base關鍵字調用父類抽象方法

原理同上,抽象類的抽象發放沒有實作語句,就算調用也沒有意義。但是可以使用base關鍵字調用非抽象方法,代碼如下:

<code>class</code> <code>Program</code>

<code>        </code><code>static</code> <code>void</code> <code>Main(</code><code>string</code><code>[] args)</code>

<code>            </code><code>//Person p = new Person();</code>

<code>            </code><code>Student s = </code><code>new</code> <code>Student();</code>

<code>            </code><code>s.Run();</code>

<code>            </code><code>Console.ReadLine();</code>

<code>                                                                       </code> 

<code>            </code><code>base</code><code>.Say();</code>

<code>            </code><code>Console.WriteLine(</code><code>"我是學生,繼承了父類,我可以跑!"</code><code>);</code>

列印結果如下:

【C#小知識】C#中一些易混淆概念總結(七)---------解析抽象類,抽象方法

抽象類思維導圖總結如下:

【C#小知識】C#中一些易混淆概念總結(七)---------解析抽象類,抽象方法

抽象方法

1)抽象方法必須定義在抽象類中,

<code>class</code> <code>Student : Person</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>Swiming();</code>

代碼編譯會報錯,如下圖:

【C#小知識】C#中一些易混淆概念總結(七)---------解析抽象類,抽象方法

2)抽象方法必須使用關鍵字修飾,示例代碼如下:

<code>abstract</code> <code>class</code> <code>Person</code>

<code>        </code><code>//private int nAge;</code>

<code>        </code><code>//abstract string strName;</code>

<code>        </code><code>//抽象類可以包含不抽象的成員,可以給繼承的子類使用</code>

<code>        </code><code>public</code> <code>void</code> <code>Say()</code>

<code>            </code><code>Console.WriteLine(</code><code>"我是父類,我是人!"</code><code>);</code>

<code>        </code><code>public</code> <code>virtual</code> <code>void</code> <code>Sing()</code>

<code>            </code><code>Console.WriteLine(</code><code>"我是父類,我是人,我可以唱歌!"</code><code>);</code>

<code>        </code><code>//Run的抽象方法,不能有方法體,留給子類實作</code>

<code>        </code><code>public</code> <code>abstract</code> <code>void</code> <code>Run();</code>

抽象方法思維導圖總結如下:

【C#小知識】C#中一些易混淆概念總結(七)---------解析抽象類,抽象方法

那麼什麼時候使用抽象類呢?

①子類必須重寫父類的方法(相當于定義了一個标準,規範)

②父類沒有必要執行個體化,就用抽象類

③抽象類是為了繼承,為了多态

最後來看一個示例代碼:

定義一個抽象類,其中包含抽象方法Run()

<code>   </code><code>{</code><code>//Run的抽象方法,隻要是繼承我的子類都要實作這個方法</code>

<code>   </code><code>}</code>

分别定義兩個子類,繼承抽象類Person

<code>        </code><code>//public abstract void Swiming();</code>

<code>           </code><code>// base.Say();</code>

<code>    </code><code>class</code> <code>Worker:Person</code>

<code>            </code><code>Console.WriteLine(</code><code>"我是勞工,繼承了父類,我每天在廠區跑!"</code><code>);</code>

為了表現多态,我們編寫一個方法如下:

<code>//該方法變現了多态,根據需要傳回子類的對象</code>

<code>        </code><code>public</code> <code>static</code> <code>Person GetEntity(</code><code>string</code> <code>str)</code>

<code>            </code><code>if</code><code>(str==</code><code>"學生"</code><code>)</code>

<code>            </code><code>{</code>

<code>                </code><code>return</code> <code>new</code> <code>Student();</code>

<code>            </code><code>}</code>

<code>            </code><code>else</code> <code>if</code><code>(str==</code><code>"勞工"</code><code>)</code>

<code>                </code><code>return</code> <code>new</code> <code>Worker();</code>

<code>            </code><code>return</code> <code>null</code><code>;</code>

main函數中的代碼如下:

<code>            </code><code>//不直接執行個體化父類對象,隻是聲明一個父類對象的變量來接收方法的傳回值</code>

<code>            </code><code>Person p = GetEntity(Console.ReadLine());</code>

運作,分别輸入“勞工”和“學生”的列印結果如下:

【C#小知識】C#中一些易混淆概念總結(七)---------解析抽象類,抽象方法

到這裡這一部分的内容就結束了,希望大家多多提寶貴的意見。

     本文轉自yisuowushinian 51CTO部落格,原文連結:http://blog.51cto.com/yisuowushinian/1357647,如需轉載請自行聯系原作者