多态性

多态性(polymorphism) 这个词意味着有多种形式。在面向对象的编程范式中,多态性往往表现为“一个接口,多个函数”。

多态性可以是静态的,也可以是动态的。在 静态多态(static polymorphism)性 中,一个函数的响应是在编译时确定。动态多态性( dynamic polymorphism) 中,其函数响应是在运行时决定。

静态多态性

在编译时将一个函数与一个对象连接起来的机制被称为早期绑定机制。它也被称为静态绑定。C # 提供了两种技术实现静态多态性。他们是:

  • 函数重载
  • 运算符重载

我们将在下一章讨论运算符重载。

函数重载

你可以在同一范围对同一函数名有多重定义。该函数的定义必须用不同的类型或通过参数列表中的参数的数量进行区分。不可以只用不同的返回类型区分不同的重载函数声明。

下面的示例显示使用函数 print() 打印不同的数据类型:

  1. using System;
  2. namespace PolymorphismApplication
  3. {
  4. class Printdata
  5. {
  6. void print(int i)
  7. {
  8. Console.WriteLine("Printing int: {0}", i );
  9. }
  10. void print(double f)
  11. {
  12. Console.WriteLine("Printing float: {0}" , f);
  13. }
  14. void print(string s)
  15. {
  16. Console.WriteLine("Printing string: {0}", s);
  17. }
  18. static void Main(string[] args)
  19. {
  20. Printdata p = new Printdata();
  21. // 调用 print 函数打印整型
  22. p.print(5);
  23. // 调用 print 函数打印浮点型
  24. p.print(500.263);
  25. // 调用 print 函数打印字符型
  26. p.print("Hello C++");
  27. Console.ReadKey();
  28. }
  29. }
  30. }

编译执行上述代码,得到如下结果:

  1. Printing int: 5
  2. Printing float: 500.263
  3. Printing string: Hello C++

动态多态性

C# 允许你创建一个抽象类,被用于提供部分类的接口实现。执行完成时,派生类继承它。抽象类(Abstract classes) 包含抽象方法,这是由派生类来实现的。派生类具有更具体化,专业化的功能。

以下是关于抽象类的规则:

  • 你不能创建抽象类的实例
  • 你不能在抽象类的外部声明抽象方法
  • 当一个类声明为 密封的(sealed) ,它不能被继承,抽象类被不能声明为密封的。

下面的程序演示了一个抽象类:

  1. using System;
  2. namespace PolymorphismApplication
  3. {
  4. abstract class Shape
  5. {
  6. public abstract int area();
  7. }
  8. class Rectangle: Shape
  9. {
  10. private int length;
  11. private int width;
  12. public Rectangle( int a=0, int b=0)
  13. {
  14. length = a;
  15. width = b;
  16. }
  17. public override int area ()
  18. {
  19. Console.WriteLine("Rectangle class area :");
  20. return (width * length);
  21. }
  22. }
  23. class RectangleTester
  24. {
  25. static void Main(string[] args)
  26. {
  27. Rectangle r = new Rectangle(10, 7);
  28. double a = r.area();
  29. Console.WriteLine("Area: {0}",a);
  30. Console.ReadKey();
  31. }
  32. }
  33. }

编译执行上述代码,得到如下结果:

  1. Rectangle class area :
  2. Area: 70

当你在一个类中有定义函数,并且希望它可以在一个被继承的类中实现功能时,你可以使用虚函数(virtual functions) 。虚函数可以在不同的被继承的类中实现,并且将在程序运行时调用此类函数。

动态多样性是通过抽象类虚函数实现的。

下列程序证实了上述说法:

  1. using System;
  2. namespace PolymorphismApplication
  3. {
  4. class Shape
  5. {
  6. protected int width, height;
  7. public Shape( int a=0, int b=0)
  8. {
  9. width = a;
  10. height = b;
  11. }
  12. public virtual int area()
  13. {
  14. Console.WriteLine("Parent class area :");
  15. return 0;
  16. }
  17. }
  18. class Rectangle: Shape
  19. {
  20. public Rectangle( int a=0, int b=0): base(a, b)
  21. {
  22. }
  23. public override int area ()
  24. {
  25. Console.WriteLine("Rectangle class area :");
  26. return (width * height);
  27. }
  28. }
  29. class Triangle: Shape
  30. {
  31. public Triangle(int a = 0, int b = 0): base(a, b)
  32. {
  33. }
  34. public override int area()
  35. {
  36. Console.WriteLine("Triangle class area :");
  37. return (width * height / 2);
  38. }
  39. }
  40. class Caller
  41. {
  42. public void CallArea(Shape sh)
  43. {
  44. int a;
  45. a = sh.area();
  46. Console.WriteLine("Area: {0}", a);
  47. }
  48. }
  49. class Tester
  50. {
  51. static void Main(string[] args)
  52. {
  53. Caller c = new Caller();
  54. Rectangle r = new Rectangle(10, 7);
  55. Triangle t = new Triangle(10, 5);
  56. c.CallArea(r);
  57. c.CallArea(t);
  58. Console.ReadKey();
  59. }
  60. }
  61. }

编译执行上述代码,得到如下结果:

  1. Rectangle class area:
  2. Area: 70
  3. Triangle class area:
  4. Area: 25