在本文中,我们展示了如何在C#中使用override修饰符。
在C#中,需要使用override修饰符来扩展或修改继承方法、属性、索引器或事件的抽象或虚拟实现。
C#重写虚方法
Object是C#类型系统的根。它支持所有类并为派生类提供低级服务。
Object.ToString返回代表当前对象的字符串。该方法的默认实现返回对象类型的完全限定名称。
public virtual string? ToString();
ToString方法有一个virtual修饰符。
通常的做法是重写Object.ToString方法以提供我们自定义对象的人类可读表示。
var u = new User("John Doe", "gardener");
Console.WriteLine(u);
class User
{
    public User(string name, string occupation)
    {
        this.Name = name;
        this.Occupation = occupation;
    }
    public string Name { get; set; }
    public string Occupation { get; set; }
    public override string ToString()
    {
        return $"{this.Name} is a {this.Occupation}";
    }
}
在程序中,我们创建了自己的Object.ToString方法实现。
var u = new User("John Doe", "gardener");
Console.WriteLine(u);
当我们将用户实例传递给Console.WriteLine方法时,将调用ToString方法。
public override string ToString()
{
    return $"{this.Name} is a {this.Occupation}";
}
我们使用override关键字来覆盖方法的默认实现,该方法被声明为virtual。
$ dotnet run
User { John Doe gardener }
User { Roger Roe driver }
C#重写抽象方法
抽象类为后代类提供通用定义。必须在子类中重写抽象方法。
var c = new Circle(12, 45, 22);
Console.WriteLine(c);
Console.WriteLine($"Area of circle: {c.Area()}");
Console.WriteLine(c.GetCoordinates());
abstract class Drawing
{
    protected int x = 0;
    protected int y = 0;
    public abstract double Area();
    public string GetCoordinates()
    {
        return $"x: {x}, y: {y}";
    }
}
class Circle : Drawing
{
    private int r;
    public Circle(int x, int y, int r)
    {
        this.x = x;
        this.y = y;
        this.r = r;
    }
    public override double Area()
    {
        return this.r * this.r * Math.PI;
    }
    public override string ToString()
    {
        return $"Circle at x: {x}, y: {x}, radius: {r}";
    }
}
我们有一个抽象基类Drawing。该类定义了两个成员字段,定义了一个方法并声明了一个方法。
public abstract double Area();
Area方法是抽象的,因此必须在具体的子类中重写它。
public override double Area()
{
    return this.r * this.r * Math.PI;
}
在Circle类中,我们覆盖了Area方法并提供了它的实现。
$ dotnet run Circle at x: 12, y: 12, radius: 22 Area of circle: 1520.53084433746 x: 12, y: 45
C#重写与新
使用new关键字,我们可以显式隐藏继承的成员。当我们隐藏继承的成员时,成员的派生版本将替换基类版本。我们仍然可以通过向上转换到基类来访问原始方法。
虽然override修饰符修改原始方法(有一个方法),但new修饰符创建一个隐藏原始方法的新方法(有两个方法)。
Base[] objs = { new Base(), new Derived(), new Base() };
Console.WriteLine("-------------------------");
Console.WriteLine("Info/override");
Derived d = new Derived();
d.Info();
((Base)d).Info();
Base b = new Base();
b.Info();
Console.WriteLine("------------");
foreach (Base obj in objs)
{
    obj.Info();
}
Console.WriteLine("-------------------------");
Console.WriteLine("Info2/new");
Derived d2 = new Derived();
d2.Info2();
((Base)d).Info2();
Base b2 = new Base();
b2.Info2();
Console.WriteLine("------------");
foreach (Base obj in objs)
{
    obj.Info2();
}
class Base
{
    public virtual void Info()
    {
        Console.WriteLine("Base class");
    }
    public virtual void Info2()
    {
        Console.WriteLine("Base class");
    }
}
class Derived : Base
{
    public override void Info()
    {
        Console.WriteLine("Derived class");
    }
    public new void Info2()
    {
        Console.WriteLine("Derived class");
    }
}
我们有一个Base类和一个Derived类。有两种方法:Info和Info2。第一个使用Derived中的override关键字,第二个使用new关键字。
$ dotnet run ------------------------- Info/override Derived class Derived class Base class ------------ Base class Derived class Base class ------------------------- Info2/new Derived class Base class Base class ------------ Base class Base class Base class
在本文中,我们介绍了C#override修饰符。
列出所有C#教程。
