在实践中理解virtual/override和new的意义
看起来没有意义的规范,放入实践中就会显示出设计者的巧思,即使概念背得滚瓜烂熟,没有实践过的知识,不算真的掌握
——茂叔
大家知道在C#里面有virtual/override的概念,可以通过不断的重载使得同一个方法在不同子类中实现越来越具体的功能。同时,C#还提供了new修饰符,可以在子类中重新定义与父类中相同名称的方法。
关于二者的概念及区别,网上有很多好文章,官方的文档也很详细,我就不在这里啰嗦了。但是几乎所有的文章都是把概念的区别描述了出来,很少有人告诉我们在实际写码的时候这些概念有什么实际意义。很多人由此觉得既然有这两个概念根本是没事找事……
显然,这是不对的。
让我们来看看下面这个例子。
class Program{
static void Main(string[] args)
{
Cat cat = new Cat();
Chicken chicken = new Chicken();
TrainedDog dog = new TrainedDog();
Animal[] AllAnimals = new Animal[] { cat,chicken,dog};
Console.WriteLine("所有动物集合!");//以动物的身份移动
foreach (Animal it in AllAnimals)
{
it.Come(3,5);
}
Console.WriteLine("小狗出列!");//训练过的小狗单独秀一把
dog.Come(4,6);
Console.ReadKey();
}
}
class Animal
{
protected string Name = "小动物";
public virtual void Come(int x, int y)
{
Console.WriteLine("{0}四足行走到坐标:x={1},y={2}",Name, x, y);
}
}
class Chicken : Animal
{
public Chicken()
{
Name = "小鸡";
}
public override void Come(int x, int y)
{
Console.WriteLine("{0}两足行走到坐标:x={1},y={2}", Name, x, y);
}
}
class TrainedDog : Animal
{
public TrainedDog()
{
Name = "训练过的小狗";
}
public new void Come(int x, int y)
{
Console.WriteLine("{0}倒立行走到坐标:x={1},y={2}", Name, x, y);
}
}
class Cat : Animal
{
public Cat()
{
Name = "小猫";
}
}
运行结果如下:
小猫、小鸡、训练过的小狗,都是动物的子类,都有Come这个方法。
作为动物,当我们调用Come的时候,小猫小狗都四足行走,小鸡则两足行走。
通过Override,我们让小鸡的Come实现了两足行走的特性。
当训练过的小狗以TrainedDog的身份Come的时候,则可以倒立行走,这就new修饰符的意义所在。
训练过的小狗作为动物的一员,有其共性,但当其作为训练过的(Trained)动物的时候,又能展现出其训练过的特性。
在很多项目实际开发中,会经常遇到 某个对象根据不同身份对同一方法实现不同功能 的地方,这时new和override相互配合,就能让代码更加有条理和符合阅读逻辑。