【C#补全计划:类和对象(七)—— 重写虚方法】
一、virtual和override
1. 问题引入:使用里氏替换原则时,使用父类容器装载子类对象,若不使用virtual和override而是使用new,当子类调用两个类共有的方法时,调用的是父类的方法而不是子类的方法:
using System;namespace Polymorphism
{class Program{static void Main(string[] args){// 使用new关键字隐藏父类方法Father son = new Son();son.fun(); // 输出:调用父类fun()方法(son as Son).fun(); // 输出:调用子类fun()方法}}// 使用new关键字隐藏父类方法class Father{public void fun(){Console.WriteLine("调用父类fun()方法");}}class Son : Father{public new void fun() // 使用new关键字隐藏父类方法{Console.WriteLine("调用子类fun()方法");}}
}
运行结果如下:
2. virtual:使父类的方法变为虚方法,可以被子类重写
3. override:使子类的方法重写父类的方法
4. 使用:
using System;namespace Polymorphism
{class Program{static void Main(string[] args){// 使用new关键字隐藏父类方法 Father son = new Son();son.fun(); // 输出:调用父类fun()方法(son as Son).fun(); // 输出:调用子类fun()方法// 使用override关键字重写父类方法GameObject player = new Player();player.ATK(); // 输出:Player攻击(player as Player).ATK(); // 输出:Player攻击}}// 使用new关键字隐藏父类方法class Father{public void fun(){Console.WriteLine("调用父类fun()方法");}}class Son : Father{public new void fun() // 使用new关键字隐藏父类方法{Console.WriteLine("调用子类fun()方法");}}// 使用override关键字重写父类方法class GameObject{public virtual void ATK(){Console.WriteLine("Gameobject攻击");}}class Player : GameObject{public override void ATK() // 使用override关键字重写父类方法{Console.WriteLine("Player攻击");}}
}
运行结果如下:
二、保留父类行为
1. 关键字:base
2. 作用:调用父类的方法
3. 使用:
using System;namespace Polymorphism
{class Program{static void Main(string[] args){// 使用new关键字隐藏父类方法 Father son = new Son();son.fun(); // 输出:调用父类fun()方法(son as Son).fun(); // 输出:调用子类fun()方法// 使用override关键字重写父类方法GameObject player = new Player();player.ATK(); // 输出:Player攻击(player as Player).ATK(); // 输出:Player攻击// 使用多态调用父类方法GameObject enemy = new Enemy();enemy.ATK(); // 输出:Gameobject攻击}}// 使用new关键字隐藏父类方法class Father{public void fun(){Console.WriteLine("调用父类fun()方法");}}class Son : Father{public new void fun() // 使用new关键字隐藏父类方法{Console.WriteLine("调用子类fun()方法");}}// 使用override关键字重写父类方法class GameObject{public virtual void ATK(){Console.WriteLine("Gameobject攻击");}}class Player : GameObject{public override void ATK() // 使用override关键字重写父类方法{Console.WriteLine("Player攻击");}}class Enemy : GameObject{public override void ATK() // 使用override关键字重写父类方法{Console.Write("Enemy: ");base.ATK(); // 保留父类行为}}
}
运行效果如下:
今天的学习就到这里了。感谢阅读。
再见!