黑马程序员--面向对象的三大基本特征(多态)(04)

来源:互联网 发布:java中interrupt用法 编辑:程序博客网 时间:2024/05/10 02:44

----------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ---------------------


面向对象的三大基本特征:封装 继承 多态。


一. 多态

 1.多态相关概念

      ① C#面向对象的多态其实就是说同一段代码(操作)作用到不同对象时能有不同的表现形态。

       多态作用:增加程序的扩展性,多态其实就是将多个不同的对象看成是一个父类对象,屏蔽掉了不同子类对象之间的差异 这样就可以写通用的代码 做通用的编程,以适应需求的不断变化;也就是说能够实现开放封闭的原则。

 2. 实现多态的方式

   (1) 使用虚方法实现多态

概念分析:

      ① 虚方法是使用virtual修饰的方法,而且不能用static来修饰

      ② 虚方法中必须有方法体(实现过程),哪怕是空实现。(注:父类中的虚方法子类不是一定要重写,根据需要)

      ③ 实现多态的方式: 将父类中的方法标记为virtual修饰的虚方法,然后在子类中用override来重写父类中的这个虚方法从而实现多态。

实例分析:

     

实例说明:

     上面演示了怎么用虚方法实现多态,在Main()方法中分别用两个Person类型的变量指向Student和Teacher对象(因为Student和Teacher类都是Person类的子类所以父类变量可以指向子类对象),然后将pers和pers1这两个Person类变量放入名为Perss的Person类数组中,最后进行遍历数组对象调用Show()方法。

    多态性体现在:尽管Perss数组中的对象类型是Person类型,但是当遍历调用数组里面对象的Show()方法时,其实调用的是子类Student和Teacher中重写的Show()方法,而并不是父类Person类中的虚方法Show(),这样虽然是同一种操作,但却有不同的结果。

      多态的扩展性假如还有一个校长类,也要实现相同的功能(表示身份的功能),则只需再加一个校长类并且继承Person类,同时用override重写Person类中的虚方法即可,在Main()中只需将一个指向校长类对象的Person类变量放入到数组中就行

    

   (2)用抽象类抽象方法实现多态

概念分析:

         ① 抽象类和抽象方法都是用abstract关键字来修饰的

         ② 抽象成员(字段,属性,方法,事件等)只能包含在抽象方法中

         ③ 抽象方法不能有任何实现过程(没有方法体),而且访问修饰符不能为private

         ④ 抽象类不能被实例化的 抽象类的作用就是为了让继承(抽象类中也可以有非抽象成员)

         ⑤ 子类继承抽象类后,子类必须将父类抽象成员(方法 属性 字段 事件等)重写 (例外:除非子类也是抽象类)

实例分析(用抽象方法实现多态):         

  

实例说明:

     上面演示了怎么用抽象方法来实现多态,同样是将Dog对象和Cat对象都赋值给一个Animal类型的变量,然后放到Animal类型的数组中,最后遍历调用父类(抽象类)中的Bark()方法和Eat()方法。

     多态性体现在:虽然ams数组里面都是Animal对象,但是当遍历调用数组中每一个对象的Bark()和Eat()方法时,其实调用的是当前Animal对象所指向的子类中的重写的方法,所以得到不同的结果。

      注意:如果父类中的方法有默认实现 而且父类需要被实例化,则可以把父类的方法当成是一个普通的类 使用虚方法来实现多态;反之就把父类作为一个抽象类 使用抽象方法来实现多态;  

    (3)接口实现多态

概念分析:    

         ① 接口:接口就是一个规范或者说协议 有了统一的规范就能写通用的代码。接口中其实就是定义了一组具有各种功能的方法。

         ② 接口语法:

         [访问修饰符]interface 接口名(通常以“I”开头)

        {

           //接口成员定义 

        }

          

      ③如果一个类既继承了父类又实现了接口,那么类必须写在前面,接口下在下面

         ④接口是一个特殊的抽象类,接口里边只是对方法进行了声明,而没有进行实现也就是说没有方法体,而且不能有任何访问修饰符 但默认为public。

         ⑤接口声明不包括数据成员,只能包含方法、属性、事件、索引等成员。

      ⑥接口一旦被实现,实现接口的任何非抽象类型都必须实现接口的所有成员,而且实现接口的时候不需要用override关键字直接写方法的实现。

实例分析:

     

实例说明:

   在Main()方法中虽然是将一个Person类型的对象赋值给接口IFlyable的变量,当IFlyable类型的变量ifly调用自己的成员属性Name和成员方法Fly()方法时,其实调用的是实现该接口的Person中的Name属性和Fly()方法,所以得到的结果是上面的那样。

    

  3.多态中的一些总结

     (1)抽象程度:接口 > 抽象类 > 父类 > 具体类 (在定义方法参数,返回值,声明变量的时候能用抽象就不要用具体的,因为具体的可以用抽象的来代替,这样可以写通用的代码)

     (2)能使用接口不实用抽象类 能使用抽象类不使用父类,能使用父类不使用子类

     (3)避免定义“多功能的接口”,或者说“体积庞大的接口”,这样会造成接口污染,只把相关联的一组成员定义到一个接口中(尽量少定义成员在接口中)

     (4)定义多个职责单一的小接口 然后组合使用 推荐!

     (5)重载(overload)、重写(override区别

       overload:一般在同一个类中,方法名相同并且方法的参数个数不同或者参数对应位置上的类型不同

       override:将基类中用virtual或者abstract修饰的方法进行重写


----------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------