#引言
最近看大话设计模式的时候注意到了C#的两个关键字,virtual & abstract,抽象方法和虚方法,感觉自己有点小纠结,来个小结吧。
##共同点:
1.virtual和abstract都是用来修饰父类的,通过覆盖父类的定义,让子类重新定义。
2.如果用来修饰方法,前面修饰符都是public,要不然就会出现编译错误:虚拟方法或抽象方法是不能私有的。毕竟加上virtual或abstract就是让子类重新定义的,而private成员是不能被子类访问的。
当然上那两个其实说的是一回事。
##区别:
区别还是蛮大的。
a) virtual修饰的方法必须有方法实现,就是必须有方法体(哪怕只有一对空的大括号),abstract修饰的方法不能有实现。
demo展示:
public class Test1
{
public virtual void fun1() //虚方法
{
}
}
public abstract class Test2
{
public abstract void fun2() //抽象方法
}
b) virtual可以被子类重写,abstract必须被子类重写
虚方法:
class BaseTest1
{
public virtual void fun()
{ } //父类必须要实现fun()
}
class DeriveTest1:BaseTest1
{
//public override void fun() { } //子类可以不重写父类方法(这行代码可省略),编译无错误
}
抽象方法:
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() { } //错误4:子类必须要重写父类的抽象方法,BaseTest2.fun()方法必须被实现。
public override void fun() //这才是正确的实现方式
{
Console.writeline("玩游戏")
}
}
(c) 无法创建abstract类的实例,因为抽象类只能被继承而无法实例化,比如: BaseTest2 base2 = new BaseTest2(); 将出现编译错误:抽象类或接口不能创建实例。 (d) C#中如果要在子类中重写方法,必须在父类方法前加virtual,在子类方法前添加override,这样就避免了程序员在子类中不小心重写了父类方法。 (e) 抽象方法只能在抽象类中声明,但虚方法不是,虚方法可以在抽象类中也可以在普通类中声明。 #总结: 1.abstract方法必须被重写,因为抽象方法是一种强制子类覆盖的方法。 2.virtual方法必须有实现,父类里面必须已经有可实现的方法体,这样子类不重写父类方法也可以直接继承复用。