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

c#中new和override的区别. virtual和abstract方法的区别.

2014-02-28 16:16 405 查看
最近做程序用到了虚函数:virtual ,所以对实现类中使用new 和 override的区别温习:

new

C#中new关键字表示隐藏,是指加上new关键字的属性或函数将对本类和继承类隐藏基类的同名属性或函数.

public classA

{

public virtual void Method()

{

Console.WriteLine("This Method in Class A!");

}

}

public classB:A

{

public new void Method()

{

Console.WriteLine("This Method in Class B!");

}

}

对于上面这个例子来说,假如运行 A a = new B(); a.Method(); 会输出 This Method in Class A !, 这是因为 classB 继承calssA,

现在B中的Method函数隐藏A中的Method,所以从B(包括继承于B的子类)的角度来看类中的Method就是B.Method, A的Method

不可见,但是如果从A的角度来看B,A只认识类B中继承于A的Method函数,对于B类中的Method它不可见,所以 A a =new B();

a.Method();相当于是调用了类B中继承于A的Method函数.

override

C#中override关键字表示重写,对于加上override关键字的属性或函数将完全覆盖基类的同名虚函数或虚属性,使基类的虚属性和

虚函数在整个继承链中都不可见(在子类中用base关键字调用除外)。

public class A

{

public virtual void Method()

{

Console.WriteLine("This Method in Class A!");

}

}

public class B:A

{

public override void Method()

{

Console.WriteLine("This Method in Class B!");

}

}

对于上面这个例子来说,假如运行 A a= new B(); a.Method();会输出 This Method in Class B! ,因为ClassB的Method函数完全覆盖

基类的同名虚函数Method,使整个继承链中看见的Method函数都是B中的Method,所以就算是以A角度来看B,A看到的Method函数也是

B中的Method,因为A中的Method完全被B的覆盖了.

但是如果要在B的对象中调用A的Method函数可以使用base关键字,比如

public class A

{

public virtual void Method()

{

Console.WriteLine("This Method in Class A!");

}

}

public class B:A

{

public override void Method()

{

base.Method();

}

}

A a = new B(); a.Method(); 会输出 This Method in Class A!. base.Method();表示调用类B中继承于基类A的Method.

new 、override与interface

接口在相互继承的时候也会隐藏基接口的同名属性或函数,但是对于接口来说很特殊,隐藏对于基接口来说是不起作用的,

接口内部的属性或函数都只是声明,它们都指向实现接口的类中的同名实现函数,通过接口调用接口的属性和函数的时候

都会去调用实现类中从上到下最先可见的同名函数和同名属性:

public interface IA { void Method() ;}

public interface IB:IA { new void Method(); }

public class IClass:IB { public void Method(){ Console.writeline("this method in class IClass!");

public class ISubClass : IClass {public new void Method() { Console.writeline("this method in class ISubClass!");}

IA ia = new ISubClass(); ia.Method(); 输出 this method in class IClass! 因为对于ia来说在继承链中最先见到的同名实现函数

是类IClass的Method函数.

上面的例子稍作修改:

public interface IA { void Method() ;}

public interface IB:IA { new void Method(); }

public class IClass:IB { public virtual void Method(){ Console.writeline("this method in class IClass!");

public class ISubClass : IClass {public override void Method() { Console.writeline("this method in class ISubClass!");}

IA ia = new ISubClass(); ia.Method(); 输出 this method in class ISubClass! 因为继承链中的Method函数都被ISubClass的

Method覆盖了,所以对于ia来说在继承链中最先见到的同名实现函数是类 ISubClass的Method函数.

virtual 和 abstract

abstract可以修饰类和方法。

virtual在C#中用于修饰方法和属性。

abstract修饰的类叫做抽象类,抽象类中必须有抽象方法,同时也可以有非抽象方法,既可以有方法的具体实现,继承抽象父类的子类中,如果子类没有

实现抽象父类中的抽象方法,那么这个子类也必须声明为抽象的,即只要类中有抽象的方法那么这个类就一定是抽象类,且抽象类不能实例化,abstract修饰的方法不能实现。

如,

public abstract Light {

public abstract void turnon();

public abstract void turnoff();

};

在派生类中一定要有抽象方法的具体实现。

注意:抽象方法只能在抽象类中。

virtual 修饰的方法可以在一般类中。

其修饰的方法在父类中一定要有实现,即使只是一对大括号。

public Light {

public virtual void turnon() {};

};

抽象方法和virtual方法在派生类中的重载都是使用关键字override.

一、Virtual方法(虚方法)

virtual 关键字用于在基类中修饰方法。virtual的使用会有两种情况:

情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法。那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法。

情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法。那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法。

二、Abstract方法(抽象方法)

abstract关键字只能用在抽象类中修饰方法,并且没有具体的实现。抽象方法的实现必须在派生类中使用override关键字来实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: