继承(五):virtual和override实现继承的多态性
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace InheritanceApp { class Employee { public string name; public Employee(string name) { this.name = name; } public void CalculatePay() { Console.WriteLine("Employee.CalculatePay called for {0}",name); } } class ContractEmployee : Employee { public ContractEmployee(string name) : base(name) { } public new void CalculatePay() { Console.WriteLine("ContractEmployee.CalculatePay called for {0}", name); } } class SalariedEmployee : Employee { public SalariedEmployee(string name) : base(name) { } new public void CalculatePay() { Console.WriteLine("SalariedEmployee.CalculatePay called for {0} ",name); } } class Program { protected Employee[] employees; public void LoadEmployees() { employees = new Employee[2]; employees[0] = new ContractEmployee("Adam Barr"); employees[1] = new SalariedEmployee("Max Benson"); } public void DoPayroll() { for (int i = 0; i < employees.GetLength(0); i++) { employees[i].CalculatePay(); } } static void Main(string[] args) { Program p = new Program(); p.LoadEmployees(); p.DoPayroll(); Console.ReadKey(); } } }
本例调用的都是基类的实现,这就是早绑定
下面将使用virtual和ovrride实现继承的多态性
using System; using System.Collections.Generic; using System.Linq; using System.Text; //多态性:使你能够在类层次结构中多次定义一个方法,这个运行时环境可以调用合适于特定对象的方法版本。 //解决办法:晚绑定,以为着编译器到运行时才选择要执行的方法,为了迫使编译器调用向上类型转换得到的对象的方法的正确版本 //必须使用两个关键字:virtual和override关键字。必须在基类方法中使用virtual关键字,在方法的派生类实现中使用override关键字 namespace InheritanceApp { class Employee { public string name; public Employee(string name) { this.name = name; } //private修饰虚方法:出现错误,“虚拟成员或抽象成员不能是私有的” // protected修饰虚方法:出现错误 //错误1 “ContractEmployee.CalculatePay()”: 当重写“protected”继承成员“Employee.CalculatePay()”时,无法更改访问修饰符 //错误2“SalariedEmployee.CalculatePay()”: 当重写“protected”继承成员“Employee.CalculatePay()”时,无法更改访问修饰符 //这里只能用用public(虚拟成员不能声明为private,因为不可能被重定义,可以将虚拟成员声明为protected,但如果不能在层次结构之外访问虚拟函数,那意义大打折扣) public virtual void CalculatePay() { Console.WriteLine("Employee.CalculatePay called for {0}",name); } } class ContractEmployee : Employee { public ContractEmployee(string name) : base(name) { } public override void CalculatePay() { Console.WriteLine("ContractEmployee.CalculatePay called for {0}", name); } } class SalariedEmployee : Employee { public SalariedEmployee(string name) : base(name) { } public override void CalculatePay() { Console.WriteLine("SalariedEmployee.CalculatePay called for {0} ",name); } } class Program { protected Employee[] employees; public void LoadEmployees() { employees = new Employee[2]; employees[0] = new ContractEmployee("Adam Barr"); employees[1] = new SalariedEmployee("Max Benson"); } public void DoPayroll() { for (int i = 0; i < employees.GetLength(0); i++) { employees[i].CalculatePay(); } } static void Main(string[] args) { Program p = new Program(); p.LoadEmployees(); p.DoPayroll(); Console.ReadKey(); } } }
![](https://images.cnblogs.com/cnblogs_com/Joetao/285933/r_17.jpg)