每次更新之后我都会思考,.NET里接口(Interface)和抽象类(Abstract Class)这两个东西到底有什么不同?到底哪个更适合实际的项目开发?毕竟大家在做设计的时候都得选一个,搞明白区别很重要。 它们俩的核心都在于帮助我们实现抽象的设计理念,让开发者能按照规范写出多态的代码。但这里面门道挺深。接口这东西主要是用来规定行为的,它里面一般只列方法、属性和事件这些成员,不会直接把代码写死(不过现在C#新特性里允许默认实现了)。一个类能实现多个接口,这就很方便实现能力型设计,比如像ILogger、IDisposable这种大家熟悉的接口。 抽象类就不一样了,它更偏向于代码复用和搭建基础结构。抽象类不光能放字段和构造函数,还能有现成的具体方法和没写实现的抽象方法。子类继承了它以后,能直接复用已经写好的代码,只用补上那些抽象方法就行。 核心的不同点其实很直观:继承数量上,类只能单继承一个抽象类,但可以实现多个接口;成员实现方面,抽象类里可以有具体逻辑,接口通常只是定规范;设计目标上,接口是定义能力用的,抽象类是搞基础结构用的。 开发时咱们得根据实际情况来选。如果你想让好几个没什么直接关系的类都有某种能力(比如写日志、序列化),就用接口;要是多个类在逻辑上是一家人(比如都属于某个大家族),那就用抽象类来体现这种继承关系。 很多公司特别喜欢搞“面向接口编程”,这其实是为了把系统耦合度降下来。只要依赖的是接口而不是具体的类,以后想换个实现方式就容易多了。比如说现在用文件存日志,哪天想换成数据库或者云存,根本不用动太多业务逻辑。 另外这对测试也有好处。在写单元测试的时候,用Mock或者Fake替换掉真实依赖就能把外面的影响隔离开来。现在主流的.NET架构像依赖注入(DI)也特别倚重接口设计,所以面向接口编程已经成了企业开发里的标配。 当然也不是所有时候都非得用接口。要是系统里有明确的继承关系,大家都要共享一堆代码,这时候用抽象类可能更划算。因为接口本身不带逻辑实现,乱用容易导致代码重复。 还有个问题要注意,接口设计太细、太杂也容易把系统搞得太复杂。一个类实现太多接口会让人看蒙圈。所以在设计的时候一定要把握好度,既要留好扩展的口子,也别弄得太过火了。