接口和抽象类之间到底有什么区别?
当前回答
我不想强调这些差异,这已经在很多答案中说过了(关于接口中变量的公共静态最终修饰符以及抽象类中受保护的私有方法的支持)
简单地说,我想说:
接口:通过多个不相关的对象实现合同
抽象类:在多个相关对象之间实现相同或不同的行为
来自Oracle文档
如果出现以下情况,请考虑使用抽象类:
您希望在几个密切相关的类之间共享代码。您希望扩展抽象类的类具有许多公共方法或字段,或者需要公共以外的访问修饰符(如protected和private)。您要声明非静态或非final字段。
如果出现以下情况,请考虑使用接口:
您希望不相关的类实现您的接口。例如,许多不相关的对象可以实现Serializable接口。您希望指定特定数据类型的行为,但不关心谁实现了它的行为。您希望利用类型的多重继承。
抽象类与具体类建立“是”关系。接口为类提供了“具有”功能。
如果您正在寻找Java作为编程语言,这里还有一些更新:
Java8通过提供默认方法特性,在一定程度上缩小了接口类和抽象类之间的差距。接口没有实现。方法现在不再有效。
有关详细信息,请参阅本文档页。
看看这个SE问题,了解代码示例,以便更好地理解。
我应该如何解释接口和抽象类之间的区别?
其他回答
让我们再次讨论这个问题:
首先要告诉你的是,1/1和1*1的结果是相同的,但这并不意味着乘法和除法是相同的。显然,他们有着良好的关系,但请注意,你们两个都不同。
我将指出主要的区别,其余的已经解释过了:
抽象类对于建模类层次结构非常有用。乍一看任何需求,我们都部分清楚要构建什么,但我们知道要构建什么。所以抽象类就是基类。
接口对于让其他层次结构或类知道我能做什么很有用。当你说我有能力做某事时,你必须有这种能力。接口将标记类必须实现相同的功能。
我迟到10年了,但我想尝试任何方法。几天前写了一篇同样的帖子。我想把它张贴在这里。
tl;博士当您看到“Is A”关系时,请使用继承/抽象类。当您看到“有”关系时,创建成员变量。当您看到“依赖于外部提供程序”时,实现(而不是继承)一个接口。
面试问题:接口和抽象类有什么区别?你如何决定何时使用什么?我通常会得到以下一个或全部答案:答案1:不能创建抽象类和接口的对象。
ZK(这是我的首字母缩写):你不能创建任何一个对象。所以这并不是什么区别。这是接口和抽象类之间的相似之处。柜台问题:为什么不能创建抽象类或接口的对象?
答案2:抽象类可以有一个函数体作为部分/默认实现。
ZK:反问题:所以如果我将其更改为纯抽象类,将所有虚拟函数标记为抽象,并且不为任何虚拟函数提供默认实现。这会使抽象类和接口相同吗?之后它们可以互换使用吗?
答案3:接口允许多重继承,抽象类不允许。
ZK:反问:你真的从接口继承吗?还是只实现一个接口,从抽象类继承?实现和继承之间有什么区别?这些反问题会让考生们措手不及,让大多数人挠头,或者直接进入下一个问题。这让我觉得人们需要帮助来构建面向对象编程的基本构件。原始问题和所有反问题的答案都可以在英语和UML中找到。为了更好地理解这两个结构,您必须至少了解以下内容。
共同名词:共同名词是指同一类或同一种类的事物的“共同”名称。例如水果、动物、城市、汽车等。
专有名词:专有名词是物体、地点或事物的名称。苹果、猫、纽约、本田雅阁等。
汽车是一个通用名词。本田雅阁是一个专有名词,可能是一个合成专有名词,一个由两个名词组成的专有名词。
来到UML部分。您应该熟悉以下关系:
是A有A使用
让我们考虑下面的两句话。-本田雅阁是一辆车?-本田雅阁有车吗?
哪一个听起来正确?简单的英语和理解能力。本田雅阁(HondaAccord)和汽车(Cars)有着“是A”的关系。本田雅阁(Honda accord)没有车,它“是”一辆车。本田雅阁“有一个”音乐播放器。
当两个实体共享“Is A”关系时,它更适合继承。Has a relationship是创建成员变量的更好候选。这样,我们的代码如下所示:
abstract class Car
{
string color;
int speed;
}
class HondaAccord : Car
{
MusicPlayer musicPlayer;
}
现在本田不生产音乐播放器。或者至少这不是他们的主要业务。
因此,他们联系其他公司并签订合同。如果你在这里接收到电源和这两条电线上的输出信号,它在这些扬声器上会播放得很好。
这使得Music Player成为界面的完美候选。你不在乎谁为它提供支持,只要连接正常即可。
您可以用索尼或其他方式替换LG的MusicPlayer。这不会改变本田雅阁的任何事情。
为什么不能创建抽象类的对象?
因为你不能走进展厅说给我一辆车。你必须提供一个专有名词。什么车?可能是本田雅阁。这就是销售代理可以给你东西的时候。
为什么不能创建接口的对象?因为你不能走进展厅说给我一份音乐播放器的合同。这没用。接口位于消费者和提供者之间,只是为了促成协议。你将如何处理协议副本?它不会播放音乐。
为什么接口允许多重继承?
接口未被继承。接口已实现。界面是与外部世界交互的候选界面。本田雅阁有一个加油接口。它有给轮胎充气的接口。和用来给足球充气的软管一样。因此,新代码如下所示:
abstract class Car
{
string color;
int speed;
}
class HondaAccord : Car, IInflateAir, IRefueling
{
MusicPlayer musicPlayer;
}
英文的意思是“本田雅阁是一款支持轮胎充气和加油的汽车”。
我正在建造一座300层的大楼
建筑的蓝图界面
例如,Servlet(I)
建筑高达200层-部分完工-摘要
部分实现,例如泛型和HTTPservlet
建筑施工完成混凝土
完整实现,例如,自己的servlet
界面
我们对实现一无所知,只知道需求。我们可以去找一个接口。默认情况下,每个方法都是公共的和抽象的这是一个100%纯抽象类如果我们宣布公开,我们就不能宣布隐私和受保护如果我们声明抽象,我们就不能声明final、static、synchronized、strictfp和native每个接口都有公共的、静态的和最终的序列化和瞬态不适用,因为我们无法在接口中创建实例非挥发性,因为它是最终的每个变量都是静态的当我们在接口内声明变量时,我们需要在声明不允许实例和静态块
摘要
部分实施它有一个抽象的方法。此外,它使用混凝土对抽象类方法修饰符没有限制抽象类变量修饰符没有限制除了abstract,我们不能声明其他修饰符初始化变量没有限制
摘自DurgaJobs网站
我们在接口和抽象类之间存在各种结构/语法差异。还有一些不同之处
[1] 基于场景的差异:
当我们希望限制用户创建父类的对象时,抽象类被用于场景中,并且我们相信将来还会添加更多的抽象方法。
当我们确信不能提供更多抽象方法时,必须使用接口。然后只发布一个接口。
[2] 概念差异:
“我们是否需要在未来提供更多抽象方法”,如果是,则将其设为抽象类,如果否,则设为接口。
(在java 1.7之前最合适和有效)
为了给出一个简单但明确的答案,设置上下文是有帮助的:当您不想提供完整的实现时,可以同时使用这两种方法。
因此,主要的区别是接口根本没有实现(只有没有主体的方法),而抽象类也可以有具有主体的成员和方法,即可以部分实现。