C#中的多态
需求如下:
1、已知一个SE类、PM类继承了Employee类;SE和PM类有一些属性,并且都有一个方法SayiHi(),我们把SE和PM共同的属性抽到Employee父类
2、使用集合存储Employee;
3、SE类中的SayiHi()方法要输出工程师的信息,PM中的SayiHi()方法要输出项目经理的信息,有相同的信息,也有各自不同的信息;
父类:Employee 员工类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Lesson6.Example { /// <summary> /// 员工类 /// </summary> public class Employee { /// <summary> /// 工号 /// </summary> public string ID { get; set; } /// <summary> /// 年龄 /// </summary> public int Age { get; set; } /// <summary> /// 名称 /// </summary> public string Name { get; set; } /// <summary> /// 性别 /// </summary> public Gender Gender { get; set; } } }
子类:SE类 工程师类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Lesson6.Example { public class SE : Employee { public SE() { } public SE(string id, string name, int age, Gender gender, int Popularity) { this.Name = name; this.Age = age; this.Gender = gender; this.Popularity = Popularity; } /// <summary> /// 人气 /// </summary> public int Popularity { get; set; } public string SayHi() { string message = string.Format("大家好,我是{0},今年{1}岁,工号是{2},我的人气值高达{3}!",this.Name,this.Age,this.ID,this.Popularity); return message; } } }
子类:PM 项目经理类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Lesson6.Example { /// <summary> /// PM类 /// </summary> public class PM : Employee { public PM() { } public PM(string id, string name, int age, Gender gender, int yearOfExperience) { this.Name = name; this.Age = age; this.Gender = gender; this.YearOfExperience = yearOfExperience; } /// <summary> /// 资历 /// </summary> public int YearOfExperience { get; set; } /// <summary> /// 问好,返回值:问好的内容 /// </summary> /// <returns></returns> public string SayHi() { string message; message = string.Format("大家好,我是{0},今年{1}岁,项目管理经验{2}年。", this.Name, this.Age, this.YearOfExperience); return message; } } }
测试类:Program类
using Lesson6.Example; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Lesson6 { class Program { static void Main(string[] args) { // 实例化SE对象 SE ai = new SE("112", "张三", 25, Gender.男, 100); // 实例化SE对象 SE joe = new SE("113", "joe", 26, Gender.男, 100); // 实例化PM对象 PM pm = new PM("113", "pm", 30, Gender.女, 100); // 泛型类型是父类,要使用的是子类的方法,要用is来判断具体的子类类型 List<Employee> empls = new List<Employee>(); empls.Add(ai); empls.Add(joe); empls.Add(pm); foreach (Employee empl in empls) { // 继承才能用is if (empl is SE) { Console.WriteLine(((SE)empl).SayHi()); } if (empl is PM) { Console.WriteLine(((PM)empl).SayHi()); } } } } }
分析,我们如果存储的是Employee这个集合的话,我们需要使用is 来判断具体是哪个子类,然后再强制转换成该子类,才能调用该子类的方法。
以上是可以解决问题的。
但我们可以使用多态来更灵活,自动的处理。
首先,在父类Employee中建一个virtual虚方法。
public virtual string SayHi() { string message = string.Format("大家好!"); return message; }
然后修改SE和PM类中的SayHi()方法前面加上override 关键字,表示重写父类的方法。
/// <summary> /// 问好,返回值:问好的内容 /// </summary> /// <returns></returns> public override string SayHi() { string message; message = string.Format("大家好,我是{0},今年{1}岁,项目管理经验{2}年。", this.Name, this.Age, this.YearOfExperience); return message; }
最后,我们在集合遍历时,可以不使用is来判断,因为面向对象的多态特性帮我们自动地判断了。
using Lesson6.Example; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Lesson5 { class Program { static void Main(string[] args) { // 实例化SE对象 SE ai = new SE("112", "张三", 25, Gender.男, 100); SE joe = new SE("113", "joe", 26, Gender.男, 100); PM pm = new PM("113", "pm", 30, Gender.女, 100); List<Employee> empls = new List<Employee>(); empls.Add(ai); empls.Add(joe); empls.Add(pm); // 遍历Employee集合 foreach (Employee empl in empls) { // 无需判断是哪个子类,面向对象的多态特性自动帮助我们判断 Console.WriteLine(empl.SayHi()); } Employee ema = new SE("113", "ema", 30, Gender.女, 100); Console.WriteLine(ema.SayHi()); } } }
根据以上实现代码,我们会发现多态其实主要是用来解决继承带来的问题的,可以帮助我们更好地解决不同的子类,产生执行不同的结果。