C#中的继承、重写、覆盖、多态、virtual override 以及其他
2012-01-08 20:50
711 查看
using System; using System.Collections.Generic; using System.Linq; using System.Text; public class BaseClass { public virtual void displayName() { Console.WriteLine("BaseClass"); } } public class DerivedClass : BaseClass { public virtual void displayName() { Console.WriteLine("DerivedClass"); } } public class SubDerivedClass:DerivedClass { public override void displayName() { Console.WriteLine("SubDerivedClass"); } } public class SuperDerivedClass:SubDerivedClass { public void displayName() { Console.WriteLine("SuperDerivedClass"); } } class Program { static void Main(string[] args) { SuperDerivedClass superDerivedClass = new SuperDerivedClass(); SubDerivedClass subDerivedClass = superDerivedClass; DerivedClass derivedClass = superDerivedClass; BaseClass baseClass = superDerivedClass; superDerivedClass.displayName(); subDerivedClass.displayName(); derivedClass.displayName(); baseClass.displayName(); } }
结果剖析:
superDerivedClass.displayName();不需解释。没有子类,所以无多态。
subDerivedClass.displayName();
subDerivedClass重写了DerivedClass的方法,则subDerivedClass中的displayName也是虚方法,于是运行时要从继承链中尽量找派生得最远的虚方法,发现其子类
SuperDerivedClass没有用override,这意味着SuperDerivedClass只是覆盖了displayName方法,没有重写它。所以并不执行SuperDerivedClass的displayName,而执
subDerivedClass的displayName。
derivedClass.displayName();
DerivedClass覆盖了(是覆盖,不是重写,因为没有override标签)BaseClass的方法,但这个覆盖的方法被声明为virtual,于是运行时要从继承链中尽量找派生得最远的虚方法,发现其子类SubDerivedClass重写了这个方法,于是从SubDerivedClass继续往下找,找到SuperDerivedClass时,发现SuperDerivedClass覆盖了这个方法,没有重写,所以最终执行SubDerivedClass的displayName方法。
baseClass.displayName();
在BaseClass中displayName是个虚方法,于是它要试图找派生的最远的虚方法。但找到DerivedClass就发现,DerivedClass已经把displayName覆盖了,这条虚链于是就断了。所以就直接执行BaseClass的方法了。
注意:
如果把SubDerivedClass的override去掉,则试图在SuperDerivedClass中写public override void displayName()是编译不过的。因为虽然在DerivedClass中有虚的displayName可供子类override,但由于SubDerivedClass中的DerivedClass没有加override,这相当于SubDerivedClass覆盖了DerivedClass的displayName方法,而非override了它,于是在SuperDerivedClass看到的displayName,其实是SubDerivedClass的dislayName,是一个非虚的方法,而不是从DerivedClass传承下来的虚方法,所以不能override总结
若一个类中有一个方法,则只在两种情况下该方法才会是一个虚方法。1:该方法用virtual定义。
2:该类的父类中有一个同名的虚方法,在该类中用override关键字重写了父类的虚方法。
子类要想“重写”而非“覆盖”父类的方法,要满足两个条件。
一:“父类方法是虚方法。(这意味着该方法或者是有virtual标记的,或者是override它的父类的。)”。
二:“子类中有override标记”。
这二者缺一,则意味着子类是对父类的方法进行了“覆盖”,而非“重写”。
如果一个方法是虚方法(),则运行时从找那个“重写”得最远的方法来执行。一旦遇到“覆盖”,则继承链就断掉了。
http://www.2cto.com/kf/201007/52956.html
相关文章推荐
- [原创]C#中的继承、重写、覆盖、多态、virtual override 以及其他
- C# 继承与多态,相关关键字virtual、override、new
- c#中多态的学习与使用方法以及重写(覆盖)和重载的区别
- java 继承 多态(override->重写(=覆盖)、overload->重载、polymorphism -> 多态)
- C#基础:多态:基类可以定义并实现虚(virtual)方法,派生类可以重写(override)这些方法
- php 面向对象的三大要素(封装、继承、多态)以及重写(override)和重载(overload)的举例说明
- A.4-继承,方法重写(覆盖)(override),虚函数(virtaul)和多态,抽象方法和抽象类abstract,密封类(sealed)和密封方法,常量的定义(const)
- C#.NET学习笔记---C#中方法覆盖时override和new的比较,abstract和virtual的比较(含C#多态的实现)
- C#中重写(override)、覆盖(new)、虚拟(Virtual)关键字的区别
- Swift 继承 override重写父类方法以及属性 final用法
- c# 虚函数Virtual与重写override
- c# 继承 和 关键字:abstract,const,override,readonly,static,virtual,base,this
- Java 子类继承父类方法的重写(或者覆盖,override)
- C#中重写(override)和覆盖(new)的区别
- 多态 -重写/覆盖(Override) -重载(Overload)
- C#中重写(override)和覆盖(new)的区别
- C#下 子类继承父类的虚方法后 使用override重写父类方法 和 不使用override重写有什么区别?
- java笔记之封装、继承、重写、多态以及类型转换
- 转:C#继承之base,virtual,override,abstract,new,sealed关键字
- java 子类继承父类 -- 重写、覆盖与多态