> 技术文档 > 【C#补全计划:类和对象(七)—— 重写虚方法】

【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(); // 保留父类行为}}}

运行效果如下:

        今天的学习就到这里了。感谢阅读。

        再见!

CG素材网