面向對象三大特性之多態


多態是什么?

    用一句話來概括下,多態就是同一操作(方法)作用於不同的對象時,可以有不同的解釋,產生不同的執行結果。這句話看似簡

    單,實則頗有深意。下面我們來深入理解一多態的意義及如何使用多態。

 

使用多態編程的好處

    在使用繼承編程的時候,我們一般是把不同子類的方法分別寫在不同的子類中,使用的時候用is a關鍵字來判斷對象是哪種類型

    的,然后進行強制轉換來使用不同對象的方法。

      但是,如果有多個子類的話,使用的時候難道要寫多個if語句來判斷對象是哪種類型的嗎?這樣會產生很多冗余代碼,也會很繁

    瑣。

    使用多態編程可以很好的解決這個問題。在父類寫一個虛方法或抽象方法,子類去重寫父類的方法,在調用的時候系統會根據對

    象運行時的類型決定調用哪個方法。這樣子是不是簡潔多了?

 

小例子

    假設我們有一個“書”類,然后有很多子類繼承“書”類。例如“計算機組成原理”類繼承“書類”,“深入Java面向對象”繼承“書”類...

    而這些子類都有類似的方法,即被不同的人使用。

    下面我們來用代碼實現它。

 1 /// <summary>
 2     /// 演示類
 3     /// </summary>
 4     class Demo
 5     {
 6         List<Book> books = new List<Book>();
 7 
 8         /// <summary>
 9         /// 測試
10         /// </summary>
11         public void Test()
12         {
13             books.Add(new ComputerBook());
14             books.Add(new JavaBook());
15 
16             foreach (Book item in books)
17             {
18                 if (item is ComputerBook)
19                 {
20                     ((ComputerBook)item).ByReading();
21                 }
22                 if (item is JavaBook)
23                 {
24                     ((JavaBook)item).ByReading();
25                 }
26             }
27         }
28     }
29 
30     /// <summary>
31     /// 書類
32     /// </summary>
33     class Book
34     {
35         
36     }
37 
38     /// <summary>
39     /// 計算機書籍
40     /// </summary>
41     class ComputerBook : Book
42     {
43         /// <summary>
44         /// 被閱讀
45         /// </summary>
46         public void ByReading()
47         {
48             Console.WriteLine("我是計算機類書籍,被在校大學生使用。");
49         }
50     }
51 
52     /// <summary>
53     /// Java書籍
54     /// </summary>
55     class JavaBook : Book
56     {
57         /// <summary>
58         /// 被閱讀
59         /// </summary>
60         public void ByReading()
61         {
62             Console.WriteLine("我是Java書籍,被在業Java程序員使用。");
63         }
64     }

     

 

     通過這段代碼可以發現:在使用子類對象的時候需要先用is a來判斷子類對象時哪種類型的。那么也就是說,如果一個父類有10

     個派生類(子類)的話,就要用10個if判斷語句來判斷子類對象是哪種類型了,未免太過繁瑣。

     這時,虛方法就該登場了。

 

虛方法

     概念:

        虛方法有方法體,可以被重寫,使用virtual來修飾。

        父類中的虛方法並非必須被子類重寫,在父類中可以給出虛方法的默認實現。如果子類不重寫父類的虛方法則依然執行

        父類的默認實現。如果子類重寫了父類的虛方法,則執行子類重寫后的方法。

        其實方法重載也是實現多態的一種形式,只是重載的方法都在同一個類中,而用虛方法實現多態的方法散布在有繼承關

        系的多個類中。

    使用:

        在父類中使用virtual關鍵字定義虛方法,在子類中使用override關鍵字來重寫父類中的虛方法。

    override關鍵字:

        通過override關鍵字來修飾的方法,稱為方法的重寫。

 

    下面我們用虛方法來改造一下上面的例子

 1     /// <summary>
 2     /// 演示類
 3     /// </summary>
 4     class Demo
 5     {
 6         List<Book> books = new List<Book>();
 7 
 8         /// <summary>
 9         /// 測試
10         /// </summary>
11         public void Test()
12         {
13             books.Add(new ComputerBook());
14             books.Add(new JavaBook());
15             //遍歷時不用加判斷
16             foreach (Book item in books)
17             {
18                 item.ByReading();
19             }
20         }
21     }
22 
23     /// <summary>
24     /// 書類
25     /// </summary>
26     class Book
27     {
28         public virtual void ByReading()
29         {
30 
31         }
32     }
33 
34     /// <summary>
35     /// 計算機書籍
36     /// </summary>
37     class ComputerBook : Book
38     {
39         /// <summary>
40         /// 被閱讀
41         /// </summary>
42         public override void ByReading()
43         {
44             Console.WriteLine("我是計算機類書籍,被在校大學生使用。");
45         }
46     }
47 
48     /// <summary>
49     /// Java書籍
50     /// </summary>
51     class JavaBook : Book
52     {
53         /// <summary>
54         /// 被閱讀
55         /// </summary>
56         public override void ByReading()
57         {
58             Console.WriteLine("我是Java書籍,被在業Java程序員使用。");
59         }
60     }

    

 

    可以看出,使用虛方法來寫代碼簡便了許多。但是問題又來了,一般子類的父類和在父類中的虛方法是“宏觀”的,“抽象”的,我

    們不想讓這個父類被實例化並且只提供方法的定義,由子類去實現這個方法,該怎么做呢?

    如何解決這個問題呢?我們可以使用抽象類和抽象方法來實現。

 

抽象類和抽象方法

    abstract關鍵字:

        abstract關鍵字用來修飾抽象類和抽象方法。

    抽象類:

        使用abstract關鍵字修飾的抽象類不能被實例化。

        抽象類中可以有非抽象方法。

        抽象類不能是密封的或者靜態的。

    抽象方法:

        使用abstract關鍵字修飾的抽象方法是一個沒有實現的方法,由子類重寫抽象方法來實現。

        抽象方法沒有大括號,直接在小括號后以分號";"結尾。

        含有抽象方法的類必須是抽象類。

        抽象方法必須在其子類中實現,除非它的子類也是抽象類。

    

    下面我們使用抽象類和抽象方法再次改造上面的例子

 1     /// <summary>
 2     /// 演示類
 3     /// </summary>
 4     class Demo
 5     {
 6         List<Book> books = new List<Book>();
 7 
 8         /// <summary>
 9         /// 測試
10         /// </summary>
11         public void Test()
12         {
13             books.Add(new ComputerBook());
14             books.Add(new JavaBook());
15             //遍歷時不用加判斷
16             foreach (Book item in books)
17             {
18                 item.ByReading();
19             }
20         }
21     }
22 
23     /// <summary>
24     /// 書類
25     /// </summary>
26     abstract class Book
27     {
28         public abstract void ByReading();
29     }
30 
31     /// <summary>
32     /// 計算機書籍
33     /// </summary>
34     class ComputerBook : Book
35     {
36         /// <summary>
37         /// 被閱讀
38         /// </summary>
39         public override void ByReading()
40         {
41             Console.WriteLine("我是計算機類書籍,被在校大學生使用。");
42         }
43     }
44 
45     /// <summary>
46     /// Java書籍
47     /// </summary>
48     class JavaBook : Book
49     {
50         /// <summary>
51         /// 被閱讀
52         /// </summary>
53         public override void ByReading()
54         {
55             Console.WriteLine("我是Java書籍,被在業Java程序員使用。");
56         }
57     }

     

    

    到了這里,我們可以發現使用虛方法和抽象方法來編程(也就是多態)更符合面向對象編程的思想,並且可以大幅的提升代碼的

    可讀性和減少冗余的代碼。

    用更少的代碼實現相同的實現,這感覺,很爽的。

 

 

 

    

 


免責聲明!

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



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