• C#面向对象:多态


    此文章转载网站:https://www.cnblogs.com/qixinbo/p/8244583.html  

    多态:

           有多态之前必须要有继承,只有多个类同时继承了同一个类,才有多态这样的说法。

      在继承关系的前提下,实例化出不同的对象,这些对象调用相同的方法,但是却表现出不同的行为,这就叫做多态。

           在 C#语言中体现多态有三种方式:虚方法,抽象类, 接口。  

     

    1、虚方法

    1.1什么是虚方法?

    在父类中使用 virtual 关键字修饰的方法, 就是虚方法。在子类中可以使用 override 关键字对该虚方法进行重写。

    Virtual方法也可以单独执行。

    1.2虚方法语法

    父类:

    public virtual 返回值类型 方法名()

    {

    方法体代码;

    }

    子类:

    public override 返回值类型 方法名()

    {

    方法体代码;

    }

    1.3.虚方法使用细节

    ①将父类的方法标记为虚方法, 就是在父类方法的返回值前加 virtual 关键字,表示这个方法可以被子类重写。

    ②子类重写父类方法, 在子类的方法的返回值前加 override 关键字。

    ③父类中的虚方法, 子类可以重写, 也可以不重写。

    ④父类中用 virtual 修饰的方法, 可以用于实现该方法共有的功能(比如初始化该方法), 然后在子类重写该方法时, 使用 base 关键字调用父类中的该方法。

    2、抽象方法

    2.1 抽象方法

    虚方法到抽象方法

    父类里面用 virtual 关键字修饰的方法叫做虚方法,子类可以使用override重新该虚方法,也可以不重写。

    虚方法还是有方法体的,当我们父类中的这个方法已经虚到完全无法确定方法体的时候,就可以使用另外一种形式来表现,这种形式叫抽象方法。

    2.2抽象方法语法

    抽象方法的返回值类型前用关键字abstract修饰,且无方法体。

    public abstract void Hello();

    抽象方法必须存在于抽象类中。

    abstract class FuLei

    在定义类的关键字class前面加abstract 修饰的类就是抽象类。

    子类继承抽象类,使用 override关键字重写父类中所有的抽象方法。

    2.3.3 抽象类注意事项

    <1>抽象类中不一定要有抽象方法, 但是抽象方法必须存在于抽象类中。

    <2>抽象类不能被实例化, 因为抽象类中有抽象方法(无方法体), 如果真能实例化抽象类的话, 调用这些无方法体的方法是没有任何意义的, 所以无法实例化。

    2.3.4 使用场景

    <1>当父类中的方法不知道如何去实现的时候, 可以考虑将父类写成抽象类,将方法写成抽象方法。

    <2>如果父类中的方法有默认实现, 并且父类需要被实例化, 这时可以考虑将父类定义成一个普通类, 用虚方法实现多态。

    <3>如果父类中的方法没有默认实现, 父类也不需要被实例化, 则可以将该类定义为抽象类。

    3、接口

    3.1 接口语法

    抽象类到接口

    当抽象类中所有的方法都是抽象方法的时候,这个时候可以把这个抽象类用另外

    一种形式来表现,这种形式叫接口。

    虚方法,抽象类,接口是三种实现多态的手段。

    语法格式要求:

    接口使用 interface 关键字定义,没有 class 关键字,接口名一般使用 “IXxxx”

    (实际使用要在interface前加public ,因为我有时候为了依赖注入,直接使用接口来装载子类对象) 

    这种方式进行书写, 在一堆脚本中通过名字判断, I 开头的都是接口。

    接口中不能包含字段,但是可以包含属性(? 没有字段,如何写属性那? ?使用自动属性 public int Age {get;set;})

    (公共字段只是类用public修饰符所公开的简单公共变量,而属性则是对字段的封装,它使用get和set访问器来控制如何设置或返回字段值。)

    接口中定义的方法不能有方法体,全是抽象方法,但又不需要用 abstract 修饰;

    接口中的成员不允许添加访问修饰符,默认都是 public;

    (既然是接口里面的方法,当然需要从外面调用,必然是public了。)

    3.2 接口注意事项

    <1>接口中所有的方法都是抽象方法,所以接口不能被实例化;

    <2>一个类可以实现多个接口,被实现的多个接口之间用逗号分隔开;

    class Batmobile:Car,IFly

    <3>一个接口可以继承多个接口, 接口之间也要用逗号分隔。

    类与类之间只能单继承。

    使用场景:

    接口是一种能力,是一种规范,当我们对现在已经存在的类的继承关系进行功能扩展的时候,就可以使用接口来完成相应的工作。

    具有特殊功能属性或者方法的子类,使用接口完成他的特殊点。

    接口独立于原有的继承关系之外

    3.3 多态之接口案例

    3.3.1 C#属性

    常规属性:先定义一个私有的字段,然后在为这个私有字段封装一个公开的属性,在属性中实现get和set两个方法,这种方式叫做常规属性。

      当我们使用常规属性的时候,可以在get和set方法中,编写逻辑代码对取值和赋值进行逻辑的校验。这种方式是我们之前一直在使用的方式。

      自动属性:在某些情况下,属性的get和set只是完成字段的取值和赋值操作,而不包含任何附加的逻辑代码,这个时候可以使用自动属性。

    例如:

    public int Age {get;set;}

    不用写字段,直接写属性

    当我们使用自动属性的时候, 就不需要再写对应的字段了, C#编译器会自动给我们的自动属性提供一个对应的字段。

    注意:在接口中使用属性,就要写自动属性的格式,因为接口中不支持字段。

    总结:

    记牢语法格式!

    使用场景对比

    虚方法:父类中的个别方法用虚方法实现,然后允许子类在有需要的情况下重写这些虚方法。

    virtual和override

    父类中包含虚方法也可以实例化对象。

    抽象类:父类定义一系列的规范,子类去把父类里面定义的这些规范全部实现。

    Abstract和override

    父类是抽象类,那么不能单独实例化。

    接口:是一种功能的扩展,是在原有的类的继承关系以外的新功能的扩展。

  • 相关阅读:
    Integration Services学习(3):数据流任务(下) (转自游子吟)
    delete和truncate的区别
    Integration Services 学习(6):包配置 (转自游子吟)
    SSIS 学习(2):数据流任务(上) (转自游子吟)
    Integration Services 学习(5):容器 (转自游子吟)
    Integration Services 学习(4):变量和表达式 (转自游子吟)
    in与exist , not in与not exist 的区别
    SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY
    关于Reporting Services的Q&A
    SSIS 学习(1) 概要 (转自游子吟)
  • 原文地址:https://www.cnblogs.com/yinyongle/p/10523154.html
Copyright © 2020-2023  润新知