C#OOP之七 多态的学习和使用

举报
tea_year 发表于 2021/12/31 23:14:18 2021/12/31
【摘要】 视频:https://edu.csdn.net/course/detail/27107 多态 什么是多态,看看大辞典的:可以呈现不同形式的能力或状态。这一术语来源于生物系统,意指同族生物具有的相同特征。而在.Net中,多态指同一操作作用于不同的实例,产生不同运行结果的机制。  多态可以分为静态多态...

视频:https://edu.csdn.net/course/detail/27107

多态

什么是多态,看看大辞典的:可以呈现不同形式的能力或状态。这一术语来源于生物系统,意指同族生物具有的相同特征。而在.Net中,多态指同一操作作用于不同的实例,产生不同运行结果的机制。

 多态可以分为静态多态和动态,即编译时多态和运行时多态。静态多态比如,汉语中有“打”这个字,但是与不同的字组合,则形成了不同的单词组合,来代表不同的含义,如打饭、打架、打车、打卡等,这种方式是在实现已经定义好了的意思,不管谁打饭、谁打架都代表一样的意思,类似于编译器首先将同名称的代码定义好了,编程中的具体实现是重载;

动态测试,相同的词语而不同对象执行不同的行为,听到“Cut”后,理发师执行的动作是剪断头发,外科医生切开皮肤做手术,演员停止表演。在编程中即运行时多态,不同对象对于同一个方法(Cut)调用的不同行为。

静态多态:即编译器就确定类、方法的关联关系,一般以方法重载来实现。如我们熟悉的计算器为例:

/*功能:实现计算器;将计算功能和用户输入分离

时间:08/09/09 星期二 第二节课

版本:6.1.1

//构成方法重载的前提是;方法名一致,参数个数不同、参数类型不一致、参数顺序不一样

*/

 


    
  1. usingSystem;
  2. class Calc
  3. {
  4. private double result; //再增加一个结果变量
  5. public double Jia(double num1,doublenum2) //加法运算:形参:num1,num2
  6. {
  7. result=num1+num2+100;
  8. return result;
  9. }
  10. public int Jia(int num1,int num2)
  11. {
  12. result=num1+num2+200;
  13. return (int)result;
  14. }
  15. publicdouble Jian(double num1,double num2) //减法运算
  16. {
  17. result=num1-num2;
  18. return result;
  19. }
  20. public int Jian(int num1,int num2) //减法运算
  21. {
  22. result=num1-num2;
  23. return (int)result;
  24. }
  25. public double Cheng(double num1,double num2) //乘法运算
  26. {
  27. result=num1*num2;
  28. return result;
  29. }
  30. public double Chu(double num1,doublenum2) //除法运算
  31. {
  32. result=num1/num2;
  33. return result;
  34. }
  35. public double PingFang(double num1)
  36. {
  37. result=num1*num1;
  38. return result;
  39. }
  40. public double NciFang(double num1,doublenum2) //num1:2的num2:5次方
  41. {
  42. result=1; //定义result为1
  43. for(int i=1;i<=num2;i++)
  44. {
  45. result=result*num1;
  46. }
  47. return result;
  48. }
  49. }
  50. /**********客户端类,即界面类***********/
  51. classClacGUI
  52. {
  53. static void Main()
  54. {
  55. Calc jisuanqi; //jisuanqi=?
  56. jisuanqi=new Calc();
  57. int x,y; //x,y为Main()的局部变量
  58. Console.Write("请输入第一个数字:");
  59. x=Convert.ToInt32(Console.ReadLine());
  60. Console.Write("请输入第二个数字:");
  61. y=Convert.ToInt32(Console.ReadLine());
  62. char op; //op为Main()的局部变量,表示操作符
  63. Console.Write("请输入您要进行的运算:+ - * / ^:"); //^:表示求N次方
  64. op=Convert.ToChar(Console.ReadLine());
  65. switch(op)
  66. {
  67. case '+': //加运算
  68. Console.WriteLine(jisuanqi.Jia(x,y));
  69. break;
  70. case '-':
  71. Console.WriteLine(jisuanqi.Jian(x,y));
  72. break;
  73. case '*': //加运算
  74. Console.WriteLine(jisuanqi.Cheng(x,y));
  75. break;
  76. case '/':
  77. if(y==0)
  78. Console.WriteLine("除数不能为0");
  79. else
  80. Console.WriteLine(jisuanqi.Chu(x,y));
  81. break;
  82. case '^':
  83. Console.WriteLine(jisuanqi.NciFang(x,y));
  84. break;
  85. default:
  86. Console.WriteLine("其他无效选择!!!");
  87. break;
  88. }
  89. }
  90. }
 

 

动态多态:也叫动态绑定(后期绑定),是在运行时通过虚方法、重写机制来实现。在.Net中虚方法以virtual关键字来标记。再来复习下virtual和override。

virtual关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。例如,此方法可被任何继承它的类重写。

默认情况下,方法是非虚拟的。不能重写非虚方法。

在该示例中,Dimensions类包含xy两个坐标和Area()虚方法。不同的形状类,如CircleCylinderSphere继承Dimensions类,并为每个图形计算表面积。每个派生类都有各自的Area()重写实现。根据与此方法关联的对象,通过调用适当的Area()实现,程序为每个图形计算并显示适当的面积。

在前面的示例中,注意继承的类 CircleSphereCylinder都使用了初始化基类的构造函数,

 


    
  1. using System;
  2. class TestClass
  3. {
  4. publicclass Dimensions
  5. {
  6. public const double PI = Math.PI;
  7. protecteddouble x, y;
  8. public Dimensions()
  9. {
  10. }
  11. public Dimensions(double x, double y)
  12. {
  13. this.x = x;
  14. this.y = y;
  15. }
  16. public virtual double Area()
  17. {
  18. return x * y;
  19. }
  20. }
  21. public class Circle : Dimensions
  22. {
  23. public Circle(double r) : base(r, 0)
  24. {
  25. }
  26. public override double Area()
  27. {
  28. return PI * x * x;
  29. }
  30. }
  31. classSphere : Dimensions
  32. {
  33. public Sphere(double r) : base(r, 0)
  34. {
  35. }
  36. public override double Area()
  37. {
  38. return 4 * PI * x * x;
  39. }
  40. }
  41. classCylinder : Dimensions
  42. {
  43. public Cylinder(double r, double h) : base(r, h)
  44. {
  45. }
  46. public override double Area()
  47. {
  48. return 2 * PI * x * x + 2 * PI * x * y;
  49. }
  50. }
  51. staticvoid Main()
  52. {
  53. double r = 3.0, h = 5.0;
  54. Dimensions c = new Circle(r);
  55. Dimensions s = new Sphere(r);
  56. Dimensions l = new Cylinder(r, h);
  57. // Displayresults:
  58. Console.WriteLine("Area of Circle = {0:F2}", c.Area());
  59. Console.WriteLine("Area of Sphere = {0:F2}", s.Area());
  60. Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());
  61. }
  62. }
 

 

效果如下:

Area ofCircle   = 28.27

Area ofSphere   = 113.10

Area ofCylinder = 150.80

 

虚方法和抽象方法的区别如下:

动态多态程序案例如下:

 


    
  1. using System;
  2. public class DrawingObject
  3. {
  4. public virtual void Draw()
  5. {
  6. Console.WriteLine("画形状的基类");
  7. }
  8. }
  9. public class Line :DrawingObject
  10. {
  11. public override void Draw()
  12. {
  13. Console.WriteLine("画一条线");
  14. }
  15. }
  16. public class Circle : DrawingObject
  17. {
  18. public override void Draw()
  19. {
  20. Console.WriteLine("画一个圆");
  21. }
  22. }
  23. public class Square : DrawingObject
  24. {
  25. public override void Draw()
  26. {
  27. Console.WriteLine("画一个正方形");
  28. }
  29. }
  30. public classDrawDemo
  31. {
  32. public static int Main(string[] args)
  33. {
  34. DrawingObject[] dObj = new DrawingObject[4];
  35. dObj[0] = new Line();
  36. dObj[1] = new Circle();
  37. dObj[2] = new Square();
  38. dObj[3] = new DrawingObject();
  39. foreach (DrawingObject drawObj in dObj)
  40. {
  41. drawObj.Draw();
  42. }
  43. return 0;
  44. }
  45. }
 

 

输出结果是:

画一条线
画一个圆
画一个正方形
画形状的基类

/*代码分析:

在DrawDemo类中的Main()方法中,创建了一个数组,数组元素是DrawingObject 类的对象。该数组名为dObj,是由四个DrawingObject类型的对象组成。

接下来, 初始化dObj数组, 由于Line, Circle和Square类都是DrawingObject类的派生类,所以这些类可以作为dObj数组元素的类型。 如果C#没有这种功能,你得为每个类创建一个数组。继承的性质可以让派生对象当作基类成员一样用,这样就节省了编程工作量。

一旦数组初始化之后,接着是执行foreach循环,寻找数组中的每个元素。在每次循环中, dObj 数组的每个元素(对象)调用其Draw()方法。多态性体现在:在运行时,各自调用每个对象的Draw()方法。尽管dObj 数组中的引用对象类型是DrawingObject,这并不影响派生类重载DrawingObject 类的虚方法Draw()。 在dObj 数组中,通过指向DrawingObject 基类的指针来调用派生类中的重载的Draw()方法。

*/

 

 

实践问题:

1.    关于实现多态下面哪个选项是不正确的?()

A.你可以通过实现接口来实现多态     C.你可以通过继承实现多态

C.你可以通过封装实现多态                D.你可以通过使用抽象类实现多态

2.下面哪个是函数重载的例子?()

A.  void example();                    B.  voidexample1();

char example();                        void example2();

C.    void example1(int,int);            D.  voidexample1(int,int);

void example2(char,char);              void example1(char,char);

3.下列哪个不属于函数签名:()

  A.参数类型     B.参数顺序        C.参数数量       D.参数名称

 

4.考虑下面的语句:

A.在动态多态中,程序的适当方法可以被调用,依赖于上下文。

B.在前期绑定中,函数在运行时被绑定。

 

5关于这些语句下面哪个选项是正确的?()

A.语句A为真,语句B为假      B. 语句A为假,语句B为真

C.两个语句A和B都是真        D. 两个语句A和B都是假

 

 

 

小结:

在本章中,我们主要学习了:

u      多态是什么

u      多态的分类和使用

u      多态的好处

 

 

英语词汇:

英文            全文                                        中文

Hour                                                       小时

Maximum                                                          最大值

Minimum                                                 最小值

Argument                                                参数

Location                                           定位

Chapter                                            章、节

Application                                              应用

Activity                                             活动

Debug                                                     调试

Compare                                                 比较

Distance                                           区别、不同

Operator                                                 操作

Struct                                                      结构

Binary                                                     二进制

 

 

练习项目:

       现在公司让要开发一款程序,用来一键式打开常见的计算机资料,例如文档、图片和影音文件等,只需安装一个程序就可以免了其他文件的管理,并且使用方便。简单分析如下了改万能加载器的功能点,考虑如下几点:

n   自动加载各种资料,一站式搜索系统常见资料;

n   能够打开常见文档类资料,例如txt文件、word文件、pdf文件、Visio文件

n   能够打开常见图片资料,例如jpg格式文件、gif文件、png文件

n   能够打开常见音频资料和视频资料,例如avi文件、mp3文件

支持简单可用的类型扩展接口,易于实现更多文件类型的加载

 

 

 

 

 


 

文章来源: aaaedu.blog.csdn.net,作者:tea_year,版权归原作者所有,如需转载,请联系作者。

原文链接:aaaedu.blog.csdn.net/article/details/51264405

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。