您的位置:首页 > 编程语言 > C#

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐