C#虚函数virtual详解
来源:互联网 发布:南宁广电网络上网 编辑:程序博客网 时间:2024/05/17 23:59
重写后的virtual函数依旧是virtual函数。由于virtual只对类中的实例函数成员有意义,所以成员字段和静态函数都不能声明为virtual,也不能与override和abstract一起用。C#中可以设置virtual属性、索引器或事件,例如
- virtual string Name
- {
- get;
- set;
- }
virtual string Name { get; set; }
无virtual和override关键字“重写”
如果签名后的函数在基类中都进行了声明,却没有用virtual和override关键字,例如:
- class Base1
- {
- public void printMethod()
- {
- Console.WriteLine("base1");
- }
- }
- class Derived1 : Base1
- {
- public void printMethod()
- {
- Console.WriteLine("derived1");
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- Base1 base1 = new Base1();
- Derived1 derived = new Derived1();
- base1.printMethod();
- derived.printMethod();
- base1 = new Derived1();
- base1.printMethod();
- Console.ReadLine();
- }
- }
class Base1 { public void printMethod() { Console.WriteLine("base1"); } } class Derived1 : Base1 { public void printMethod() { Console.WriteLine("derived1"); } } class Program { static void Main(string[] args) { Base1 base1 = new Base1(); Derived1 derived = new Derived1(); base1.printMethod(); derived.printMethod(); base1 = new Derived1(); base1.printMethod(); Console.ReadLine(); }}
- 输出为:
输出为:
base1
derived1
base1
由于方法相同,在用子类新方法编译代码时候,程序在应该调用哪种方法上就会有潜在的冲突,此时编译器会发出警告,认为子类Derived1的printMethod()隐藏了父类Base1的printMethod();此时可以从新命名子类Derived1的printMethod(),这是最好的解决办法,其次可以通过关键字new隐藏此方法来控制版本。
这是所谓的无virtual和override的“重写”其实只是隐藏。
有virtual和override关键字“重写”
在派生类中添加关键字virtual和override,实现对基类的重写:
- class Base1
- {
- public virtual void printMethod()
- {
- Console.WriteLine("base1");
- }
- }
- class Derived1 : Base1
- {
- public override void printMethod()
- {
- Console.WriteLine("derived1");
- }
- }
- class Program
- {
- static void Main(string[] args)
- {
- Base1 base1 = new Base1();
- Derived1 derived = new Derived1();
- base1.printMethod();
- derived.printMethod();
- base1 = new Derived1();
- base1.printMethod();
- Console.ReadLine();
- }
- }
class Base1 { public virtual void printMethod() { Console.WriteLine("base1"); } } class Derived1 : Base1 { public override void printMethod() { Console.WriteLine("derived1"); } } class Program { static void Main(string[] args) { Base1 base1 = new Base1(); Derived1 derived = new Derived1(); base1.printMethod(); derived.printMethod(); base1 = new Derived1(); base1.printMethod(); Console.ReadLine(); } }
- 此时,输出的结果是:
此时,输出的结果是:
base1
derived1
derived1
在类的定义中,申明时定义的类叫申明类,执行实例化时候定义的类叫实例类。例如:
Base1 base1 = new Derived1 ();其中Base1叫做申明类,而Derived1则是实例类。
此时编译器具体的检查的流程如下
1、当调用函数时,系统会直接去检查申明类,看所调用的函数是否为虚函数;
2、如果不是,那么它就直接执行该函数。如果是virtual函数,则转去检查对象的实例类。
3.在实例类中,若有override的函数,则执行该函数,如果没有,则依次上溯,按照同样步骤对父类进行检查,知道找到第一个override了此函数的父类,然后执行该父类中的函数。(星梦《C#虚函数virtual详解收藏》)
由此可知,
若子类Derived1中未添加关键字override,则直接在base1中执行父类同名函数,此时输出结果为:
base1
derived1
base1
依次类推,若有Derived2继承了Derived1,即:
- class Derived2 : Derived1
- {
- public void printMethod(){
- Console.WriteLine("derived2");
- }
- }
class Derived2 : Derived1 { public void printMethod(){ Console.WriteLine("derived2"); } }
在Program类 中执行
- base1 = new Derived2();
- base1.printMethod();
base1 = new Derived2(); base1.printMethod();
则此时执行的是Derived2中override的同名函数printMethod()。
- C#虚函数virtual详解
- C#虚函数virtual详解
- C#虚函数virtual详解
- C#虚函数virtual详解
- C#虚函数virtual详解
- C#虚函数virtual详解
- C#虚函数virtual详解
- C#虚函数virtual详解
- C#虚函数virtual详解
- C#虚函数virtual详解
- C#虚函数virtual详解
- C#虚函数virtual详解收藏
- C#虚函数virtual详解收藏
- C#虚函数virtual详解1
- C#虚函数virtual详解收藏
- C#虚函数virtual
- C#虚函数virtual详解收藏(转)
- C#虚方法virtual详解
- java面试题
- jfreechart Struts2 IllegalStateException 异常处理
- 《基于ARM的嵌入式系统设计与开发》学习笔记
- istringstream用法 关于字符串处理的问题
- Android handler 用法总结
- C#虚函数virtual详解
- 什么是颜色深度(色深)
- 配置nutch1.2时url被过滤掉的问题
- linux 时间获取和计时
- 如何让Android横竖屏切换时不销毁当前activity
- linux C获取系统时间
- java中数据库重连
- 我眼中的MVC模式(2) --- 变体 MOVE
- C#虚函数virtual详解1