abstract
修饰符可以和类、方法、属性、索引器及事件一起使用,表示抽象的意思。在类声明中使用abstract修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。
- abstract修饰类,表示抽象类
抽象类有以下特征:
- 不能实例化
- 抽象类可以包含抽象的方法、属性、索引器及事件。但是抽象类也可以包含非抽象成员。
- 派生自抽象类的类必须实现抽象类的所有抽象成员。
- abstract修饰方法、属性、索引器及事件(这里我们以抽象方法来讲解,抽象属性、索引器及事件类似)。
抽象方法具有以下特征:
- 抽象方法是隐式的虚方法,但它与虚方法不同,虚方法在派生类既可以用override进行重写,也可以不重写。但是抽象方法在派生类中是必须用override来进行重写的。
- 只允许在抽象类中使用抽象方法声明。
- 抽象方法是一个未做任何实现的方法,只有方法声明。
下面我们通过一个例子来看看:
/// <summary> /// 抽象类,既可以包含抽象成员,也可以包含非抽象成员 /// 抽象成员只能声明在抽象类中 /// </summary> public abstract class BaseClass { protected Int32 _x; protected Int32 _y; //委托声明 public delegate void GetResultHandler(Object sender, EventArgs e); //抽象事件 public abstract event GetResultHandler GetResultEvent; // 抽象属性 public abstract Int32 X { get; set; } public abstract Int32 Y { get; set; } // 抽象索引器 public abstract String this[Int32 i] { get; set; } // 抽象方法 public abstract void AbstractMethod(); // 非抽象方法 public void PrintMessage() { Console.WriteLine("Non-abstract method"); } } public class DerivedClass : BaseClass { private readonly List<String> _dataList = new List<String>() { "", "", "", "", "", "", "", "", "", "", "", "" }; // 实现抽象事件 public override event GetResultHandler GetResultEvent; // 实现抽象属性 public override Int32 X { get { return _x; } set { _x = value; } } public override Int32 Y { get { return _y; } set { _y = value; } } // 实现抽象索引器 public override String this[Int32 i] { get { if (i < 0 || i >= _dataList.Count) return String.Empty; return _dataList[i]; } set { if (i < 0 || i >= _dataList.Count) return; _dataList[i] = value; } } // 实现抽象方法 public override void AbstractMethod() { Console.WriteLine("Abstract method"); } public void GetResultMessage() { Console.WriteLine(_x + _y); if (GetResultEvent != null) { GetResultEvent(this, EventArgs.Empty); } } } public class Program { static void Main() { // 下面语句试图对抽象类BaseClass实例化,将出现错误 // BaseClass baseClass = new BaseClass(); DerivedClass derivedClass = new DerivedClass(); //注册GetResultEvent事件 derivedClass.GetResultEvent += new BaseClass.GetResultHandler(DerivedClassGetResultEvent); derivedClass.AbstractMethod(); derivedClass.PrintMessage(); derivedClass.GetResultMessage(); for (Int32 i = 0; i < 10; i++) { derivedClass[i] = String.Format("Derived_{0}", i); } for (Int32 i = 0; i < 10; i++) { Console.Write(String.Format("{0}\t", derivedClass[i])); } Console.WriteLine(); derivedClass.X = 123; derivedClass.Y = 32; Console.WriteLine("x = {0}, y = {1}", derivedClass.X, derivedClass.Y); } static void DerivedClassGetResultEvent(Object sender, EventArgs e) { Console.WriteLine("Received event notice"); } }
输出结果: