抽象方法、虚方法小结
abstract :表示方法是抽象方法,在子类中必须重写。抽象方法所在的类必须是抽象类,即用abstract modifiers;
virtual:表示此方法是virtual方法,除了在子类中可以重写外(在子类中也可直接使用),和普通方法完全一样;
override:表示重写父类的virtual方法;
new: 显式隐藏从基类继承的成员;
区别:
virtual:标记方法为虚方法
1.可在派生类中以override覆盖此方法
2.不覆盖也可由对象调用
3.无此标记的方法(也无其他标记),重写时需用new隐藏原方法
abstract 与virtual : 方法重写时都使用 override 关键字
如果子类重写了父类的虚方法,那么通过父类变量来调用这个方法的时候会调用子类的,如果没有,则会调用父类的
Eg1:
public abstract class Book { public Book() { } public abstract void getPrice(); //抽象方法,不含主体 public virtual void getName() //虚方法,可覆盖 { Console.WriteLine("this is a test:virtual getName()"); } public virtual void getContent() //虚方法,可覆盖 { Console.WriteLine("this is a test:virtual getContent()"); } public void getDate() //一般方法,若在派生类中重写,须使用new关键字 { Console.WriteLine("this is a test: void getDate()"); } } public class ChineseBook : Book { public override void getPrice() //实现抽象方法,必须实现 { Console.WriteLine("this is a test:ChineseBook override abstract getPrice()"); } public override void getName() //覆盖原方法,不是必须的 { Console.WriteLine("this is a test:ChineseBook override virtual getName()"); } public new void getDate() { Console.WriteLine("this is a test:ChineseBook new getDate()"); } public void Run() { getPrice(); getName(); getContent(); getDate(); } }
.csharpcode, .csharpcode pre { font-size: small; color: rgba(0, 0, 0, 1); font-family: consolas, “Courier New”, courier, monospace; background-color: rgba(255, 255, 255, 1) }
.csharpcode pre { margin: 0 }
.csharpcode .rem { color: rgba(0, 128, 0, 1) }
.csharpcode .kwrd { color: rgba(0, 0, 255, 1) }
.csharpcode .str { color: rgba(0, 96, 128, 1) }
.csharpcode .op { color: rgba(0, 0, 192, 1) }
.csharpcode .preproc { color: rgba(204, 102, 51, 1) }
.csharpcode .asp { background-color: rgba(255, 255, 0, 1) }
.csharpcode .html { color: rgba(128, 0, 0, 1) }
.csharpcode .attr { color: rgba(255, 0, 0, 1) }
.csharpcode .alt { background-color: rgba(244, 244, 244, 1); width: 100%; margin: 0 }
.csharpcode .lnum { color: rgba(96, 96, 96, 1) }
Output:
this is a test:ChineseBook override abstract getPrice()
this is a test:ChineseBook override virtual getName()
this is a test:virtual getContent()
this is a test:ChineseBook new getDate()
Eg2:
public abstract class FlowModel { public abstract void A(); public virtual void B(){ Console.WriteLine("Orginal B()"); } public virtual void C(){ Console.WriteLine("Orginal C()"); } public void D(){ Console.WriteLine("Orginal D()"); } } public class Flow:FlowModel { public override void A() { //执行步骤A Console.WriteLine("Execute Step A "); } public virtual void B() { //执行步骤B Console.WriteLine("Execute Step B"); } public void C() { //执行步骤C Console.WriteLine("Execute Step C"); } public new void D() { Console.WriteLine("Execute Step D"); } public void Run() { A(); B(); //步骤B是扩展点 ,可以由子类决定具体执行什么 C(); D(); } }
Output:
Execute Step A
Execute Step B
Execute Step C
Execute Step D