c# 关于多态性的问题
admin 发表于 2010-04-25 | 来源:互联网 | 阅读:
- C# code
-
using System; namespace 多态性_1 { public class Person { private string name = "张三"; private int age = 26; public Person(string Name, int Age) { name = Name; age = Age; } protected virtual void Display() { Console.WriteLine("姓名:{0},年龄:{1}", name, age); } static public void DisplayData(Person aPerson) { aPerson.Display(); } } public class Employee:Person { private string department; private decimal salary; public Employee(string Name, int Age, string D, decimal S):base(Name, Age) { department = D; salary = S; } protected override void Display() { base.Display(); Console.WriteLine("部门:{0},薪金:{1}", department , salary ); } } class Test { static void Main(string[] args) { Person OnePerson = new Person("李四", 40); Person.DisplayData(OnePerson); Employee OneEmployee = new Employee ("王五", 23, "客服部", 5000); Person .DisplayData(OneEmployee); Console.Read(); } } }
运行的结果是
姓名:李四,年龄:40
姓名:王五,年龄:23
部门:客服部,薪金:5000
为什么在Main()主函数中Person.DisplayData(OneEmployee);这句语句输出的是派生类重写后的输出的语句呢?
这里DisplayData是基类的静态方法!其中执行的语句是aPerson.Display();怎么这个Display却成了派生类重写后的内容了呢?
是不是只要派生类,做了实例化后,基类中的虚方法就被重写了,不然的话在上面的代码中,并没有用派生类的对象去调用重写的Display方法啊,怎么结果会成为这样呢?

姓名:王五,年龄:23部门:客服部,薪金:5000以上信息是Person .DisplayData(OneEmployee);所以打印出来的因为你用的父类对象来调的方法,而参数传的却是子类的又因为DisplayData方法是重写的,所以它会先调用自己的,随后再是子类重写后的方法
DisplayData方法是重写的,怎么会是重写的? 它不是个静态的方法吗?而且其中的aPerson.Display();也是基类的对象啊!
姓名:王五,年龄:23这行结果是明白是怎么输出的,剩下的那两行就不太明白了
Person.DisplayData(OnePerson); ==>姓名:李四,年龄:40Person .DisplayData(OneEmployee);==>姓名:王五,年龄:23 部门:客服部,薪金:5000设置断点,单步调试就明白啦
当我在Person .DisplayData (OneEmployee);这句设置断点时执行到aPerson.Display();这句时,下一句就跳到了protected override void Display() { base.Display(); Console.WriteLine("部门:{0},薪金:{1}", department , salary );}这一部分呢?为什么不去执行基类中的protected virtual void Display(){ Console.WriteLine("姓名:{0},年龄:{1}", name, age); }
学习 接分
Person .DisplayData(OneEmployee);这句以OneEmployee为参数执行static public void DisplayData(Person aPerson) { aPerson.Display(); } 这句就到执行protected override void Display() { base.Display(); Console.WriteLine("部门:{0},薪金:{1}", department , salary ); }到了这里,注意是base.Display();是执行基类的 Display方法,也就是protected virtual void Display(){ Console.WriteLine("姓名:{0},年龄:{1}", name, age); } 这里是关键了,这句的参数name, age,因为是以OneEmployee为参数,OneEmployee里有这句public Employee(string Name, int Age, string D, decimal S):base(Name, Age) { department = D; salary = S; } 注意这个:base(Name, Age) //派生类和基类通信,以base实现,基类首先被调用,所以其实基类的public Person(string Name, int Age) { name = Name; age = Age; }因为参数是:王五,23。所以base.Display();执行基类的protected virtual void Display() { Console.WriteLine("姓名:{0},年龄:{1}", name, age); }结果就是:姓名:王五,年龄:23 了然后才是子类的Console.WriteLine("部门:{0},薪金:{1}", department , salary );
最近在看理论书,看到《你必须知道的.net》里这么说的,结合示例才搞明白这些,自己以前没系统学习理论都是从代码学的。
多态-〉 调用方法时会根据实际的对象类型调用相应的方法。Person .DisplayData (OneEmployee);这个方法的参数类型是Person,所以可以接受的参数是Person和它的子类。当在方法中执行person.Display()时,会根据person的实际类型去调用。因为是Employee类型,且Display方法是override,所以调用的是Employee的display方法
如果你把Person中的Display前的virtual去掉,然后在Employee的Display前的override换成new。这样再执行的话,调用时应该是执行的是Person的Display方法了//因为使用new的话是隐藏了基类的方法
多态-〉 调用方法时会根据实际的对象类型调用相应的方法。Person .DisplayData (OneEmployee);这个方法的参数类型是Person,所以可以接受的参数是Person和它的子类。当在方法中执行person.Display()时,会根据person的实际类型去调用。因为是Employee类型,且Display方法是override,所以调用的是Employee的d……是调用的子类中重写过的Display方法,但是子类的Display方法中有个base.Display();还是要调用基类的,但是这个基类的参数name, age是用的子类实例OneEmployee的参数:王五,23
你的子类已经继承了DisplayData这个方法 Person .DisplayData(OneEmployee);在这你传入了一个子类对象, static public void DisplayData(Person aPerson) { aPerson.Display(); } 这个地方用父类的当我在Person .DisplayData (OneEmployee);这句设置断点时执行到aPerson.Display();这句时,下一句就跳到了protected override void Display() { base.Display(); Console.WriteLine("部门:{0},薪金:{1}", department , salary );}……就是不去执行才对。
路过,学习了`~~顶顶
应为只要是重写了以后再次调用Display方法时,就会把子类的构造函数的内容覆盖父类输出