A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李伟斌 中级黑马   /  2012-12-3 21:31  /  1297 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

虚方法
当类中的方法声明前加上了 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 某一刻指代的对象来确定的, 所以实现了动态的多态性

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

1 个回复

倒序浏览
值得学习ing!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马