ZetCode

C# 抽象类

最后修改于 2023 年 7 月 5 日

在本文中,我们将展示如何在 C# 中使用抽象类。

抽象类是一个未完成的类。它必须在其子类中实现。抽象类使用 abstract 关键字创建。我们可以创建抽象方法和成员字段。

抽象类的目的是为后代类提供一个通用的定义。

抽象类不能被实例化。如果一个类包含至少一个抽象方法,它也必须被声明为抽象类。抽象方法不能被实现;它们仅仅声明了方法的签名。当我们从一个抽象类继承时,所有抽象方法都必须由派生类实现。此外,这些方法必须以相同或更宽松的可见性声明。

接口不同,抽象类可以具有具有完整实现的方法,并且还可以具有已定义的成员字段。因此,抽象类可以提供部分实现。我们将一些通用功能放入抽象类中。

C# 抽象类示例

以下示例创建了一个抽象类。

Program.cs
var c = new Circle(12, 45, 22);

Console.WriteLine(c);
Console.WriteLine($"Area of circle: {c.Area()}");
Console.WriteLine(c.GetCoordinates());

Console.WriteLine("---------------------");

var r = new Rectangle(10, 20, 50, 60);
Console.WriteLine(r);
Console.WriteLine($"Area of rectangle: {r.Area()}");
Console.WriteLine(r.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}";
    }
}

class Rectangle : Drawing
{
    private int width;
    private int height;

    public Rectangle(int x, int y, int width, int height)
    {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    public override double Area()
    {
        return this.width * this.height;
    }

    public override string ToString()
    {
        return $"Rectangle at x: {x}, y: {y}, w: {width} h: {height}";
    }
}

我们有一个抽象基类 Drawing。该类定义了两个成员字段,定义了一个方法,并声明了一个方法。其中一个方法是抽象的,另一个方法是完全实现的。 Drawing 类是抽象的,因为我们无法绘制它。我们可以绘制一个圆、一个点或一个正方形。 Drawing 类具有一些可以绘制的对象的通用功能。

abstract class Drawing

我们使用 abstract 关键字来定义一个抽象类。

public abstract double Area();

抽象方法也以 abstract 关键字开头。

class Circle : Drawing

CircleDrawing 类的子类。它必须实现抽象的 Area 方法。

private int r;

我们声明 radius 成员字段,它是 Circle 类特有的。

public Circle(int x, int y, int r)
{
    this.x = x;
    this.y = y;
    this.r = r;
}

这是 Circle 的构造函数;它设置成员变量。 xy 变量是从 Drawing 继承的。

public override double Area()
{
    return this.r * this.r * Math.PI;
}

当我们实现 Area 方法时,我们必须使用 override 关键字。 这样,我们通知编译器,我们正在重写一个现有的(继承的)方法。

class Rectangle : Drawing

另一个具体的形状是 Rectangle

private int width;
private int height;

Rectangle 定义了两个变量:widthheight

public override double Area()
{
    return this.width * this.height;
}

Rectangle 提供了 Area 方法的自己的实现。

$ dotnet run
Circle at x: 12, y: 12, radius: 22
Area of circle: 1520.53084433746
x: 12, y: 45
---------------------
Rectangle at x: 10, y: 20, w: 50 h: 60
Area of rectangle: 3000
x: 10, y: 20

来源

抽象和密封类以及类成员

在本文中,我们使用了 C# 中的抽象类。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。 我从 2007 年开始撰写编程文章。 迄今为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 C# 教程