抽象类和接口的区别

看了这篇文章有所收获,可是有些地方了解的不是很完全,留着学习!
html

在开发人员岗位面试时,是否了解抽象类和接口之间的基本区别是一个很重要的考量因素。程序员

显而易见?

彻底不是。笔者面试过不少人,一般问的第一个问题是关于接口和抽象类的区别。但实际上不多有程序员能给出正确的答案。面试

就这个问题来讲,初级程序员可能都会清楚之间的区别,可能也并不必定理解其背后的缘由,但其结构上的差别,特别是针对特定语言(几乎和全部的面向对象的语言同样)应该深刻了解。函数

同时,笔者也发现其余职位候选人(有时甚至是高级职位)居然也不知道这之间的差别,或者只知道的一个或几个。学习

若是只是须要了解这些内容那并不难,但这些都是面向对象的基础知识,所以想要设计良好的代码必须对其有一个深刻的认识。spa

下面将详细介绍这些基础知识。设计

继承

下面将从众所周知的接口和抽象类的区别开始。这种差别是关于继承的,任何类均可以实现多个接口,可是只能扩展一个类,也只能有一个父类。htm

多个类扩展是一个语言特性,它存在于一些面向对象的语言。为何呢?由于它带来的问题每每多于价值。对象

当一个类有许多父类时,有一个状况就是彻底相同的方法会声明多个,所以必须显式地“告知”究竟须要的是哪个。继承

这样的代码一般难以维护,由于对其进行的任何修改或者重构都必须当心地检查。另外一方面,若是一个类须要扩展(至少)两个拥有相同方法的类,那么DRY规则显然会被破坏(所以须要从别处下手),或者说会干扰到Single Responsibility Principle(SAP)。

“若是多个类的继承如此糟糕,为何它能够实现许多接口呢?”——若是这样的问题在你的脑海盘旋,我不得不认可这是一个绝妙的问题。

然而,答案很简单。每个接口都是基于函数而不是一个类去实现。因此,即便实现十个不一样的接口,每一个包含相同的方法声明,内部也不会发生冲突。接口保证了方法的存在,而不是去说明方法的实现,这意味着,只要不违反SRP,你彻底能够实现多个接口。

方法的可见度

接口中的全部方法都是public的,但对于抽象类的声明并无这样的规则,固然不能是private。为何不能private?由于一个抽象方法须要在子类中实现,但private没法访问子类,所以不抽象类不可能存在private属性。

接着回归主题。正如上文写道的,接口是一个函数的保证,你能够把它看成使用接口的类和实现这个接口的类之间的一个合约——保证一个特定类将实现全部声明的方法。这也是为何这些方法必须是public的缘由。由于被严格的限制到了实现上,因此其余一切都不成问题。

然而,当涉及到抽象类时并不是这样。咱们老是能够有不一样的类组,除了这几方面基本上不一样之外,其余地方几乎同样,类体的公共方法也是很是类似的。在这种状况下,能够建立protected方法来保持类之间的差别。Template Method就是一个很典型的例子。

声明和定义

接口只能包含方法声明,而抽象类还能够包含方法的定义。

接口的重点在于提供特定函数,而抽象类还在于子类实现的类似性,不只仅是其中的函数。

常量

接口和抽象类中均可以定义常量。这是由于这些值不依赖于特定对象,对它们来讲都是相同的。

属性

抽象类能够包含属性,但接口却不能。缘由与声明和定义是同样的。

总结

除了说明差别,笔者也试图解释它产生的缘由。这不只是由于人们发明某个语言时的突发奇想,而是源于语言背后所支撑的理念。

原文连接: Differences Between Abstract Class and Interface (译者/ OneAPM工程师 责编/仲浩)