zoukankan      html  css  js  c++  java
  • C#中的抽象类abstract与开闭原则

    什么是接口和抽象类:

    具体类→抽象类→接口:越来越抽象,内部实现的东西越来越少

    抽象类是未完全实现逻辑的类(可以有字段和非public成员,它们代表了“具体逻辑”)

    抽象类为复用而生:专门作为基类来使用,也具有解耦功能

    封装确定的,开放不确定的,推迟到合适的子类中去实现

    接口是完全未实现逻辑的“类”(“纯虚类”;只有函数成员;成员全部public)

    接口为解耦而生:“高内聚,低耦合”

    都不能实例化,只能用来声明变量、引用具体类(concrete class)的实例

    抽象类abstract

    在介绍抽象类前,先介绍一个设计原则,SOLID设计原则中的Open Close Principle(开闭原则),抽象类和开闭原则之间有非常密切的联系,SOLID设计原则介绍:https://www.cnblogs.com/huangenai/p/6219475.html,开闭原则(OCP)认为“软件体应该是对于扩展开放的,但是对于修改封闭的”的概念,意思就是说我们应该封装不变的、稳定的、确定的成员,而把不确定、有可能改变的成员声明为抽象成员,并留给子类去实现。下面使用代码实例来介绍抽象类:

    首先定义两个类Car(汽车类)和Truck(卡车类)

    两个类都有Run(跑)、Stop(停)两个方法,我们发现两个类具有相同方法Stop(),这个时候我们可以定义一个基类(Vehicle)来实现这个相同方法,然后使两个类都派生至基类(Vehicle)。

    这时如果我们想实现多态,实例化基类调用Run()方法是不行的,因为基类里面没有实现Run()方法,只能调用基类成员。

    这时一般的解决方法是在基类中再加入一个Run()方法,传入参数,基类通过判断参数来实现Run()方法

    但是如果我这时又添加了一个新的类(Racecar)来继承基类Vehicle,那么就又要修改基类Vehicle的代码,但是这样就严重的违反了开闭原则,除非修改或添加功能,否则我们不应该经常修改封装的基类代码,这样不易于后期维护。

    解决这个问题,我们可以用virtual虚方法来实现,将基类中的Run()方法定义为虚方法,然后在子类中重写,那么在添加基类Vehicle的派生类时就不用修改基类的代码了。

    但是我们发现基类Vehicel本身的Run()方法永远也不会执行,都是子类来重写它,那么它方法体里面的代码就没有意义,这时我们就可以把Run()方法定义成一个抽象方法,那么含有抽象方法的Vehicle类就变成了一个抽象类。

    抽象类是不能实例化的,因为它含有抽象方法,没有方法体,就算创建实例成功,如果调用到抽象方法,没有方法体的实现,那么程序就会崩溃。

    这里我们可以体会到抽象类是专为基类而生的,它的作用就是以基类类型来声明变量,并且引用已经完全实现了它那些抽象成员的子类类型的实例。

    如果一个类中的所有成员都是抽象的,那么这个类就是一个接口interface。

    End!

  • 相关阅读:
    Android开发经验一判断当前屏幕是全屏还是非全屏
    Android得到控件在屏幕中的坐标
    MyBatis简单的增删改查以及简单的分页查询实现
    Coreseek:第二步建索引及測试
    极静之渊
    统计电影票房排名前10的电影并存入还有一个文件
    AAA
    FreeLink开源呼叫中心设计思想
    树后台数据存储(採用webmethod)
    [乐意黎原创] 百度统计这个坑爹货
  • 原文地址:https://www.cnblogs.com/gygg/p/13372769.html
Copyright © 2011-2022 走看看