接口和抽象类之间到底有什么区别?
当前回答
当您想在继承层次结构中提供多态行为时,请使用抽象类。
当您想要完全无关的类的多态行为时,请使用接口。
其他回答
实际上并不是最初问题的答案,但一旦你找到了它们之间的区别的答案,你就会进入何时使用每一个困境:何时使用接口或抽象类?何时同时使用两者?
我对OOP的了解有限,但将接口视为语法中形容词的等价物对我来说一直有效(如果这个方法是假的,请纠正我!)。例如,接口名称类似于可以赋予类的属性或功能,并且类可以具有许多属性或功能:ISerializable、ICountable、IList、ICacheable、IHappy。。。
抽象类和接口之间的关键技术差异是:
抽象类可以有常量、成员、方法存根(没有主体的方法)和定义的方法,而接口只能有常量和方法存根。抽象类的方法和成员可以以任何可见性定义,而接口的所有方法都必须定义为public(默认情况下定义为public)。继承抽象类时,具体的子类必须定义抽象方法,而抽象类可以扩展另一个抽象类,父类的抽象方法不必定义。类似地,扩展另一个接口的接口不负责从父接口实现方法。这是因为接口不能定义任何实现。子类只能扩展一个类(抽象或具体),而接口可以扩展或类可以实现多个其他接口。子类可以定义具有相同或更少限制性可见性的抽象方法,而实现接口的类必须定义具有完全相同可见性(公共)的方法。
在实用性方面(JAVA),抽象类和接口之间的主要区别是抽象类可以保存状态。除了保持状态,我们还可以使用Interface实现其余操作。
之所以调用接口,是因为它向调用方(例如COM客户端)提供了由某个类实现的方法接口。通过将一个对象指针以多态的方式投射到对象类实现的接口的类型,它限制对象对其实现的接口中的函数和成员的访问,与coclass可能实现的其他COM接口分离。客户端不需要知道什么类实现了接口,或者该类中存在什么其他方法;对象以它所知道的接口实例的形式呈现(其中类的实例已被多态地转换为接口实例,该接口实例是类的子实例),它只是通过调用接口实例上的接口方法来使用接口。实际实现的所有细节和不同接口实现的无关功能/细节都与调用方期望的接口分离——调用方只使用它与对象的接口(接口实例及其作为对象一部分的虚拟表指针),并且调用底层对象实现,而调用者不必知道实现的位置或细节。通过接口(接口类型的指针)访问对象是一种封装形式,在语法上防止未经授权访问对象,并隐藏实现细节和其他与接口及其定义的个性无关的功能。
接口是所有方法都是虚拟和抽象的(抽象在C++中称为纯虚拟;所有抽象方法都包含虚拟说明符,因此是虚拟的)。抽象类是指至少有一个方法是虚拟的,并指定为抽象的(或C++中的纯虚拟)。其他细节因语言而异。所有的接口属性在java中都是隐式的公共静态final,但在C++中不是。Java允许在抽象类中使用非静态属性,但C++允许在两者中使用它们。两种语言中的属性都不能是虚拟/抽象的。
要点是:
抽象是面向对象的。它提供了一个“对象”应该具有的基本数据和/或它应该能够执行的功能。它关注对象的基本特性:它具有什么和它可以做什么。因此,从同一抽象类继承的对象共享基本特性(泛化)。接口是面向功能的。它定义了对象应该具有的功能。不管它是什么对象,只要它可以执行界面中定义的这些功能,就可以了。它忽略了其他一切。一个对象/类可以包含几个(组)功能;因此,类可以实现多个接口。
推荐文章
- 如何在方法中访问“静态”类变量?
- 为什么c#不提供c++风格的'friend'关键字?
- String, StringBuffer和StringBuilder
- 如何在python抽象类中创建抽象属性?
- 存储库和服务层的区别?
- DDD -实体不能直接访问存储库的规则
- 为什么STL如此严重地基于模板而不是继承?
- 如何在Objective-C中声明类级属性?
- 面向方面编程与面向对象编程
- c++中类似于java的instanceof
- 在python中遍历对象属性
- 将类代码分离为头文件和cpp文件
- 在PHP中使用getter和setter而不是函数或简单的公共字段有什么优点?
- 基于原型的继承与基于类的继承
- 如何在Java中找到给定类的所有子类?