1. 重写(override)和覆盖(new)的概念
在C#中,重写(override)和覆盖(new)都是用来实现方法的多态性。然而,它们之间有一些重要的区别。
2. 重写(override)的使用
2.1 在继承关系中的重写(override)
重写(override)是指在派生类中重新实现基类中的虚方法。通过重写一个方法,派生类可以为基类中的方法提供自己的实现逻辑。
下面是一个示例,展示了如何在派生类中重写基类的虚方法:
class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Animal is making a sound");
}
}
class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("Cat is meowing");
}
}
Animal animal = new Cat();
animal.MakeSound(); // 输出: Cat is meowing
在上述示例中,基类Animal中定义了虚方法MakeSound,派生类Cat通过重写该方法,实现了自己的MakeSound逻辑。
需要注意的是,重写(override)的方法在运行时会根据对象的实际类型来调用相应的方法,而不是根据变量声明的类型。
2.2 使用关键字base调用基类方法
在派生类中重写一个基类方法时,如果需要在派生类的方法中调用基类的实现,可以使用关键字base。
下面的示例展示了如何使用base调用基类的方法:
class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Animal is making a sound");
}
}
class Cat : Animal
{
public override void MakeSound()
{
base.MakeSound(); // 调用基类的MakeSound方法
Console.WriteLine("Cat is meowing");
}
}
Animal animal = new Cat();
animal.MakeSound();
// 输出:
// Animal is making a sound
// Cat is meowing
在上述示例中,派生类Cat通过重写MakeSound方法,在方法中使用base关键字调用了基类Animal的MakeSound方法。
3. 覆盖(new)的使用
3.1 在同一个类中的覆盖(new)
覆盖(new)是指在同一个类中重新定义基类中的非虚方法。通过覆盖一个方法,可以让同一个类中的不同方法具有相同的名称。
下面是一个示例,展示了如何使用覆盖(new):
class Animal
{
public void MakeSound()
{
Console.WriteLine("Animal is making a sound");
}
}
class Cat : Animal
{
public new void MakeSound()
{
Console.WriteLine("Cat is meowing");
}
}
Cat cat = new Cat();
cat.MakeSound(); // 输出: Cat is meowing
Animal animal = new Cat();
animal.MakeSound(); // 输出: Animal is making a sound
在上述示例中,派生类Cat使用了覆盖(new)关键字,重新定义了基类Animal中的MakeSound方法。在同一个类中,可以通过具有相同名称的方法来实现不同的逻辑。
3.2 覆盖(new)与重写(override)的区别
覆盖(new)与重写(override)在使用上有一些重要的区别。
第一,覆盖(new)是在同一个类中重新定义基类中的非虚方法,而重写(override)是在派生类中重新实现基类中的虚方法。
第二,通过覆盖(new)定义的方法在运行时是根据变量声明的类型来调用的,而重写(override)的方法是根据对象的实际类型来调用的。
第三,覆盖(new)关键字可以让同一个类中的不同方法具有相同的名称,而重写(override)则必须使用相同的方法签名。
4. 总结
在C#中,重写(override)和覆盖(new)都是实现方法的多态性的重要方式。重写(override)是在派生类中重新实现基类中的虚方法,通过重写可以为基类方法提供自己的实现逻辑。覆盖(new)是在同一个类中重新定义基类中的非虚方法,可以让同一个类中的不同方法具有相同的名称。两者在使用上有一些区别,值得开发者们注意。