为何C#中接口需显式实现成员,抽象类却支持后台继承?
为什么C#里接口必须手动实现成员,抽象类却不用?
这个问题问到点子上了——其实本质是接口和抽象类在C#里的设计定位完全不同,咱们一步步拆解:
接口是「契约」,只定义规则不提供实现
接口的核心作用是约定:「任何实现我的类,必须具备这些成员」。它本身不包含任何可执行的代码逻辑(哪怕C# 8+支持默认实现,那也是补充机制,核心契约属性没变)。
比如你给出的IBar接口,它只是告诉编译器:“所有实现IBar的类,必须有MemberA和MemberB这两个属性”。当Foo2实现IBar却没写这两个属性时,编译器就会报错——因为你违反了契约,没完成约定的义务。抽象类是「部分实现的基类」,自带可继承的代码
抽象类的定位是给子类提供共享的代码和模板,它可以包含已经实现好的成员。你给出的Bar抽象类里的MemberA和MemberB是自动属性,C#会自动生成默认的get/set逻辑,这些逻辑是可以被子类继承的。
所以Foo1继承Bar时,直接就拿到了这两个属性的实现,不需要自己再写——这正是抽象类“减少重复代码”的设计初衷。
举个更直白的例子:
- 接口像一份合同,签了字就得按条款干活,没人替你干;
- 抽象类像一个已经搭好部分框架的房子,子类直接住进去就行,不用再重新砌墙。
再看你给出的代码验证:
正确运行的继承抽象类代码:
public abstract class Bar { public int MemberA {get;set;} public string MemberB {get;set;} } public class Foo1 : Bar { } // 直接继承已实现的成员,没问题
触发编译错误的实现接口代码:
public interface IBar { public int MemberA {get;set;} public string MemberB {get;set;} } public class Foo2 : IBar { } // 没实现接口约定的成员,违反契约报错
补充一句:C# 8之后接口可以加默认实现,但别搞混——默认实现不会被子类继承为自身的成员,子类如果不重写,只能通过接口类型调用,本质还是没打破“接口是契约”的核心逻辑。
内容的提问来源于stack exchange,提问作者Eduardo Pignatelli
相关产品推荐
相关产品推荐

