马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#技术求助 ASP.NET技术求助

【源码下载】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接外包项目】 面试-葵花宝典下载

官方一群:

官方二群:

C#面向对象之多态

[复制链接]
查看2181 | 回复0 | 2019-9-26 09:15:35 | 显示全部楼层 |阅读模式

一、多态

  多态是从继续中引出来的概念,即差别的派生类对基类的类似方法表现出差别的举动。如下面例子中动物的游泳方法:

  1. 1 /// <summary>
  2. 2 /// 动物
  3. 3 /// </summary>
  4. 4 public class Animal
  5. 5 {
  6. 6 public string Swimming()
  7. 7 {
  8. 8 return "不会";
  9. 9 }
  10. 10 }
  11. 11 /// <summary>
  12. 12 /// 鸡
  13. 13 /// </summary>
  14. 14 public class Chicken : Animal
  15. 15 {
  16. 16
  17. 17 }
  18. 18 /// <summary>
  19. 19 /// 狗
  20. 20 /// </summary>
  21. 21 public class Dog : Animal
  22. 22 {
  23. 23 }
  24. 24 /// <summary>
  25. 25 /// 蛙
  26. 26 /// </summary>
  27. 27 public class Frog : Animal
  28. 28 {
  29. 29 }
复制代码

当用户利用派生类鸡的游泳方法时,由于基类的游泳方法满足鸡的需求,则直接调用基类的游泳方法返回不会;当用户利用派生类狗和蛙的游泳方法时,由于基类的游泳方法的实现不满足狗和蛙的需求,以是狗和蛙必要实现自己的逻辑。怎样实现狗的狗刨和蛙的蛙泳?答案是重写(利用关键字virtual和override在派生类中重新实现基类的同名方法)。

  1. 1 public class Animal
  2. 2 {
  3. 3 //设计基类时对必要在派生类中重写的方法利用virtual修饰,利用virtual修饰的方法叫做虚方法
  4. 4 public virtual string Swimming()
  5. 5 {
  6. 6 return "不会";
  7. 7 }
  8. 8 }
  9. 9 public class Dog : Animal
  10. 10 {
  11. 11 //派生类若要重写基类的方法,可利用override修饰与基类同名的方法,实现自己的举动,被override修饰的方法也可被重写
  12. 12 public override string Swimming()
  13. 13 {
  14. 14 return "狗刨";
  15. 15 }
  16. 16 }
  17. 17 public class Frog : Animal
  18. 18 {
  19. 19 //派生类若要重写基类的方法,可利用override修饰与基类同名的方法,实现自己的举动,被override修饰的方法也可被重写
  20. 20 public override string Swimming()
  21. 21 {
  22. 22 return "蛙泳";
  23. 23 }
  24. 24 }
复制代码

上面的例子中,差别的派生类(鸡、狗、蛙)对基类(动物)的游泳方法表现出各自差别的结果,即类的多态特性。

  也可以利用另一种方式遮挡来实现类的多态特性,即派生类利用new关键字来实现与基类同名方法的差别举动。

  1. 1 public class Animal
  2. 2 {
  3. 3 public string Swimming()
  4. 4 {
  5. 5 return "不会";
  6. 6 }
  7. 7 }
  8. 8 public class Dog : Animal
  9. 9 {
  10. 10 //利用new关键字遮挡基类的同名方法,也可以利用到派生类的其他成员中
  11. 11 public new string Swimming()
  12. 12 {
  13. 13 return "狗刨";
  14. 14 }
  15. 15 }
  16. 16 public class Frog : Animal
  17. 17 {
  18. 18 //利用new关键字遮挡基类的同名方法,也可以利用到派生类的其他成员中
  19. 19 public new string Swimming()
  20. 20 {
  21. 21 return "蛙泳";
  22. 22 }
  23. 23 }
复制代码

注:重要利用的情况是当我们没有修改基类的权限又希望实现派生类的多态特性时。

二、C#关键字:base

  在派生类的方法中利用“base.基类方法名”可以复用基类的方法。

三、C#关键字:sealed

  由于被override修饰的方法是隐式可重写的,以是当我们不希望被override修饰的方法被重写时,可以利用sealed关键字防止被重写。

  1. 1 public class Dog : Animal
  2. 2 {
  3. 3 //Dog类不希望自己的游泳方法被它的派生类重写
  4. 4 public sealed override string Swimming()
  5. 5 {
  6. 6 return "狗刨";
  7. 7 }
  8. 8 }
复制代码

注:在防止被重写中,sealed关键字必须与override关键字类似存在。

四、抽象类和抽象方法

  当一个基类的作用只是为派生类提供公共成员,而无其他实际意义时,我们不希望用户通过new关键字创建这个基类,可将基类设计成抽象类,这样用户就不能用new关键字创建它。利用abstract关键字修饰类可使其变成抽象类。

  当抽象类的某个方法在派生类中表现出多态性时,这个方法的实现对派生来说是无用的,我们希望全部派生类必须重写基类的这个方法,可将这个方法设计成抽象方法,这样抽象类的抽象方法不消提供默认实现而且派生类必须利用override重写此抽象方法。如果派生类不重写这个抽象方法自身也将成为一个抽象类。利用abstract关键字修饰方法可使其变成抽象方法。

  1. 1 /// <summary>
  2. 2 /// 可调度温度的电子装备
  3. 3 /// </summary>
  4. 4 public abstract class TemperatureElectric
  5. 5 {
  6. 6 protected int temperature;
  7. 7
  8. 8 public abstract int Up();
  9. 9
  10. 10 public abstract int Down();
  11. 11 }
  12. 12 /// <summary>
  13. 13 /// 空调
  14. 14 /// </summary>
  15. 15 public class AirConditioner : TemperatureElectric
  16. 16 {
  17. 17 public override int Up()
  18. 18 {
  19. 19 if (temperature < 30)
  20. 20 temperature += 1;
  21. 21 return temperature;
  22. 22 }
  23. 23
  24. 24 public override int Down()
  25. 25 {
  26. 26 if (temperature > 16)
  27. 27 temperature -= 1;
  28. 28 return temperature;
  29. 29 }
  30. 30 }
  31. 31 /// <summary>
  32. 32 /// 冰箱
  33. 33 /// </summary>
  34. 34 public class Refrigerator : TemperatureElectric
  35. 35 {
  36. 36 /// <summary>
  37. 37 /// 提拔冷藏温度
  38. 38 /// </summary>
  39. 39 public override int Up()
  40. 40 {
  41. 41 if (temperature < 7)
  42. 42 temperature += 1;
  43. 43 return temperature;
  44. 44 }
  45. 45
  46. 46 /// <summary>
  47. 47 /// 低沉冷藏温度
  48. 48 /// </summary>
  49. 49 public override int Down()
  50. 50 {
  51. 51 if (temperature > 3)
  52. 52 temperature -= 1;
  53. 53 return temperature;
  54. 54 }
  55. 55 }
复制代码

五、几种概念的对比

1、重载与重写

重载和重写的类似点在于他们都是对同名的方法利用。

重载和重写的差别点:在利用范围上,前者利用在单个类中,后者利用在两个或多个有继续关系的类中;在利用意图上,前者是写法上的简化,后者是功能上的扩展。

2、重写与遮挡

重写与遮挡的类似点在于他们都是对基类同名方法的扩展。

重写与遮挡的差别点在于,通过A a = new B();B继续于A,前者调用B的同名方法,而后者调用的是A的同名方法;前者用于自动设计,后者用于被动修改。

  1. 1 public class RealizeObject
  2. 2 {
  3. 3 public void Realize()
  4. 4 {
  5. 5 //Dog是通过virtual重写的Animal
  6. 6 Animal animal = new Dog();
  7. 7 animal.Swimming();//输出的狗刨
  8. 8
  9. 9 //Dog是通过new遮挡的Animal
  10. 10 Animal animal = new Dog();
  11. 11 animal.Swimming();//输出的不会
  12. 12 }
  13. 13 }
复制代码

3、虚方法和抽象方法

虚方法与抽象方法的类似点在于他们都可以被重写。

虚方法与抽象方法的差别点:在利用范围上前者大于后者,前者利用在非密封类中,后者只能利用在抽象类中;在利用方式上,前者必须有实现部分,后者不能有实现部分;在派生类中,前者可重写可不重写,后者必须重写。

4、抽象类与接口范例的区别(见C#接口范例)







来源:https://www.cnblogs.com/yaojieyuan/archive/2019/09/25/11587026.html
C#论坛 www.ibcibc.com IBC编程社区
C#
C#论坛
IBC编程社区
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则