abstract类不能直接new实例,因其含未实现的抽象成员(如抽象方法),编译器在编译期强制禁止实例化以确保继承体系完整性与多态性。
类不能直接 new 实例,这是最常踩的坑——编译器会立刻报错
。它不是“高级版普通类”,而是设计用来被继承的契约骨架。
为什么 new 不了
类?
因为
类里可能有没实现的成员,比如
方法或属性。C# 要求所有非抽象子类必须补全这些空缺,否则连编译都过不去。
哪怕类里只有一个
方法,整个类自动变成
,且不可实例化
类可以有构造函数,但只能被子类的
调用,不能手动 new
误写
会触发编译错误,不是运行时异常
方法必须用
实现
子类实现抽象成员时,必须显式加
,不能只写方法签名。漏掉
会导致编译失败,提示
或
。
抽象方法声明末尾是分号,没有大括号:
子类实现必须带
,访问修饰符不能比父类更严格(如父类
,子类不能写
)
不能在抽象方法上加
、
或
—— 编译器直接拒绝
接口和
类混用时的常见陷阱
当一个
类实现接口(如
),它可以不提供接口方法的具体实现,而是把责任推给子类——只要把接口方法也声明为
即可。
C知道
CSDN推出的一款AI技术问答工具
下载
例如:
这样子类只需实现一次
,就同时满足接口契约和抽象类约束
但如果子类忘了实现,错误信息可能指向接口而非抽象类,容易误判源头
注意:抽象类必须“声明”所有接口成员,哪怕只是用
转发过去;否则编译报错
别把
和
放在一起
这两个关键字语义冲突,C# 禁止同时使用。试图写
会得到编译错误
。
的核心诉求是“必须被继承”,
的核心诉求是“禁止被继承”
如果想阻止进一步派生,应该让子类用
,而不是污染抽象基类
抽象类里的方法默认是隐式
,所以子类能
;不需要、也不允许显式加
真正难的不是语法,而是判断哪些逻辑该放进抽象层、哪些留给子类决定。比如
可以是抽象的,但通用日志记录或参数校验往往适合放在抽象类的非抽象方法里——这部分容易被忽略,结果导致重复代码或行为不一致。
abstractCannot create an instance of the abstract class or interfaceabstractabstractabstractabstractabstractabstract: base(...)new MyBaseClass()abstractoverrideoverrideoverrideNo suitable method found to overrideMember must have 'override' keywordpublic abstract int Area();public override int Area() { ... }publicprotectedstaticvirtualsealedabstractabstractIComparableabstractabstract class Shape : IComparable { public abstract int CompareTo(object obj); }CompareToabstract'X' does not implement interface member 'Y'abstractsealedsealed abstract class Cerror CS0418: 'C': an abstract class cannot be sealed or staticabstractsealedsealedvirtualoverridevirtualDraw()