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!

  • 相关阅读:
    oracle 10g 免安装客户端在windows下配置
    sql2005 sa密码
    使用windows live writer 有感
    windows xp SNMP安装包提取
    汉化groove2007
    迁移SQL server 2005 Reporting Services到SQL server 2008 Reporting Services全程截图操作指南
    foxmail 6在使用中的问题
    AGPM客户端连接不上服务器解决一例
    SpringSource Tool Suite add CloudFoundry service
    Java 之 SWing
  • 原文地址:https://www.cnblogs.com/gygg/p/13372769.html
Copyright © 2011-2022 走看看