当前位置:  编程技术>.net/c#/asp.net

c#中虚函数的相关使用方法

    来源: 互联网  发布时间:2014-10-16

    本文导语:  若一个实例方法声明前带有virtual关键字,那么这个方法就是虚方法。 虚方法与非虚方法的最大不同是,虚方法的实现可以由派生类所取代,这种取代是通过方法的重写实现的(以后再讲)虚方法的特点:虚方法前不允许有static,...

若一个实例方法声明前带有virtual关键字,那么这个方法就是虚方法。

虚方法与非虚方法的最大不同是,虚方法的实现可以由派生类所取代,这种取代是通过方法的重写实现的(以后再讲)
虚方法的特点:
虚方法前不允许有static,abstract,或override修饰符
虚方法不能是私有的,因此不能使用private修饰符
虚方法的执行:
我们知道一般函数在编译时就静态地编译到了执行文件中,其相对地址在程序运行期间是不发生变化的,
而虚函数在编译期间是不被静态编译的,它的相对地址是不确定的,它会根据运行时期对象实例来动态判断要调用的函数,
其中那个申明时定义的类叫申明类,那个执行时实例化的类叫实例类。
如:A a =new B(); 其中A是申明类,B是实例类。
1.当调用一个对象的函数时,系统会直接去检查这个对象申明定义的类,即申明类,看所调用的函数是否为虚函数;
2.如果不是虚函数,那么它就直接执行该函数。而如果是一个虚函数,那么这个时候它就不会立刻执行该函数了,而是开始检查对象的实例类。
3.在这个实例类里,他会检查这个实例类的定义中是否有实现该虚函数或者重新实现该虚函数(通过override关键字)的方法,
如果有,它就不会再找了,而是马上执行该实例类中实现的虚函数的方法。而如果没有的话,系统就会不停地往上找实例类的父类,
并对父类重复刚才在实例类里的检查,直到找到第一个重载了该虚函数的父类为止,然后执行该父类里重载后的函数。
例1:

代码如下:

class A
    {
        publicvirtualvoid Sum()
        {
            Console.WriteLine("I am A Class,I am virtual sum().");
        }
    }
    class Program
    {
        staticvoid Main(string[] args)
        {
             A a=new A();   // 定义一个a这个A类的对象.这个A就是a的申明类,实例化a对象,A是a的实例类  
             a.Sum();
             Console.Read();
        }
    }

 执行a.Sum:
1.先检查申明类A 2.检查到是sum是虚拟方法 3.转去检查实例类A,结果是题本身
4.执行实例类A中实现Sum的方法 5.输出结果 I am A Class,I am virtual sum().
例2:

代码如下:

class A
    {
        publicvirtualvoid Sum()
        {
            Console.WriteLine("I am A Class,I am virtual sum().");
        }
    }
    class B : A   
    {
        publicoverridevoid Sum() // 重新实现了虚函数  
        {
            Console.WriteLine("I am B Class,I am override sum().");
        } 

    }
    class Program
    {
        staticvoid Main(string[] args)
        {
             A a=new B();  // 定义一个a这个A类的对象.这个A就是a的申明类,实例化a对象,B是a的实例类             
             a.Sum();
             Console.Read();
        }
    }


执行a.Sum:
1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类B,有重写的方法 4.执行实例类B中的方法 5.输出结果 I am B Class,I am override sum().
例3:
代码如下:

class A
    {
        publicvirtualvoid Sum()
        {
            Console.WriteLine("I am A Class,I am virtual sum().");
        }
    }
    class B : A   
    {
        publicoverridevoid Sum() // 重新实现了虚函数  
        {
            Console.WriteLine("I am B Class,I am override sum().");
        } 

    }
    class C : B
    {

    }
    class Program
    {
        staticvoid Main(string[] args)
        {
             A a=new C();// 定义一个a这个A类的对象.这个A就是a的申明类,实例化a对象,C是a的实例类             
             a.Sum();
             Console.Read();
        }
    }


执行a.Sum:
1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类C,无重写的方法 4.转去检查类C的父类B,有重写的方法
5.执行父类B中的Sum方法 6.输出结果 I am B Class,I am override sum(). 
例4:

代码如下:

class A
    {
        publicvirtualvoid Sum()
        {
            Console.WriteLine("I am A Class,I am virtual sum().");
        }
    }
    class B : A   
    {
        publicnewvoid Sum() //覆盖父类里的同名函数,而不是重新实现 
        {
            Console.WriteLine("I am B Class,I am new sum().");
        } 

    }
    class Program
    {
        staticvoid Main(string[] args)
        {
             A a=new B();
             a.Sum();
             Console.Read();
        }
    }


执行a.Sum:
1.先检查申明类A 2.检查到是虚拟方法 3.转去检查实例类B,无重写的(这个地方要注意了,虽然B里有实现Sum(),但没有使用override关键字,所以不会被认为是重写) 4.转去检查类B的父类A,就为本身 5.执行父类A中的Sum方法 6.输出结果 I am A Class,I am virtual sum(). 
那么如果在例4里,申明的是类B呢?
代码如下:

class A
    {
        publicvirtualvoid Sum()
        {
            Console.WriteLine("I am A Class,I am virtual sum().");
        }
    }
    class B : A   
    {
        publicnewvoid Sum() //覆盖父类里的同名函数,而不是重新实现 
        {
            Console.WriteLine("I am B Class,I am new sum().");
        } 

    }
    class Program
    {
        staticvoid Main(string[] args)
        {
             B b=new B();
             b.Sum();
             Console.Read();
        }
    }


执行B类里的Sum(),输出结果I am B Class,I am new sum().
可以使用抽象函数重写基类中的虚函数吗?
答案是可以的。

代码如下:

class A
    {
        publicvirtualvoid PrintFriends()
        {
            Console.WriteLine("A.PrintFriends()");  
        } 
    }
    abstractclass B : A   
    {
        public abstract override void PrintFriends();   //使用override 修饰符,表示抽象重写了基类中该函数的实现
    }
    abstract class C : A
    {
        public abstract new void PrintFriends();        //使用 new 修饰符显式声明,表示隐藏了基类中该函数的实现
    }

密封类可以有虚函数吗?
可以,基类中的虚函数将隐式的转化为非虚函数,但密封类本身不能再增加新的虚函数

代码如下:

class A
    {
        publicvirtualvoid Fun()
        {
            Console.WriteLine("I am A.");
        }
    }
    sealedclass Program:A
    {
        public override void Fun()
        {
            Console.WriteLine("I am B.");
        }
        staticvoid Main(string[] args)
        {
            Program p =new Program();
            p.Fun();
            Console.Read();
        }
    }

    
 
 

您可能感兴趣的文章:

  • C#私有构造函数的简单例子
  • C#类的学习笔记之C#构造函数
  • 学习C#中的静态构造函数与复制构造函数
  • C# 静态构造函数使用总结
  • C#实现关闭显示器的函数一例
  • C#学习笔记之抽象类和抽象函数
  • C#生成MD5的函数代码
  • c#(asp.net)实现的文件下载函数
  • C#私有构造函数使用示例
  • C# 使用匿名函数解决EventHandler参数传递的难题
  • c#只读字段和常量的区别,以及静态构造函数的使用实例
  • C#中英文混合字符串截取函数
  • C#委托所蕴含的函数指针概念详细解析
  • C#中私有构造函数的特点和用途实例解析
  • c# 获取CookieContainer的所有cookies函数代码
  • c#和javascript函数相互调用示例分享
  • C#版的 Escape() 和 Unescape() 函数分享
  • C#四舍五入(函数)用法实例
  • C#只读字段和常量的区别 静态构造函数的例子
  • c#中oracle的to_date函数使用方法
  • 请问有没头函数<pthread.h>和<signal.h>里的函数的详细功能介绍?和使用方法???
  • gcc怎么查看某个函数包含在哪个头文件及其使用方法
  • Python的函数嵌套的使用方法
  • 问个比较菜的问题: LINUX如何查询C函数的使用方法?
  • python回调函数的使用方法
  • 如何将GTK中的CallBack函数封装成类似JAVA接口类的使用方法
  • MySQL中的LOCATE和POSITION函数使用方法
  • java用静态工厂代替构造函数使用方法和优缺点
  • C++函数中return语句的使用方法
  • jQuery filter函数使用方法
  • Python使用函数默认值实现函数静态变量的方法
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 哈希函数的构造方法及举例
  • 一个基本概念问题:静态函数只能调用静态方法,类的成员函数也是静态的吗?
  • Windows和Linux下C++类成员方法作为线程函数方法介绍
  • 调用另一个构造函数方法
  • mysql中字符串和时间互相转换的方法(自动转换及DATE_FORMAT函数)
  • java类中的方法就是函数了,函数参数全是传值了,传址参数怎样表示?
  • Linuc中C函数查找方法
  • Linux C 有没有 查看函数定义的方法?
  • 关于反三角函数的方法
  • 在UNIX中测试函数系统运行时间用什么方法?谢谢!
  • 有没有微妙级别的times函数或者实现方法
  • 那里有关于JSP的函数、方法、属性的介绍(中文版的)?
  • 高分求java.sql类库的类说明,函数及方法!
  • php向js函数传参的几种方法
  • 在静态上下文中不能引用非静态方法test(),天啊,为什么我的main()不能调用任何其它函数?
  • 请教各位大虾。在linux下可有类似Win API中的核心代码段的函数?或方法??????
  • 急!linux unix C上毫秒乃至微妙级别的回调函数的方法有么?
  • 自己实现strcpy函数的实现方法
  • SQL中函数 replace 的参数1的数据类型ntext无效的解决方法
  • 好像在函数(方法)里面不可以用 static来定义变量,是这样的吗?
  • C++实现CreatThread函数主线程与工作线程交互的方法
  • C++ Maps 成员 key_comp():返回比较元素key的函数
  • 请问:定义了2个函数,其中第一个函数要访问另外一个函数的变量,怎么处理阿?谢谢
  • C++ Maps 成员 value_comp():返回比较元素value的函数
  • 如果知道一个函数的地址或函数名,如何得到函数所在的文件名?
  • C++ MultiMaps 成员 key_comp():返回比较key的函数
  • java的数学函数在那个类中,如幂函数、指数、对数、双曲线函数等?
  • C++ MultiMaps 成员 value_comp():返回比较元素value的函数
  • 一个父类的构造函数的参数是(Applet applet),请问它的子类构造函数当中应怎样调用父类构造函数?
  • C++ STL Bitsets构造函数及成员函数解释及代码示例
  • 虚函数被类的构造析构函数和成员函数调用虚函数的执行过程


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3