[ASP.NET]91之ASP.NET由淺入深 不負責講座 Day15 – Abstract與Interface

[ASP.NET]91之ASP.NET由淺入深 不負責講座 Day15 – Abstract與Interface

前言
上次介紹了OO的三個特性:封裝、繼承跟多型,大家還記得嗎?有辦法用自己的話來說明與舉例子嗎?
如果還沒,建議您先去看前面那一篇:
[ASP.NET]91之ASP.NET由淺入深 不負責講座 Day14 – Object Oriented (1)

這一篇文章,要介紹更抽象的abstract與interface。
希望透過這篇文章,讓原本攪在一起的觀念可以釐清一下。

首先,
抽象這個term本身就很抽象,我的自己用一段話來定義『抽象』:
抽象就是不管實作內容。抽象就是用實際世界的角度思考,而非寫code的角度思考。
接下來,我們來說明Abstract與Interface:

Issues

  1. Abstract
    1. 不能被直接實體化使用,所以我們可以把實體化沒有任何意義的class宣告成abstract
    2. 宣告成abstract的property與function都會強制子類別需overrides
    3. 用來定義抽象的屬性、行為
    4. 也是一種Super Class,可以在abstract class裡面,定義需被繼承且覆寫,以及可被繼承的實體屬性與方法,也就是方法內具備內容。
  2. Interface
    1. 類似contract的概念,實作介面就該履行內容
    2. 抽象化的屬性與行為
    3. 不需要擁有相同的父類別,也可以具備同樣的行為
    4. 介面的定義應該簡潔明瞭 (SOLID原則中的L原則)
  3. Abstract與Interface在系統中扮演的角色
    1. Abstract:決定了系統的Reuse程度。透過繼承與限制,可決定子類別的設計方式。
    2. Interface:決定了系統設計的抽象程度。透過實作介面,來定義物件之間的抽象行為與關係。
    3. Abstract與Interface的差異
      其實Interface可以當作abstract極致化的概念產物,
      但是abstract class裡面,是可以包含實作的,這是最大的差異。


光這樣說,有一點難以理解。我們舉個例子來說明 (雖然單純用文字說明也不是挺好懂的)
PS:這個例子是Design Pattern裡面,Template Method pattern的實作case。

例如:

  1. 我們有一個interface,叫做『生活起居』,裡面有個方法是『起床』。
  2. 我們有一個abstract class,叫做『每個家庭的爸爸』,實作『生活起居』這個interface。
    我們這個爸爸的abstract class裡面,定義了三個abstract protected(或public)的void,分別是『刷牙』、『洗臉』跟『大便』。因為定義成abstract,所以這三個方法實際的內容,得由子類別覆寫後來決定。
  3. 我們希望繼承『每個家庭的爸爸』的子類別,他們的『起床』行為,裡面就是要依序執行『每個家庭的爸爸』abstract class裡面的『刷牙』、『洗臉』跟『大便』這三個void。由這三個方法組成『每個家庭的爸爸』的『起床行為』。
  4. 倘若我們要限制子類別不可以修改此『起床』行為,那麼我們就寫成這樣
    interface
     public interface ICommonLife
        {
            /// <summary>
            /// 起床
            /// </summary>        
            void GetUp();
        }


    abstract class
        public abstract class AbstractDaddy : ICommonLife
        {
            public abstract void 刷牙();        
            public abstract void 洗臉();        
            public abstract void 大便();
    
            #region ICommonLife 成員
    
            /// <summary>
            /// 起床
            /// </summary>
            /// <remarks>
            /// 當繼承AbstractDaddy的時候,強迫繼承的子類別其GetUp行為,一定得是先刷牙、洗臉,再大便,才算完成起床的動作。
            /// 而實際的刷牙、洗臉跟大便的內容跟方式,則由子類別自行決定。
            /// 這樣的限制(或稱為reuse,因為子類別不需在重複定義這樣的起床行為),只有abstract可以做,interface做不了
            /// </remarks>
            public void GetUp()
            {
                this.刷牙();
                this.洗臉();
                this.大便();
            }
            #endregion
        }


    Class Diagram長這樣:
    image


結論:如同註解內所提到,因為interface無法加入實作內容 (也因此interface才可以定義抽象行為),所以要達到這個case裡面限制『起床』行為的需求,只能透過abstract來作。

 



最後,請想學習的客倌,看完這篇文章思考一下,下列的問題該如何回答:

  1. 什麼是abstract? 請舉例。
  2. 什麼是interface? 請舉例。
  3. abstract與interface的差異? 請舉出只能用abstract,不可以用interface的例子。
  4. abstract與interface在系統中扮演的角色為何?



blog 與課程更新內容,請前往新站位置:http://tdd.best/