Virtual
virtual
官方描述:关键字用于修改方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。
配合的关键字
override
官方描述:扩展或修改继承的方法、属性、索引器或事件的抽象或虚拟实现需要 override 修饰符。new
修饰符 官方描述:在用作声明修饰符时,new 关键字可以显式隐藏从基类继承的成员。 隐藏继承的成员时,该成员的派生版本将替换基类版本。 虽然可以不使用 new 修饰符来隐藏成员,但将收到编译器警告。 如果使用 new 来显式隐藏成员,将禁止此警告。(new有很多用途,这里主要用作于修饰符)
项目源码地址:https://gitee.com/michel4liu/LearnCSharp.git
项目:LearnVirtual
环境VS2017 .NET Core2.0
virtual+override 比较常见的用法
static void Main(string[] args)
{
Father f = new Father();
f.DoSomething();//输出 Father.Work
Son s = new Son();
s.DoSomething();//输出 Son.Learn
Father fs = new Son();
fs.DoSomething();//输出 Son.Learn
}
class Father
{
public virtual void DoSomething()
{
Console.WriteLine($"{nameof(Father)}.Work");
}
}
class Son : Father
{
public override void DoSomething()
{
Console.WriteLine($"{nameof(Son)}.Learn");
}
}
重点在于第三个输出
Father fs = new Son();
fs.DoSomething(); //输出 Son.Learn
因 Son 利用关键字 override 重写 DoSomething() 所以用Father声明接收时也能指向Son.DoSomething()
virtual+New
static void Main(string[] args)
{
Father f = new Father();
f.DoSomething();//输出 Father.Work
Son s = new Son();
s.DoSomething();//输出 Son.Learn
Father fs = new Son();
fs.DoSomething();//输出 Father.Learn
}
class Father
{
public virtual void DoSomething()
{
Console.WriteLine($"{nameof(Father)}.Work");
}
}
class Son : Father
{
public new void DoSomething()
{
Console.WriteLine($"{nameof(Son)}.Learn");
}
}
重点在于第三个输出
Father fs = new Son();
fs.DoSomething(); //输出 Son.Learn
因 Son 利用关键字 new 隐藏继承DoSomething() 所以用Father声明接收Son对象时只能指向Father.DoSomething()
注意点
- 如果Father和Son 中都不指定virtual、override 、new 关键字,编译默认使用new,编译器会报警告。
- New和Override 关键字互斥的。不可以同时使用。
- New重写后能通过转换(如获取父对象调用或base.方法())找到基类的方法,Override 重写后则无法找到基类方法。