发布于2026-07-18 阅读(0)
扫一扫,手机访问
抽象类在C#中的地位有些特殊——它不能直接实例化,只允许被继承。换句话说,只要一个类里出现了abstract标识的方法,这个类就必须声明为abstract class,否则编译器会直接报错。这可不是什么小细节,而是整个抽象机制的设计起点。
先搞清楚一个基本规则:abstract class是不能用new来创建实例的。想试试new Animal()?编译器会直接甩你一脸CS0144:“无法创建抽象类的实例”。抽象类存在唯一的意义,就是作为基类被继承。它允许你定义一部分可复用的逻辑(比如Sleep()),同时强制子类实现关键行为(比如MakeSound())。
具体来说,抽象类有几个值得注意的特性:
base())protected或internal成员sealed修饰抽象类——这俩语义冲突:一个要求必须被继承,一个禁止被继承抽象方法的声明形式是public abstract void Run();,结尾是分号,没有{}。它不提供任何实现,只划出契约边界。一旦父类中存在这样的方法,所有非抽象子类都必须用override显式实现它。
这里有几点必须注意:
private——子类根本访问不到,还怎么重写?static或virtual——abstract已隐含virtual语义,二者重复;static属于类型而非实例,和“由子类实现”的设计目标矛盾protected,但不推荐:外部无法通过变量调用,削弱了多态价值这是个经典问题。当你要共享代码实现、需要字段或构造逻辑、或者想约束继承链深度(只能单继承)时,优先考虑抽象类。举个例子,所有Shape都要记录CreatedTime字段,都有默认的ToString()实现,但面积计算必须由子类决定——这种场景抽象类再合适不过。
对比来看:
IComparable、IDisposable),抽象类更适合定义“是什么+部分怎么做”(Stream、Exception): Animal, IFlyable, ISwimmable,但只能: Mammal——继承结构越清晰,越该用抽象类做骨架很多人在这里卡壳。比如abstract class Logger完全可以不写任何abstract方法,只提供通用日志格式化逻辑,并用abstract修饰自身来防止被误实例化。编译器只检查“有没有abstract成员”来决定是否强制子类实现,不检查“有没有abstract方法”。
还有几点补充:
abstract方法,类就必须是abstract——没得商量abstract,但它可以是protected,这是最常见也最合理的做法
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8