zoukankan      html  css  js  c++  java
  • 《C#入门详解》刘老师 抽象类与开闭原则

    抽象类&开闭原则

    一、概念

    为做基类而生的“抽象类”与“开放/关闭原则”

    抽象类是函数成员没有被完全实现的类,就是类里面可以有若干个函数成员,其中至少有一个函数成员没有被实现。没有被实现的函数成员一定要用abstract来修饰。不允许实例化一个抽象类。

    一个类不能被实例化,就剩两个用处了。第一,作为基类,在派生类中把没有实现的函数成员实现。第二,抽象类作为基类去声明变量,用基类类型的变量去引用子类类型的实例。

    子类如果没有全部实现父类(抽象类)的抽象方法,则该子类依然是抽象类。

     

    二、抽象类与接口

    如果单从具体代码来看,对这两个概念很容易模糊,甚至觉得接口就是多余的,因为单从具体功能来看,除多重继承外,抽象类似乎完全能取代接口。但是,难道接口的存在是为了实现多重继承?当然不是。我认为,抽象类和接口的区别在于使用动机。使用抽象类是为了代码的复用,而使用接口的动机是为了实现多态性。所以,如果你在为某个地方该使用接口还是抽象类而犹豫不决时,那么可以想想你的动机是什么。

    看到有朋友对IVehicle这个接口的质疑,我个人的理解是,IVehicle这个接口该不该定义,关键看具体应用中是怎么个情况。如果我们的项目中有Car和Heavy Car,都继承Vehicle,而且Car和Heavy Car绝大多数方法都相同,只有一个方法Running Speed()不同,那么当然定义一个AbstractVehicle抽象类比较合理,因为它可以把其他所有方法都包含进去,子类只定义Running Speed(),大大减少了重复代码量。

    但是,如果我们程序中的Car 和 Heavy Car两个类基本没有共同代码,而且有一个Run类需要实例化他们,并且不希望知道他们是汽车还是重型卡车,而只需把他们当作车来看待,并实现多态,那么定义成接口就有必要了。

    总而言之,接口与抽象类的区别主要在于使用的动机,而不在于其本身。而一个东西该定义成抽象类还是接口,要根据具体环境的上下文决定。

    再者,我认为接口和抽象类的另一个区别在于,抽象类和它的子类之间应该是一般和特殊的关系,而接口仅仅是它的子类应该实现的一组规则。(当然,有时也可能存在一般与特殊的关系,但我们使用接口的目的不在这里)如,交通工具定义成抽象类,汽车、飞机、轮船定义成子类,是可以接受的,因为汽车、飞机、轮船都是一种特殊的交通工具。再譬如Icomparable接口,它只是说,实现这个接口的类必须要可以进行比较,这是一条规则。如果Car这个类实现了Icomparable,只是说,我们的Car中有一个方法可以对两个Car的实例进行比较,可能是比哪辆车更贵,也可能比哪辆车更大,这都无所谓,但我们不能说“汽车是一种特殊的可以比较”,这在文法上都不通。

  • 相关阅读:
    Mac Office2016 安装及破解
    Axure 下载安装
    MacBook Pro常用快捷键
    MySQL 关于case when结合group by用时的写法举例
    RFID第二次作业
    Javascript函数柯里化(curry)
    binarySearch二分查找——Javascript实现
    KMP算法——Javascript实现
    从输入 URL 到页面加载完成的过程中都发生了什么事情?
    丁又专老师作业——Java检测代码
  • 原文地址:https://www.cnblogs.com/zfcsharp/p/13737393.html
Copyright © 2011-2022 走看看