接口和抽象类之间到底有什么区别?
当前回答
我们在接口和抽象类之间存在各种结构/语法差异。还有一些不同之处
[1] 基于场景的差异:
当我们希望限制用户创建父类的对象时,抽象类被用于场景中,并且我们相信将来还会添加更多的抽象方法。
当我们确信不能提供更多抽象方法时,必须使用接口。然后只发布一个接口。
[2] 概念差异:
“我们是否需要在未来提供更多抽象方法”,如果是,则将其设为抽象类,如果否,则设为接口。
(在java 1.7之前最合适和有效)
其他回答
接口
接口是一个契约:编写接口的人说,“嘿,我接受这样的东西”,而使用接口的人则说“好的,我编写的类是这样的”。
接口是一个空壳。只有方法的签名,这意味着方法没有主体。接口无法执行任何操作。这只是一种模式。
例如(伪代码):
// I say all motor vehicles should look like this:
interface MotorVehicle
{
void run();
int getFuel();
}
// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{
int fuel;
void run()
{
print("Wrroooooooom");
}
int getFuel()
{
return this.fuel;
}
}
实现一个接口只消耗很少的CPU,因为它不是一个类,只是一堆名称,因此不需要进行任何昂贵的查找。在重要的时候,比如在嵌入式设备中,这是非常棒的。
抽象类
与接口不同,抽象类是类。它们的使用成本更高,因为从它们继承时需要进行查找。
抽象类看起来很像接口,但它们有更多:您可以为它们定义行为。这更像是一个人说,“这些课程应该看起来像那样,而且它们有共同点,所以填空吧!”。
例如:
// I say all motor vehicles should look like this:
abstract class MotorVehicle
{
int fuel;
// They ALL have fuel, so lets implement this for everybody.
int getFuel()
{
return this.fuel;
}
// That can be very different, force them to provide their
// own implementation.
abstract void run();
}
// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
void run()
{
print("Wrroooooooom");
}
}
实施
虽然抽象类和接口被认为是不同的概念,但实现有时会使该语句不真实。有时,他们甚至不是你想象的那样。
在Java中,这个规则是强制执行的,而在PHP中,接口是没有声明方法的抽象类。
在Python中,抽象类更多地是一种编程技巧,您可以从ABC模块中获得,并且实际上使用元类,因此使用类。接口与这种语言中的duck类型更为相关,它混合了约定和调用描述符的特殊方法(__method__方法)。
与编程一样,还有另一种语言的理论、实践和实践:-)
抽象类是无法创建对象的类或无法实例化的类。抽象方法使类抽象。抽象类需要被继承,以便覆盖在抽象类中声明的方法。对访问说明符没有限制。抽象类中可以有构造函数和其他具体(非abstract方法)方法,但接口不能有。
接口是方法的蓝图/模板。(例如,在纸上给出一个房子(接口房子),不同的建筑师将使用他们的想法来建造它(实现房子接口的建筑师的类别)。它是抽象方法、默认方法、静态方法、最终变量和嵌套类的集合。所有成员都将是最终成员或公共成员,不允许使用受保护和私有访问说明符。不允许创建对象。必须创建一个类,以便使用实现接口并重写接口中声明的抽象方法。接口是松散耦合(动态多态性/动态绑定)的一个很好的例子接口实现了多态性和抽象。它告诉要做什么,但如何做由实现类定义。例如,有一家汽车公司希望其制造的所有汽车的某些功能都相同,因此该公司将制造一种具有这些功能的接口车辆,而不同级别的汽车(如Maruti Suzkhi、Maruti 800)将覆盖这些功能。
当我们已经有抽象类时,为什么要接口?Java只支持多级和分层继承,但借助于接口,我们可以实现多重继承。
之所以调用接口,是因为它向调用方(例如COM客户端)提供了由某个类实现的方法接口。通过将一个对象指针以多态的方式投射到对象类实现的接口的类型,它限制对象对其实现的接口中的函数和成员的访问,与coclass可能实现的其他COM接口分离。客户端不需要知道什么类实现了接口,或者该类中存在什么其他方法;对象以它所知道的接口实例的形式呈现(其中类的实例已被多态地转换为接口实例,该接口实例是类的子实例),它只是通过调用接口实例上的接口方法来使用接口。实际实现的所有细节和不同接口实现的无关功能/细节都与调用方期望的接口分离——调用方只使用它与对象的接口(接口实例及其作为对象一部分的虚拟表指针),并且调用底层对象实现,而调用者不必知道实现的位置或细节。通过接口(接口类型的指针)访问对象是一种封装形式,在语法上防止未经授权访问对象,并隐藏实现细节和其他与接口及其定义的个性无关的功能。
接口是所有方法都是虚拟和抽象的(抽象在C++中称为纯虚拟;所有抽象方法都包含虚拟说明符,因此是虚拟的)。抽象类是指至少有一个方法是虚拟的,并指定为抽象的(或C++中的纯虚拟)。其他细节因语言而异。所有的接口属性在java中都是隐式的公共静态final,但在C++中不是。Java允许在抽象类中使用非静态属性,但C++允许在两者中使用它们。两种语言中的属性都不能是虚拟/抽象的。
我正在建造一座300层的大楼
建筑的蓝图界面
例如,Servlet(I)
建筑高达200层-部分完工-摘要
部分实现,例如泛型和HTTPservlet
建筑施工完成混凝土
完整实现,例如,自己的servlet
界面
我们对实现一无所知,只知道需求。我们可以去找一个接口。默认情况下,每个方法都是公共的和抽象的这是一个100%纯抽象类如果我们宣布公开,我们就不能宣布隐私和受保护如果我们声明抽象,我们就不能声明final、static、synchronized、strictfp和native每个接口都有公共的、静态的和最终的序列化和瞬态不适用,因为我们无法在接口中创建实例非挥发性,因为它是最终的每个变量都是静态的当我们在接口内声明变量时,我们需要在声明不允许实例和静态块
摘要
部分实施它有一个抽象的方法。此外,它使用混凝土对抽象类方法修饰符没有限制抽象类变量修饰符没有限制除了abstract,我们不能声明其他修饰符初始化变量没有限制
摘自DurgaJobs网站
php.net上抽象类和接口的简单而有效的解释:
接口就像一个协议。它不指定对象的行为;它指定代码如何告诉该对象的动作。接口类似于英语:定义接口定义代码如何与实现该接口的任何对象通信。接口始终是一个协议或承诺。当一个类说“我实现接口Y”时,它就是说“我承诺拥有与任何具有接口Y的对象相同的公共方法”。另一方面,抽象类类似于部分构建的类。它很像是一个有空格要填写的文档。它可能使用英语,但这并不像某些文档已经写好这样重要。抽象类是另一个对象的基础。当一个类显示“I extend abstract class Y”时,它表示“I use some methods or properties already defined in this other class named Y”。因此,请考虑以下PHP:<?php文件类X实现了Y{}//这意味着“X”同意使用代码使用语言“Y”。类X扩展了Y{}//这意味着“X”将完成部分类“Y”。?>如果您正在分发一个类供其他人使用,那么您的类将实现一个特定的接口。接口是一个协议,为您的类提供一组特定的公共方法。如果您(或其他人)编写了一个已经编写了一些要在新类中使用的方法的类,则可以让您的类扩展一个抽象类。这些概念虽然很容易混淆,但却特别不同和不同。出于所有意图和目的,如果您是任何类的唯一用户,则不需要实现接口。
推荐文章
- Java抽象接口
- 什么是依赖倒置原则?为什么它很重要?
- 为什么在Python方法中需要显式地有“self”参数?
- 如何在方法中访问“静态”类变量?
- 为什么c#不提供c++风格的'friend'关键字?
- String, StringBuffer和StringBuilder
- 如何在python抽象类中创建抽象属性?
- 存储库和服务层的区别?
- DDD -实体不能直接访问存储库的规则
- 为什么STL如此严重地基于模板而不是继承?
- 如何在Objective-C中声明类级属性?
- 面向方面编程与面向对象编程
- c++中类似于java的instanceof
- 在python中遍历对象属性
- 将类代码分离为头文件和cpp文件