方法重写:
在父类中定义或实现一个虚拟方法,然后在子类中替换它。
当你决定将一个方法声明为虚拟方法时,你允许派生类通过自己的实现来扩展和重写该方法。你还可以让扩展的方法调用父类方法的代码。
在大多数面向对象的语言中,你也可以选择隐藏父类方法。当你引入一个具有相同名称和签名的新实现而不是重写的方法时,你就隐藏了父类方法。
C#中的重写
在C#中,你可以使用virtual关键字在父类中指定一个虚拟方法,并使用override关键字在子类中扩展(或替换)它。
在子类方法中使用base关键字执行父类方法中的代码,例如base.SomeMethod()。
语法示例:
class Robot
{
public virtual void Speak()
{
}
}
class Cyborg:Robot
{
public override void Speak()
{
}
}
覆盖细节
您无法覆盖常规的非虚方法或静态方法。
父方法的第一个版本必须是虚拟的或抽象的。
您可以覆盖任何标记为virtual、abstract或override(已经被覆盖)的父方法。
这些方法必须具有相同的签名。
这些方法必须具有相同的可见性(相同的访问级别)。
使用base关键字来引用父类,如base.SomeMethod()。
C# 覆盖示例
以下代码片段演示了在后代类中使用virtual和override来覆盖父方法。
using System;
class Dog
{
public virtual void Bark()
{
Console.WriteLine("RUFF!");
}
}
class GermanShepard:Dog
{
public override void Bark()
{
Console.WriteLine("Rrrrooouuff!!");
}
}
class Chiuaua:Dog
{
public override void Bark()
{
Console.WriteLine("ruff");
}
}
class InclusionExample
{
public static void Main()
{
Dog MyDog=new Dog();
MyDog=new GermanShepard();
MyDog.Bark();
MyDog=new Chiuaua();
MyDog.Bark();
}
}
隐藏方法使用New关键字
使用new关键字引入父方法的新实现(这将隐藏父方法)。您可以不使用new来隐藏方法,但是会收到编译器警告。使用new将抑制警告。
new和override修饰符具有不同的含义。new修饰符创建一个具有相同名称、签名和可见性的新成员,并隐藏原始成员。override修饰符扩展了继承成员的实现,并允许您实现基于继承的多态性。
避免引入新成员:有时候有明显的理由引入一个与父方法具有相同名称、签名和可见性的新方法。在这些明显的情况下,引入新成员是一个强大的功能。然而,如果您没有明确的理由,那么通过命名新方法为独特且适当的名称来避免引入方法的新版本。
class Robot : System.Object
{
public void Speak()
{
MessageBox.Show("Robot says hi");
}
}
class Cyborg : Robot
{
new public void Speak()
{
MessageBox.Show("hi");
}
}
调用基类版本
在面向对象编程中,一个常见的任务是通过首先执行父类方法代码,然后添加代码来扩展方法。使用base关键字来引用父类,如base.SomeMethod()。
class Robot : System.Object
{
public virtual void Speak()
{
MessageBox.Show("Robot says hi");
}
}
class Cyborg : Robot
{
public override void Speak()
{
base.Speak();
MessageBox.Show("hi");
}
}