首页 > 编程 > C# > 正文

C#类的多态性详解

2019-10-29 21:37:42
字体:
来源:转载
供稿:网友

这篇文章主要介绍了C#类的多态性,主要有两种:一是编译时的多态性,二是运行时的多态性,需要的朋友可以参考下

第一种:编译时的多态性,

直接这样说不知道说啥?程序执行过程主要分为三步:编译,链接,运行。在编译时体现的多态性是通过方法的重载来实现的。方法的重载我们听过,就是一个类对象调用若干同名,但参数类型、个数不同。类对象是根据参数类型,个数来决定调用哪个同名方法,实现何种操作。C#语言的方法重载与C++、java基本是一样的,但是C#还包含C++的运算符重载,java里面没有这个概念。

第二种:运行时的多态性,

是在系统运行时,调用一个名字相同,参数类型也相同以及个数也完全一样的方法,但会完成不同的操作。C#运行时的多态性通过虚方法实现。在类方法声明加上了virtual修饰符,称为虚方法,反之为非虚方法。就这一点C#跟C++有很多相似之处。

代码清单:虚方法与非虚方法的区别

 

 
  1. namespace e_11  
  2. {  
  3. class A  
  4. {  
  5. public void F() //非虚方法  
  6. { Console.WriteLine("A.F"); }  
  7. public virtual void G() //虚方法  
  8. { Console.WriteLine("A.G"); }  
  9.  
  10. }  
  11. class B : A //A类为B类的基类  
  12. {  
  13. new public void F() //隐藏基类的同名非虚方法F(),注意使用new  
  14. { Console.WriteLine("B.F"); }  
  15. public override void G() //隐藏基类的同名虚方法G(),注意使用override  
  16. { Console.WriteLine("B.G"); }  
  17. }  
  18. class Test  
  19. {  
  20. static void F2(A aA) //注意,参数为A类引用变量  
  21. { aA.G(); }  
  22. static void Main(string[] args)  
  23. {  
  24. B b = new B();  
  25. A a1 = new A();  
  26. A a2 = b; //允许基类引用变量引用派生类对象,a2引用A类的派生类B的对象b  
  27. a1.F(); //调用基类A的非虚方法F(),显示A.F  
  28. a2.F(); //F()为非虚方法,调用基类A的F(),显示A.F  
  29. b.F(); //F()为非虚方法,调用派生类的F(),显示B.F  
  30. a1.G(); //G()为虚方法,因a1引用基类A对象,调用基类A的G(),显示A.G  
  31. a2.G(); //G()为虚方法,因a2引用派生类B对象,调用派生类B的G(),显示B.G  
  32. F2(a2); //由于a2引用A类派生类B的对象b,调用派生类B的的G(),显示B.G  
  33. F2(a1); //实参为基类A对象,调用A类的函数G(),显示A.G  
  34. }  
  35. }  
  36. }  

输出结果:

C#类的多态性详解

看上面的代码,我产生了一个疑问?为什么因为G()为虚方法,a2引用派生类B对象,调用的是B类的G()?

这里有一个解释:如果将基类引用变量引用不同对象,或者是基类对象,或者是派生类对象,用这个基类引用变量分别调用同名虚方法,根据对象的不同,会完成不同的操作。而非虚方法不具备次此功能。

关于类的多态性典型的例子:

 

 
  1. //类的多态性  
  2. namespace e_11  
  3. {  
  4. public class Person  
  5. {  
  6. private String name = "张三"//类的成员说明  
  7. private int age = 12;  
  8. protected virtual void Display() //类的虚方法  
  9. { Console.WriteLine("姓名:{0},年龄:{1}", name, age); }  
  10. public Person(string Name, int Age) //构造函数,函数名和类名同名,无返回值  
  11. { name = Name; age = Age; }  
  12. static public void DisplayData(Person aPerson) //静态方法  
  13. { aPerson.Display(); } //不是静态方法调用实例方法,如写为Display()错误  
  14. }  
  15.  
  16. public class Employe : Person //基类是Person  
  17. {  
  18. private string department;  
  19. private decimal salary;  
  20. public Employe(string Name, int Age, string D, decimal S)  
  21. : base(Name, Age)  
  22. { department = D; salary = S; }  
  23. protected override void Display() //重载虚方法,注意用Override  
  24. {  
  25. base.Display();  
  26. Console.WriteLine("部门:{0}, 薪金:{1}", department, salary);  
  27. }  
  28. }  
  29.  
  30. class Class1  
  31. {  
  32. static void Main(string[] args)  
  33. {  
  34. Person OnePerson = new Person("李四", 30);  
  35. Person.DisplayData(OnePerson); //显示基类的数据  
  36. Employe OneEmployee = new Employe("王五", 40, "财务", 2000);  
  37. Person.DisplayData(OneEmployee); //显示派生类数据  
  38. }//两次调用完全相同的方法,实参不同,实现的功能不同  
  39. }  
  40.  
  41. }  

运行效果:

C#类的多态性详解

以上就是本文的全部内容,希望能够帮到大家。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表