这是【C# 教程系列第 15 篇】,如果觉得有用的话,欢迎关注专栏。
前面几篇博客介绍了抽象类与接口,提到其中一个,很容易想到另外一个,包括搜索时自动联想的内容也是两者的区别,因为抽象类和接口在使用方法上很类似。
如果想简单看下两者区别的,这里我以 Excel 表格形式做了总结。 如果想深入了解两者区别的,可以看下方内容。
为方便理解,这里我再简述一下抽象类与接口。
抽象类:
抽象类是特殊的类,只是不能被实例化;除此以外,具有类的其他特性;
重要的是抽象类可以包括抽象方法,这是普通类所不能的。
抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。
另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们。
接口: 接口除了可以包含方法之外,还可以包含属性、索引器、事件,而且这些成员都被定义为公有的。
除此之外,不能包含任何其他的成员,例如:常量、域、构造函数、析构函数、静态成员。
相同点:
- 都可以被继承。
- 不能被实例化。
- 自身不提供实现代码。
- 派生类必须实现未实现的方法。
不同点:
- 抽象基类可以定义字段、属性、方法实现。接口只能定义属性、索引器、事件、和方法声明,不能包含字段。
- 接口可以被多重实现,抽象类只能被单一继承。
- 一个类一次可以实现若干个接口,但是只能扩展一个父类。
- 抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法默认为非虚的,不过你也可以声明为虚的。
- 抽象类实现了 OOP 中的一个原则,把可变的与不可变的分离。抽象类和接口就是定义为不可变的,而把可变的交给子类去实现。
- 好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其它方法,就叫接口污染。
下面我单独将 相同点 里的第三条(自身不提供实现代码)抽出来。因为这点对抽象类与接口来说并不完全相同。
//抽象类的定义
public abstract class Test
{
public void DoWork()
{
Debug.Log("Working");
}
public abstract int Value { get; set; }
}
//接口的定义
public interface ITest
{
void DoWork();
int value { get; set; }
}
通过上面两段代码,我们会发现以下几点差异。
- 抽象类的成员定义是带有可访问性关键字的(例如:public),而接口是不带可访问性关键字的,因为接口中所声明的成员都是公共的(隐式public),所以没有必要添加访问修饰符。
- 抽象类除了包含抽象成员外,还可以包含非抽象成员,也包括构造函数、而接口不能包含具备实现代码的成员,也不能包含构造函数。因为接口是另一种类型,不是类,而抽象类是类的一种。
你的问题得到解决了吗?欢迎在评论区留言。
赠人玫瑰,手有余香,如果觉得文章不错,希望可以给个一键三连,感谢。
结束语 技术是一点一点积累的,大神也不是一天就可以达到的。原地不动就是退步,所以每天进步一点点。 最后,附上一句格言:"好学若饥,谦卑若愚",望共勉。