c# 中 Abstract和Virtual对照容易混淆,都与担任有关,并且涉及override的使用。下面讨论一下二者的区别:
一、Virtual要领(虚要领)
virtual 关键字用于在基类中修饰要领。virtual的使用会有两种情况:
情况1:在基类中界说了virtual要领,但在派生类中没有重写该虚要领。那么在对派生类实例的挪用中,该虚要领使用的是基类界说的要领。
情况2:在基类中界说了virtual要领,然后在派生类中使用override重写该要领。那么在对派生类实例的挪用中,该虚要领使用的是派生重写的要领。
二、Abstract要领(抽象要领)
abstract关键字只能用在抽象类中修饰要领,并且没有具体的实现。抽象要领的实现必需在派生类中使用override关键字来实现。
接口和抽象类最素质的区别:抽象类是一个不完全的类,是对东西的抽象,而接口是一种行为规范。
三、关键字
Static:当一个要领被声明为Static时,这个要领是一个静态要领,编译器会在编译时保存这个要领的实现。也就是说,这个要领属于类,但是不属于任何成员,不管这个类的实例是否存在,它们城市存在。就像入口函数Static void Main,,因为它是静态函数,所以可以直接被挪用。
Virtua:当一个要领被声明为Virtual时,它是一个虚拟要领,直到你使用ClassName variable = new ClassName();声明一个类的实例之前,它都不存在于真实的内存空间中。这个关键字在类的担任中非每每用,用来供给类要领的多态性撑持。
overrride:暗示重写 这个类是担任于Shape类
virtual,abstract是报告其它想担任于他的类 你可以重写我的这个要领或属性,否则不允许。
abstract:抽象要领声明使用,是必需被派生类覆写的要领,抽象类就是用来被担任的;可以当作是没有实现体的虚要领;如果类中包罗抽象要领,那么类就必需界说为抽象类,岂论是否还包罗其他一般要领;抽象类不能有实体的。
a) virtual修饰的要领必需有要领实现(哪怕只有一对大括号),abstract修饰的要领不能有实现。
b) virtual可以被子类重写,abstract必需被子类重写
c) 如果类中的某一函数被abstact修饰,则类名也必需用abstact修饰
d) Abstract修饰的类不能被创建实例。
e) C#中如果筹备在子类重写父类的要领,则该要领在父类中必需用virtual修饰,在子类中必需用overide修饰,制止了措施员在子类中不小心重写了父类父类要领。
注:用abstract修饰的类只能被担任不能够被实例化。
解读二
virtual和abstract都是用来修饰父类的,通过笼罩父类的界说,让子类从头界说。
它们有一个配合点:如果用来修饰要领,前面必需添加public,要不然就会呈现编译错误:虚拟要领或抽象要领是不能私有的。终究加上virtual或abstract就是让子类从头界说的,而private成员是不能被子类访谒的。
但是它们的区别很大。(virtual是“虚拟的”,abstract是“抽象的").
(1)virtual修饰的要领必需有实现(哪怕是仅仅添加一对大括号),而abstract修饰的要领必然不能实现。如对付virtual修饰的要领如果没有实现:
public class Test1 { public virtual void fun1(); }
错误:“Test1.fun1()”必需声明主体,因为它未符号为 abstract、extern 或 partial
对付abstract修饰的要领如果有实现:
public abstract class Test2 { public abstract void fun2() { } }
错误: “Test2.fun2()”无法声明主体,因为它符号为 abstract
(2)virtual可以被子类重写,而abstract必需被子类重写。
class BaseTest1 { public virtual void fun() { }//必需有实现 } class DeriveTest1:BaseTest1 { //public override void fun() { } }
编译不会呈现错误,如果重写了virtual修饰的要领,前面必需添加override(这样就报告了编译器你要重写虚拟要领),而且必需有实现,否则编译堕落:
abstract class BaseTest2 { public abstract void fun(); } class DeriveTest2 : BaseTest2 { //public override void fun();错误1:没有实现 //public void fun() { } 错误2:重写时没有添加override //override void fun() { }错误3:虚拟成员或者抽象成员不能是私有的(只要在父类中声明了虚拟成员或抽象成员,即等于担任的也要加上这个限制) public override void fun() { }//如果重写要领; 错误:“A.DeriveTest2”不实现担任的抽象成员“A.BaseTest2.fun()” }
(3)如果类成员被abstract修饰,则该类前必需添加abstract,因为只有抽象类才可以有抽象要领。