48.里氏替换原则中虚函数执行逻辑
48.1 题目
当我们使用里氏替换原则,用父类容器装载子类对象时,通过该父类容器调用其中的一个虚函数,执行的逻辑是父类中的还是子类中的逻辑呢?
public class Father
{
public virtual void Eat()
{
Console.WriteLine("Father Eat");
}
}
public class Son : Father
{
public override void Eat()
{
Console.WriteLine("Son : Father");
}
}
Father f = new Son();
f.Eat();
48.2 深入解析
执行结果会是子类中的逻辑。若子类重写了虚函数,那么执行的逻辑会是子类中的逻辑。具体是否执行父类中逻辑,主要取决于子类重写时是否利用了 base 关键字来执行父类逻辑。
Son : Father
Father f = new Son();
f.Eat(); // 执行结果为:Son : Father
48.3 答题示例
“根据里氏替换原则和虚函数的多态特性,当父类引用指向子类对象时(如
Father f = new Son()),调用虚函数会执行子类的重写逻辑。在您提供的示例中,Son类重写了Eat()方法,因此f.Eat()的输出结果是Son : Father。关键点在于:
- 虚函数通过对象的实际类型(而非引用类型)来决定执行逻辑
- 即使变量
f被声明为Father类型,但其实际指向的是Son实例- 子类重写方法中若使用
base.Eat(),会先执行父类逻辑再执行子类逻辑,但本题子类未调用base,因此只输出子类逻辑。”
48.4 关键词联想
- 里氏替换原则(LSP)
- 动态绑定(运行时多态)
- 虚函数表(VTable)
virtual与override关键字- 对象实际类型 vs 引用类型
- 方法重写(Method Override)
base关键字调用父类实现- 多态性(Polymorphism)
- 静态类型检查 vs 动态执行
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com