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;
//
// ... (其他成员)
//
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;
//
// ... (其他成员)
//
public abstract void Draw(Graphics g);
public double X { get { return _x; } }
public double Y { get { return _y; } }
}
尽管抽象类与非抽象类类似,但也存在一些重要的区别。首先,不能使用 new
关键字创建抽象类的实例。例如,下面的语句会引发编译错误:
AbstractShape shape = new AbstractShape(); // 错误
当然,假设具体类 Square
从 AbstractShape
派生,那么下面的代码是正确的:
AbstractShape shape = new Square(); // 正确
第二个区别是,抽象类可以有抽象成员。如上所示,这并不是必须的。为了创建一个至少有一个抽象成员的类,必须在类关键字之前添加 abstract
关键字。
第三个区别是,一个类不能同时是抽象的和密封的(sealed)。这意味着,如果类是抽象的,则不能使用 sealed
修饰符。
实现方法
与虚方法一样,你可以使用 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
。唯一的区别是,如果方法所在的类继承自抽象类,且忘记使用 new
或 override
关键字,则会引发错误;如果类尝试重写虚方法,则会引发警告。
最后修改: 2025年01月11日 星期六 23:56