abstract
修饰符可以和类、方法、属性、索引器及事件一起使用,表示抽象的意思。在类声明中使用abstract修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。
- abstract修饰类,表示抽象类
抽象类有以下特征:
- 不能实例化
- 抽象类可以包含抽象的方法、属性、索引器及事件。但是抽象类也可以包含非抽象成员。
- 派生自抽象类的类必须实现抽象类的所有抽象成员。
- abstract修饰方法、属性、索引器及事件(这里我们以抽象方法来讲解,抽象属性、索引器及事件类似)。
抽象方法具有以下特征:
- 抽象方法是隐式的虚方法,但它与虚方法不同,虚方法在派生类既可以用override进行重写,也可以不重写。但是抽象方法在派生类中是必须用override来进行重写的。
- 只允许在抽象类中使用抽象方法声明。
- 抽象方法是一个未做任何实现的方法,只有方法声明。
下面我们通过一个例子来看看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | /// <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" ); } } |
输出结果:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)