跳转到内容

C# 编程/抽象类

来自维基教科书,自由的教科书

一般来说,接口是组件的公共成员集。当然,这对 C# 接口 也是如此。C# 类也定义了一个接口,因为它有一组公共成员。非抽象 C# 类定义了每个成员的实现。

在 C# 中,可以拥有介于不定义任何实现的纯接口和定义完整实现的类型之间的类型。这称为抽象类,通过在类定义中包含 abstract 关键字来定义。

抽象类介于 C# 接口和非抽象类之间。在抽象类定义的公共成员中,任何数量的这些成员都可以包含实现。

例如,抽象类可能为所有成员提供实现。

public abstract class AbstractShape
{
    public abstract void Draw(Graphics g);
    public abstract double X {get; set;}
    public abstract double Y {get; set;}
}

从许多方面来说,此类等效于接口。(一个区别是,从该类派生的类不能从任何其他类派生。)

抽象类也可以定义所有成员。

public abstract class AbstractShape
{
    private double _x;
    private double _y;
    //
    // ... (other members)
    //
    public void Draw(Graphics g) {g.DrawRectangle(Pens.Black, g_rect);}
    public double X {get{return _x;}}
    public double Y {get{return _y;}}
}

抽象类还可以定义一些成员,但留下其他成员未定义。

public abstract class AbstractShape
{
    private double _x;
    private double _y;
    //
    // ... (other members)
    //
    public abstract void Draw(Graphics g);
    public double X {get{return _x;}}
    public double Y {get{return _y;}}
}

虽然抽象类类似于非抽象类,但存在一些重要的区别。首先,您不能使用 new 关键字创建抽象类的实例。例如,以下语句将引发编译器错误

AbstractShape shape = new AbstractShape();

当然,假设具体类 SquareAbstractShape 派生,则以下将是正确的

AbstractShape shape = new Square();

第二个区别是抽象类可能具有抽象成员。如上所示,这不是必需的。要创建至少具有一个抽象成员的类,必须在 class 关键字之前添加 abstract 关键字。

第三个区别是类不能同时是 abstractsealed

实现方法

[编辑 | 编辑源代码]

与虚方法一样,您可以使用 override 关键字实现抽象方法或属性

public class Rectangle : AbstractShape
{
    private double _x;
    private double _y;
    // ...
    public override void Draw(Graphics g)
    {
        g.DrawRectangle(Pens.Black, g_rect);
    }

    public override double X {
        get { return _x; }
        set { _x = value; }
    }

    public override double Y {
        get { return _y; }
        set { _y = value; }
    }
}

覆盖抽象方法与覆盖虚方法实际上相同 - 您不能更改访问说明符(即您不能将受保护的抽象方法转换为公共方法),并且您不能向抽象属性添加丢失的 get 或 set。唯一的区别是,如果您忘记了 newoverride 关键字,则会产生错误,如果该方法所属的类是从抽象类派生的,并且如果该类尝试覆盖虚方法,则会产生警告。

华夏公益教科书