虚方法(virtual关键字)
using System;
namespace ConsoleAppTestVirtualMethod
{
class Program
{
static void Main(string[] args)
{
// cat1是Animal类型的对象
// I'm in the Animal Sounds Method...
Animal cat1 = new Cat();
cat1.Sounds();
}
}
class Animal
{
public void Sounds()
{
Console.WriteLine("I'm in the Animal Sounds Method...");
}
}
class Cat:Animal
{
// 继承并实现相同的方法
public void Sounds()
{
Console.WriteLine("I'm in the Cat Sounds Method...");
}
}
}
- 使用
虚方法(virtual)和override实现子类重写的方法
using System;
namespace ConsoleAppTestVirtualMethod
{
class Program
{
static void Main(string[] args)
{
// I'm in the Cat Sounds Method...
Animal cat1 = new Cat();
cat1.Sounds();
}
}
class Animal
{
// virtual标识"虚方法"
public virtual void Sounds()
{
Console.WriteLine("I'm in the Animal Sounds Method...");
}
}
class Cat:Animal
{
// override重写
public override void Sounds()
{
Console.WriteLine("I'm in the Cat Sounds Method...");
}
}
}
public new void Sounds()中,new关键字的作用:
- explicitly(显式地)告诉编译器和阅读代码的人:“我知道这个方法和父类中的方法同名,但我并不是要重写(override)它,我是要 intentionally(故意地)隐藏它,并提供一个全新的实现。”
- 它是一种意图声明,主要用于消除警告,并表明你的行为是经过考虑的。
- 意义: 使用new通常意味着你的类层次结构设计可能存在问题,或者你正在处理一个无法修改其父类(比如一个外部的库)但又必须添加一个同名方法的情况。你应该先深刻理解virtual和override机制。new关键字你需要知道它的存在和含义,但在自己设计代码时,应尽量避免使用。
using System;
namespace ConsoleAppTestVirtualMethod
{
class Program
{
static void Main(string[] args)
{
......
}
}
class Animal
{
public void Sounds()
{
......
}
}
class Cat:Animal
{
// new关键字显式声明Sounde方法不需要重写,暂时隐藏起来...
public new void Sounds()
{
Console.WriteLine("I'm in the Cat Sounds Method...");
}
}
}
public class Animal
{
public void MakeSound() { Console.WriteLine("Animal sound"); } // 普通方法
public virtual void Move() { Console.WriteLine("Animal moves"); } // 虚方法
}
public class Dog : Animal
{
public new void MakeSound() { Console.WriteLine("Dog barks (new)"); } // 隐藏 (使用 new)
public override void Move() { Console.WriteLine("Dog runs (override)"); } // 重写
}
// 测试代码
Dog myDog = new Dog();
Animal myAnimal = myDog; // 关键:将Dog对象用Animal类型的变量来引用
// 调用MakeSound方法
myDog.MakeSound(); // 输出: Dog barks (new) - 调用的是Dog自己的新方法
myAnimal.MakeSound(); // 输出: Animal sound - 调用的是Animal的方法 (因为被隐藏了,编译时绑定)
// 调用Move方法
myDog.Move(); // 输出: Dog runs (override)
myAnimal.Move(); // 输出: Dog runs (override) - 调用的是Dog的重写方法 (因为是多态,运行时绑定)