虚方法 当类中的方法声明前加上了 Virtual 修饰符, 我们称为虚方法, 反之为非虚, 使用了 virtual 修饰符后, 不允许再有 static, abstract 或 override 修饰符. 也可以把属性声明为 virtual , 对于虚属性,语法于非虚属性是相同的, 但要在定义中加上关键字 virtual , 其语法如下所示: string name; public virtual string Name { get{ return name; } set{ name = value; } } 虚方法的概念于标准的OOP 概念相同 : 可以在派生类中重写虚方法, 在调用方法时, 会调用对象类型的合适方法. 在C#中,函数在默认情况下不是虚拟的, 但 (除了构造函数以外) 可以显式的声明为 virtual. 在派生类的函数重写另一函数时,要使用 override 关键字显式声明: class MyDerivedClass : MyBaseClass { public override void VirtualMethod() { cw("This method is an override defined in MyDerivedClass"); } } 对基类虚方法的重载是函数重载的一种特殊形式, 在派生类中重新定义虚方法时: 要求的是 方法名称, 返回值类型 ,参数表中的参数个数, 类型, 顺序都必须于基类中的虚方法完全一致. using System; class Vehicle //定义汽车类 { public int wheels; //公共成员, 轮子数 protected int weight; // 保护成员: 重量 public Vehicle(){} public Vehicle(int wheels,int weight) { this.wheels=wheels; this.weight=weight; } public virtual void Speak() { Console.WriteLine("the vehicle speaking!"); } } class Car : Vehicle { int passengers; // 私有成员: 乘客数 public Car(int wheels,int weight,int passengers):base(wheels,weight) { this.wheels=wheels; this.weight=weight; this.passengers=passengers; } public override void Speak() { Console.WriteLine("the car Di-Di"); } } class Truck : Vehicle { int load; //私有成员: 载重量 public Truck(int wheels,int weight,int load):base(wheels,weight) { this.wheels=wheels; this.weight=weight; this.load=load; } public override void Speak() { Console.WriteLine("the truck Ba-Ba"); } } class Program { static void Main() { Vehicle[] vs={ new Car(4,2,5), new Truck(10,5,50), new Truck(10,5,60), new Car(3,2,4), new Vehicle() }; foreach(var v in vs) { v.Speak(); } } } Vehicle 类中的 Speak() 方法被声明为 虚方法, 那么在派生类中就可以重新定义此方法. 在派生类 Car 和 Truck 中分别重载了 Speak() 方法, 派生类中的方法原型和基类中的方法原型必须完全一致. 在 Program 类中, 创建了 Vehicle 类型的数组 vs ,里面包含 两个Car 和 两个Truck 以及一个Vehicle 的实例,然后遍历了 vs 对其中 的每个实例都调用了 Speak() 方法. 运行程序,结果是: the car Di-Di the truck Ba-Ba the truck Ba-Ba the car Di-Di the vehicle speaking! 这里 foreach 中的 v 先后指向了 不同的实例, 都调用了 Speak() 方法, v.Speak() 究竟执行哪个版本, 是在程序的动态运行时, 根据 v 某一刻指代的对象来确定的, 所以实现了动态的多态性 |