[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
        {
            /// 
            /// 起床
            ///         
            void GetUp();
        }



    abstract class
        public abstract class AbstractDaddy : ICommonLife
        {
            public abstract void 刷牙();        
            public abstract void 洗脸();        
            public abstract void 大便();
    
            #region ICommonLife 成员
    
            /// 
            /// 起床
            /// 
            /// 
            /// 当继承AbstractDaddy的时候,强迫继承的子类其GetUp行为,一定得是先刷牙、洗脸,再大便,才算完成起床的动作。
            /// 而实际的刷牙、洗脸跟大便的内容跟方式,则由子类自行决定。
            /// 这样的限制(或称为reuse,因为子类不需在重复定义这样的起床行为),只有abstract可以做,interface做不了
            /// 
            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在系统中扮演的角色为何?



或许您会对下列培训课程感兴趣:

  1. 2019/7/27(六)~2019/7/28(日):演化式设计:测试驱动开发与持续重构 第六梯次(中国台北)
  2. 2019/8/16(五)~2019/8/18(日):【C#进阶设计-从重构学会高易用性与高弹性API设计】第二梯次(中国台北)
  3. 2019/9/21(六)~2019/9/22(日):Clean Coder:DI 与 AOP 进阶实战 第二梯次(中国台北)
  4. 2019/10/19(六):【针对遗留代码加入单元测试的艺术】第七梯次(中国台北)
  5. 2019/10/20(日):【极速开发】第八梯次(中国台北)

想收到第一手公开培训课程资讯,或想询问企业内训、顾问、教练、咨询服务的,请洽 Facebook 粉丝专页:91敏捷开发之路。