【转】C#中virtual和abstract的区别
看到一边文章中有诸多不严谨之处,转载并加以修改。
C++:
C++中,由virtual实现多态。除多态外,virtual有两个特殊用法:
1、虚基类(Virtual base class)
为解决多重继承时的二义性提出来的。使用方法:
class B :virtual public A
class C :virtual public A
class D: public B, public C
Abstract class
2、纯虚函数
含有纯虚函数的类叫做抽象类。纯虚函数如下:
void virtual foo() = 0;
注意:与C#不同,在C++中,abstract不是一个关键字。
C#:
abstract可以修饰类和方法。
virtual在C#中用于修饰方法和属性。
abstract修饰的类叫做抽象类,抽象类不能实例化。
abstract修饰的方法不能有实现体,相当于纯虚函数
如,
public abstract Light {
public void turnon()
{
...
}
public abstract void turnoff();
};
注意:抽象方法只能在抽象类中。
virtual 修饰的方法可以在一般类中。
其修饰的方法在父类中一定要有实现,即使只是一对大括号。
public Light {
public virtual void turnon() {};
};
抽象方法和virtual方法在派生类中的重载都是使用关键字override.
派生类如果是非abstract,则其中一定要有抽象方法的具体实现
一、Virtual方法(虚方法)
virtual 关键字用于在基类中修饰方法。virtual的使用会有两种情况:
情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法。那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法。
情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法。那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法。
二、Abstract方法(抽象方法)
abstract关键字只能用在抽象类中修饰方法,并且没有具体的实现。抽象方法的实现必须在派生类中使用override关键字来实现。
C#的virtual & abstract经常让人混淆,这两个限定词都是为了让子类进行重新定义,覆盖父类的定义。但是用法上差别很大。
a) virtual修饰的方法必须有方法实现(哪怕只有一对大括号),abstract修饰的方法不能有实现。
b) virtual可以被子类重写,abstract必须被子类重写
c) 如果类中的某一函数被abstact修饰,则类名也必须用abstact修饰
d) Abstract修饰的类不能被创建实例。
e) C#中如果准备在子类重写父类的方法,则该方法在父类中必须用virtual修饰,在子类中必须用overide修饰,避免了程序员在子类中不小心重写了父类父类方法。
它们有一个共同点:如果用来修饰方法,前面必须添加public,要不然就会出现编译错误:虚拟方法或抽象方法是不能私有的。毕竟加上virtual或abstract就是让子类重新定义的,而private成员是不能被子类访问的。
但是它们的区别很大。(virtual是“虚拟的”,abstract是“抽象的").