一文详解C#中重写(override)及覆盖(new)的区别

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)是在同一个类中重新定义基类中的非虚方法,可以让同一个类中的不同方法具有相同的名称。两者在使用上有一些区别,值得开发者们注意。

后端开发标签