虚函数无敌解释

助于理解。。。

虚拟函数(virtual)
  使用面向对象的开发过程就是在不断的抽象事物的过程,我们的目标就是抽象出一个紧内聚,低偶合,易于维护和扩展的模型.但是在抽象过程中我们会发现很多事物的特征不清楚,或者很容易发生变动,怎么办呢?比如飞禽都有飞这个动作,但是对于不同的鸟类它的飞的动作动方式是不同的,有的要滑行,有的要颤抖翅膀, 虽然都是飞但千差万别,在我们抽象的模型中不可能一个个都考虑到,怎么为以后留下好的扩展,怎么来处理子类的前差万别?比如我现在又要抽象一个类"鹤", 它也有飞禽的特征,我可以简单的继承"飞禽",而不去修改现有的代码,可以很容易的扩展系统
  面向对象的概念中引入了虚拟函数. 就是在父类中把子类中共同的,易于变化或者不清楚的特征抽取出来,作为子类需要去重新实现的操作(override),我们可以称做"热点".还是上面的例子
  class 飞禽
  { 
    private void Shape ;    //注意private访问修订符,Shape是不会被子类继承的!
    public string Wing ;    //翅膀
    public string Feather ; //羽毛  
    public virtual boolean Fly() {} ;  //飞翔. 定义的虚拟函数, 这是一个热点
  }
 
  class 麻雀 : 飞禽    //麻雀从飞禽继承而来
  {
    public boolean CanSpeaking; //申明了麻雀自己的特征.
    public override boolean Fly() {...} ;    //重载飞翔动作,实现自己的飞翔
  }

  class  鹤 : 飞禽  //鹤从飞禽继承而来
  {
   
    public override void Fly() {...} ;    //重载实现鹤的飞翔
  }
 
  //如何来使用虚拟函数,这里同时也是一个多态的例子.
  //打鸟
  void ShootBird(Bird : 飞禽)  //注意这里申明传入一个"飞禽"类,而不是具体的"鸟类". 好处是以后不管出现多少种鸟类,只要是从飞禽继承下来的,都照打不误:)
  {
    if( Bird.fly())
    {
      ....
      开始打鸟...
      ...
    }
  }
 
  static void main()
  {
     //打麻雀
     ShootBird( new 麻雀());
     //打鹤
     ShootBird( new 鹤());    
     //看到没!都是打鸟的过程,我这里可以实现打任何一种鸟了,添加一行代码而不去修改代码
     ShootBird( new 其它的飞禽());         
     ShootBird( ...);         
  }  
-------------------------------------------- 
虚拟函数的的执行过程:   
   虚拟函数从C#的程序编译的角度来看,它和其它一般的函数有什么区别呢?一般函数在编译期间就静态的编译到了执行文件中,在程序运行期间是不发生变化的,也就是写死了!而虚拟函数在编译期间是不被静态编译的,它是不确定的,它会根据运行时期对象实例来动态判断要调用的函数,其中那个申明时定义的类叫申明类,那个执行时实例化的类叫实例类.具体的检查的流程如下:
 a.当调用一个对象的函数时,系统会去检查这个对象申明定义的类,即申明类
 b.然后它更据这个申明类型的定义去检查这个函数是否虚拟函数
 c.如果有virtual关键字,他就认为是虚拟函数,这个时候他又去检查实例类.
 d.好!找到这个实例类后,他再检查这个实例类定义中是否重新实现了虚拟函数(通过override),如果是!好了他就不再找了,马上执行它.
 e.如果没有,系统又往上层父类找实例类的父类,直到找到一个最近重载了该虚拟函数的父类为止,然后执行该函数.
 呵呵,知道这点有什么用呢?搞清楚这个老师的bt题目就可以拿下了.
 还是来个简单例子说明问题
 class A
 {
   protected virtual FuncA() {Console.WriteLine("FuncA")} ;//注意virtual,表明这是一个虚拟函数
 }
 
 class B :A             //注意 B是从A类继承,所以A是父类,B是子类
 {
   protected override FuncA(){Console.WriteLine("FuncB")} ; //注意override ,表明重新实现了虚拟函数
 }
 
 static void main()
 {
   A a ;               //定义一个a这个A类对象.这个A就是a的申明类
   A b ;               //定义一个b这个A类的对象.这个A就是b的申明类 
   a = new A() ;      //实例化a对象,A是这次实例类
   a.FuncA() ;        //开始执行FuncA. 1.先照申明类A 2.检查是虚拟方法 3.检查实例类A 4.执行实例类中的方法 5输出结果 FuncA
   b = new B();     //实例化b对象,B是这次实例类
   b.FuncA() ;     //开始执行FuncA. 1.先照申明类A 2.检查是虚拟方法 3.检查实例类B  4.执行实例类中的方法 5输出结果 FuncB
 }  


from:http://forum.mvpcn.net/ShowPost.asp?action=Previous&id=113

阅读更多
上一篇cout 输出格式控制 还是要注意点
下一篇c++构造函数详解(转)
想对作者说点什么? 我来说一句

无敌英语语法高中版PDF格式

2009年10月24日 2.48MB 下载

网吧破解无敌IV5.1

2010年02月21日 8KB 下载

无敌搜索引擎

2004年08月23日 146KB 下载

没有更多推荐了,返回首页

关闭
关闭