abstract 修饰符可以和类、方法、属性、索引器及事件一起使用。在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。
抽象类具有以下特性:
抽象类不能实例化。
抽象类可以包含抽象方法和抽象访问器。
通过使用 virtual 关键字,可以将事件标记为虚拟事件。这样,派生类就可以通过使用 override 关键字来重写事件行为。有关更多信息,请参见继承(C# 编程指南)。重写虚事件的事件也可以为 sealed,以表示其对于派生类不再是虚事件。最后,可以将事件声明为 abstract,这意味着编译器不会生成 add 和 remove 事件访问器块。因此派生类必须提供其自己的实现。
因为抽象方法声明不提供实际的实现,所以没有方法体;方法声明只是以一个分号结束,并且在签名后没有大括号 ({ })。例如:
复制代码
public abstract void MyMethod();
实现由一个重写方法override(C# 参考)提供,此重写方法是非抽象类的一个成员。
复制代码
// abstract_keyword.cs
// Abstract Classes
using System;
abstract class BaseClass // Abstract class
{
protected int _x = 100;
protected int _y = 150;
public abstract void AbstractMethod(); // Abstract method
public abstract int X { get; }
public abstract int Y { get; }
}
class DerivedClass : BaseClass
不能用 sealed(C# 参考)修饰符修改抽象类,这意味着抽象类不能被继承。
从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。
在方法或属性声明中使用 abstract 修饰符以指示方法或属性不包含实现。
抽象方法具有以下特性:
抽象方法是隐式的虚方法。
只允许在抽象类中使用抽象方法声明。
实现接口的抽象类可以将接口方法映射到抽象方法上。例如:
复制代码
interface I
{
void M();
}
abstract class C: I
{
public abstract void M();
}
示例
在本例中,DerivedClass 类是从抽象类 BaseClass 派生的。抽象类包含一个抽象方法 AbstractMethod 和两个抽象属性 X 和 Y。
复制代码
public struct Book
{
public decimal price;
public string title;
public string author;
}
备注
结构还可以包含构造函数、常量、字段、方法、属性、索引器、运算符、事件和嵌套类型,但如果同时需要上述几种成员,则应当考虑改为使用类作为类型。
{
return _x + 10;
}
}
public override int Y // overriding property
{
get
{
return _y + 10;
class Class2
{
}
class MainClass
{
static void Main()
{
object[] objArray = new object[6];
objArray[0] = new Class1();
objArray[1] = new Class2();
}
}
复制代码
x = 111, y = 161
注释
在上面的示例中,如果试图通过使用下面的语句将抽象类实例化:
复制代码
BaseClass bc = new BaseClass(); // Error
将出现错误,指出编译器无法创建抽象类“BaseClass”
objArray[2] = "hello";
objArray[3] = 123;
objArray[4] = 123.4;
objArray[5] = null;
for (int i = 0; i < objArray.Length; ++i)
// Declare the event.
public event SampleEventHandler SampleEvent;
// Wrap the event in a protected virtual method
// to enable derived classes to raise the event.
注意,as 运算符只执行引用转换和装箱转换。as 运算符无法执行其他转换,如用户定义的转换,这类转换应使用强制转换表达式来执行。
示例
复制代码
// cs_keyword_as.cs
// The as operator.
using System;
class Class1
{
}
复制代码
public class Publisher
{
// Declare the delegate (if using non-generic pattern).
public delegate void SampleEventHandler(object sender, SampleEventArgs e);
在抽象方法声明中使用 static 或 virtual 修饰符是错误的。
除了在声明和调用语法上不同外,抽象属性的行为与抽象方法一样。
在静态属性上使用 abstract 修饰符是错误的。
在派生类中,通过包括使用 override 修饰符的属性声明,可以重写抽象的继承属性。
抽象类必须为所有接口成员提供实现。
结构可以实现接口,但它们无法继承另一个结构。因此,结构成员无法声明为 protected。
as 运算符用于在兼容的引用类型之间执行转换。例如:
复制代码
string s = someObject as string;
if (s != null)
{
// someObject is a string.
在 C# 中,new 关键字可用作运算符、修饰符或约束。
new 运算符
用于创建对象和调用构造函数。
new 修饰符
用于向基类成员隐藏继承成员。
new 约束
用于在泛型声明中约束可能用作类型参数的参数的类型。
struct 类型是一种值类型,通常用来封装小型相关变量组,例如,矩形的坐标或库存商品的特征。下面的示例显示了一个简单的结构声明。
}
备注
as 运算符类似于强制转换操作。但是,如果无法进行转换,则 as 返回 null 而非引发异常。请看下面的表达式:
复制代码
expression as type
它等效于以下表达式,但只计算一次 expression。
复制代码
expression is type ? (type)expression : (type)null
event 关键字用于在发行者类中声明事件。
备注
下面的示例演示如何声明和引发将 EventHandler 用作基础委托类型的事件。有关演示如何使用泛型 EventHandler<(Of <(TEventArgs>)>) 委托类型、如何订阅事件以及如何创建事件处理程序方法的完整代码示例,请参见如何:发布符合 .NET Framework 准则的事件(C# 编程指南)。
sealed
指定对于派生类它不再属虚拟性质。
abstract
编译器不会生成 add 和 remove 事件访问器块,因此派生类必须提供自己的实现。
通过使用 static 关键字,可以将事件声明为静态事件。即使类没有任何实例,调用方也能在任何时候使用静态事件。有关更多信息,请参见静态类和静态类成员(C# 编程指南)。
{
string s = objArray[i] as string;
Console.Write("{0}:", i);
if (s != null)
{
Console.WriteLine("'" + s + "'");
}
}
static void Main()
{
DerivedClass o = new DerivedClass();
o.AbstractMethod();
Console.WriteLine("x = {0}, y = {1}", o.X, o.Y);
C# 关键字
关键字是对编译器具有特殊意义的预定义保留标识符。它们不能在程序中用作标识符,除非它们有一个 @ 前缀。例如,@if 是有效的标识符,但 if 不是,因为 if 是关键字。
本主题中的第一个表列出的关键字在 C# 程序的任何部分都是保留标识符。本主题中的第二个表列出了 C# 中的上下文关键字。上下文关键字仅在受限制的程序上下文中具有特殊含义,并且可在该上下文外部用作标识符。通常,在将新关键字添加到 C# 语言的同时,也会将它们添加为上下文关键字,以便避免破坏用该语言的早期版本编写的程序。