继承(五):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();     

        }
    }

   
}
posted @ 2011-03-09 21:29  焦涛  阅读(856)  评论(0编辑  收藏  举报