C#多态的总结
2018-01-02 23:15
288 查看
什么是多态
专业述语:不同的对象对同一消息作出不同的响应就是多态。
生活例子:老板对员工说“员工们开始工作”,程序员听到后写代码,销售人员听到后出去跑业务,客服人员听到后给客户打电话做回访。
不可能让老板说“程序员你们快写代码,销售人员你们快去跑业务,客服人员你们快去电话回访”。如果公司发展壮大,又增加了一个员工类型“公关人员”,则老板又要加句“公关人员快去宣传”,将来不断增加员工类型的话,那老板岂不累晕啊,或者老板出差很久回来时并不知道增加新的员工类型或去掉了员工类型,那他说的话会出错啊。这样就导致了不灵活(因为每次都要修改所说的),增加了依赖(因为每次都要清楚知道有哪些员工类型)。
从这个生活的例子可以看出,有两种类型:老板、员工。员工又分为程序员、销售员、客服员等等子类型。还有一种行为:工作。
下面把生活中的例子用代码来实现。
一、基于共同基类的多态
当增加新的员工类型“公关人员”时,现有的员工种类和老板类都不需要修改,只需新增就行了。就这遵循了面向对象的“开闭原则”(对功能扩展是开放的,对修改则是封闭的)。老板只依赖于Empolyee这个类,极大降低了依赖。
当然这个例子也可不用抽象类加抽象方法,用正常类加virtual方法也行。
不过使用正常类不太适合,当实例化一个员工Employee对象时,我们并不清楚是哪种员工,概念太模糊,所以用抽象的才最合适。
二、基于共同接口的多态
接口的本质的是抽象类,所以和(一)中的一样。当然这个例子使用接口不合适,因为属性在各个子类都要实现一下。
三、基于共同委托的多态
当然这里使用委托是不合适的,只是为了演示多态的另一种形式。委托的本质也是一个类,即action1,2,3都会被编译成类。个人认为也满足述语:不同的对象对同一消息作出不同的响应就是多态这句话。
专业述语:不同的对象对同一消息作出不同的响应就是多态。
生活例子:老板对员工说“员工们开始工作”,程序员听到后写代码,销售人员听到后出去跑业务,客服人员听到后给客户打电话做回访。
不可能让老板说“程序员你们快写代码,销售人员你们快去跑业务,客服人员你们快去电话回访”。如果公司发展壮大,又增加了一个员工类型“公关人员”,则老板又要加句“公关人员快去宣传”,将来不断增加员工类型的话,那老板岂不累晕啊,或者老板出差很久回来时并不知道增加新的员工类型或去掉了员工类型,那他说的话会出错啊。这样就导致了不灵活(因为每次都要修改所说的),增加了依赖(因为每次都要清楚知道有哪些员工类型)。
从这个生活的例子可以看出,有两种类型:老板、员工。员工又分为程序员、销售员、客服员等等子类型。还有一种行为:工作。
下面把生活中的例子用代码来实现。
一、基于共同基类的多态
// 员工类 public abstract class Employee { //姓名 public string Name { get; set; } //工作 public abstract void Work(); } //程序员类 public class Programmer : Employee { public override void Work() { Console.WriteLine(Name + "程序员开始写代码"); } } //销售员类 public class Seller : Employee { public override void Work() { Console.WriteLine(Name + "销售员开始出去跑业务"); } } //客服类 public class Srv : Employee { public override void Work() { Console.WriteLine(Name + "客服开始打电话回访"); } } // 老板类 public class Boss { //老板向员工们发话 public void SendCommand(List<Employee> employeeList) { foreach (var emp in employeeList)//员工们开始工作吧 emp.Work(); } } static void Main(string[] args) { Employee employee1 = new Programmer() { Name = "程大大" }; Employee employee2 = new Seller() { Name = "销美美" }; Employee employee3 = new Srv() { Name = "客小服" }; List<Employee> employeeList = new List<Employee>(); employeeList.Add(employee1); employeeList.Add(employee2); employeeList.Add(employee3); Boss boss = new Boss(); boss.SendCommand(employeeList); Console.ReadLine(); }
当增加新的员工类型“公关人员”时,现有的员工种类和老板类都不需要修改,只需新增就行了。就这遵循了面向对象的“开闭原则”(对功能扩展是开放的,对修改则是封闭的)。老板只依赖于Empolyee这个类,极大降低了依赖。
当然这个例子也可不用抽象类加抽象方法,用正常类加virtual方法也行。
不过使用正常类不太适合,当实例化一个员工Employee对象时,我们并不清楚是哪种员工,概念太模糊,所以用抽象的才最合适。
二、基于共同接口的多态
// 员工接口 public interface IEmployee { //姓名 string Name { get; set; }//属性的本质是方法,所以可在接口中定义 //工作 void Work(); } //程序员类 public class Programmer : IEmployee { public string Name { get; set; } public void Work() { Console.WriteLine(Name + "程序员开始写代码"); } } //销售员类 public class Seller : IEmployee { public string Name { get; set; } public void Work() { Console.WriteLine(Name + "销售员开始去出跑业务"); } } //客服类 public class Srv : IEmployee { public string Name { get; set; } public void Work() { Console.WriteLine(Name + "客服开始打电话回访"); } } // 老板类 public class Boss { //老板向员工们发话 public void SendCommand(List<IEmployee> employeeList) { foreach (var emp in employeeList)//员工们开始工作吧 emp.Work(); } } static void Main(string[] args) { IEmployee employee1 = new Programmer() { Name = "程大大" }; IEmployee employee2 = new Seller() { Name = "销美美" }; IEmployee employee3 = new Srv() { Name = "客小服" }; List<IEmployee> employeeList = new List<IEmployee>(); employeeList.Add(employee1); employeeList.Add(employee2); employeeList.Add(employee3); Boss boss = new Boss(); boss.SendCommand(employeeList); Console.ReadLine(); }
接口的本质的是抽象类,所以和(一)中的一样。当然这个例子使用接口不合适,因为属性在各个子类都要实现一下。
三、基于共同委托的多态
//程序员类 public class Programmer { public string Name { get; set; } public void WriteCode()//写代码 { Console.WriteLine(Name + "程序员开始写代码"); } } //销售员类 public class Seller { public string Name { get; set; } public void TakeBusiness()//跑业务 { Console.WriteLine(Name + "销售员开始去出跑业务"); } } //客服类 public class Srv { public string Name { get; set; } public void CallPhone()//打电话 { Console.WriteLine(Name + "客服开始打电话回访"); } } // 老板类 public class Boss { //老板说开始工作 public void SendCommand(List<Action> actionList) { foreach(var action in actionList) action?.Invoke(); } } static void Main(string[] args) { var employee1 = new Programmer() { Name = "程大大" }; var employee2 = new Seller() { Name = "销美美" }; var employee3 = new Srv() { Name = "客小服" }; Action action1 = employee1.WriteCode; Action action2 = employee2.TakeBusiness; Action action3 = employee3.CallPhone; List<Action> actionList = new List<Action>(); actionList.Add(action1); actionList.Add(action2); actionList.Add(action3); Boss boss = new Boss(); boss.SendCommand(actionList); Console.ReadLine(); }
当然这里使用委托是不合适的,只是为了演示多态的另一种形式。委托的本质也是一个类,即action1,2,3都会被编译成类。个人认为也满足述语:不同的对象对同一消息作出不同的响应就是多态这句话。
相关文章推荐
- C# 适应虚函数,抽象类,接口分别实现多态的方法总结。
- C#基础总结之八面向对象知识点总结-继承与多态-接口
- C#经典语法总结(三)多态
- 总结:C#语法——继承、虚拟、多态、实例化
- 三周C#总结7oop--多态
- c# 多态总结
- C#中的继承封装和多态知识点总结
- C# 学习总结 之 类 、接口、多态、重载
- 新手菜鸟学习C#的笔记总结 之多态
- C# 学习总结 之 类 、接口、多态、重载
- C#总结(三)—三大特性(封装、继承、多态)
- C#之入门总结_多态_07
- C# 类的多态、结构、接口、抽象、虚函数总结
- C# 模板编程相关学习总结
- 【C#】委托总结
- 总结 使用c# 开发邮件系统心得
- [原创]C#操作Excel(创建、打开、读写、保存)几种方法的总结(一)
- 【《Effective C#》提炼总结】提高Unity中C#代码质量的22条准则
- C# 线程资源同步方式总结
- 实习总结:c#开发之旅(二)善用ref和out,让函数使用起来更方便。