早绑定early binding:
在编译的时候就已经却确定了将来程序运行基类或者派生类的哪个方法.
在编译代码的时候根据引用类型就决定了运行该引用类型中定义的方法.即基类方法.
这种方式运行效率高.
晚绑定late binding:
只有在运行的时候才能决定运行基类或者派生类中的方法.
运行的时候将根据该实际类型,而不是引用类型来调用相应的方法.即取决于我们new了什么对象.
为了实现晚绑定,C#引入了virtual和override关键字.默认情况下,C#方法为非虚方法,如果某个方法被声明为虚方法,则继承该方法的任何类都可以实现自己的版本.
若要使方法称为虚方法,需要在方法前使用virtual关键字,然后派生类可以使用override关键字来重写基类虚方法,或者使用new关键字来覆盖基类虚方法.
如果new和override均为指定,编译器会按照添加new关键字来执行.
例子:
public class Super { public virtual void Show() { HttpContext.Current.Response.Write("Super<br/>"); } } public class SonOverride : Super { public override void Show() { HttpContext.Current.Response.Write("Son Override<br/>"); } } public class SonNew : Super { public new void Show() { HttpContext.Current.Response.Write("Son New<br/>"); } }public partial class mytest_Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Super[] arrs = new Super[3]; arrs[0] = new Super(); arrs[1] = new SonOverride(); arrs[2] = new SonNew(); for (int i = 0; i < arrs.Length; i++) { arrs[i].Show(); } } }
结果:
Super Son Override Super
再看下面一个例子,可以理解override和new的作用:
public class A { public virtual void Show() { HttpContext.Current.Response.Write("A Show<br/>"); } } public class B:A { public void Shows() { HttpContext.Current.Response.Write("B Shows<br/>"); } } public class C : B { }
但是,现在如果修改了A类如下:
public class A { public virtual void Show() { HttpContext.Current.Response.Write("A Show<br/>"); } public virtual void Shows() { HttpContext.Current.Response.Write("A Shows<br/>"); } }
此时,运行下列代码,结果如何呢?
protected void Page_Load(object sender, EventArgs e) { A c = new C(); c.Shows(); }
注意,此时实例a也具有了Shows方法.若要执行a.Shows(),结果会如何呢?
protected void Page_Load(object sender, EventArgs e) { A a = new B(); a.Shows(); }
结果:
A Shows
因为此时类B中的Shows()方法默认是使用了new关键字的.此时,若想以后均使用类B自定义的Shows方法,该怎么办呢?
此时就用到了override关键字.类B修改如下:
public class B:A { public override void Shows() { HttpContext.Current.Response.Write("B Shows<br/>"); } }
此时再运行代码,结果为:
B Shows
结论:
override可以确保所有继承了B类的派生类都使用B中定义的派生类版本.若想使用类A中的方法,则需使B中和A中签名的方法前都加上new关键字.