虚方法解析与应用
虚方法概述
当一个实例方法前使用 virtual 关键字修饰时,该方法即为虚方法。虚方法的核心特性在于其可以在派生类中被重写,从而实现多态行为。
虚方法的特点
- 虚方法不能同时使用
static、abstract或override修饰符。 - 虚方法不能是私有的(
private),因此不能使用private修饰符。
虚方法的执行机制
普通方法在编译时会直接绑定到具体实现,而虚方法的调用则依赖运行时的对象类型动态决定。以下是虚方法执行的基本流程:
- 系统首先检查调用对象的声明类型(即声明类)以确定方法是否为虚方法。
- 如果方法不是虚方法,则直接执行;如果是虚方法,则进一步检查对象的实际类型(即实例类)。
- 在实例类中查找是否存在对该虚方法的重写(通过
override关键字)。若存在,则执行实例类中的实现;否则沿继承链向上查找,直到找到第一个重写的实现。
代码示例
示例1:简单虚方法调用
class BaseClass
{
public virtual void Display()
{
Console.WriteLine("This is from BaseClass.");
}
}
class Program
{
static void Main(string[] args)
{
BaseClass obj = new BaseClass();
obj.Display(); // 输出: This is from BaseClass.
Console.ReadLine();
}
}
示例2:派生类重写虚方法
class BaseClass
{
public virtual void Display()
{
Console.WriteLine("This is from BaseClass.");
}
}
class DerivedClass : BaseClass
{
public override void Display()
{
Console.WriteLine("This is from DerivedClass.");
}
}
class Program
{
static void Main(string[] args)
{
BaseClass obj = new DerivedClass();
obj.Display(); // 输出: This is from DerivedClass.
Console.ReadLine();
}
}
示例3:未重写的间接派生类
class BaseClass
{
public virtual void Display()
{
Console.WriteLine("This is from BaseClass.");
}
}
class IntermediateClass : BaseClass
{
public override void Display()
{
Console.WriteLine("This is from IntermediateClass.");
}
}
class FinalClass : IntermediateClass { }
class Program
{
static void Main(string[] args)
{
BaseClass obj = new FinalClass();
obj.Display(); // 输出: This is from IntermediateClass.
Console.ReadLine();
}
}
示例4:隐藏与重写的区别
class BaseClass
{
public virtual void Display()
{
Console.WriteLine("BaseClass Display.");
}
}
class DerivedClass : BaseClass
{
public new void Display()
{
Console.WriteLine("DerivedClass Display.");
}
}
class Program
{
static void Main(string[] args)
{
BaseClass obj = new DerivedClass();
obj.Display(); // 输出: BaseClass Display.
DerivedClass derivedObj = new DerivedClass();
derivedObj.Display(); // 输出: DerivedClass Display.
Console.ReadLine();
}
}
抽象函数与密封类
抽象类可以重写基类中的虚方法,并且可以选择将其定义为抽象方法。例如:
abstract class BaseClass
{
public virtual void Show()
{
Console.WriteLine("BaseClass.Show()");
}
}
abstract class AbstractDerived : BaseClass
{
public abstract override void Show();
}
密封类虽然不能被继承,但仍可包含从基类继承的虚方法。这些方法在密封类中将自动变为非虚方法:
class BaseClass
{
public virtual void Execute()
{
Console.WriteLine("BaseClass.Execute()");
}
}
sealed class SealedClass : BaseClass
{
public override void Execute()
{
Console.WriteLine("SealedClass.Execute()");
}
}
class Program
{
static void Main(string[] args)
{
SealedClass obj = new SealedClass();
obj.Execute(); // 输出: SealedClass.Execute()
Console.ReadLine();
}
}
