我应该如何解释一个接口和一个抽象类的区别?

在我的一个采访中,我被要求解释一个接口和一个抽象类的区别。

这是我的回应:

Java接口的方法是隐式抽象的,不能有实现。 Java抽象类可以有实现默认行为的实例方法。

在Java接口中声明的variables在默认情况下是final的。 抽象类可能包含非最终variables。

Java接口的成员默认是公共的。 一个Java抽象类可以拥有像private,protected等类成员的通常风味。

Java接口应该使用关键字“implements”来实现; Java抽象类应该使用关键字“extends”进行扩展。

一个接口只能扩展另一个Java接口,一个抽象类可以扩展另一个Java类并实现多个Java接口。

一个Java类可以实现多个接口,但它只能扩展一个抽象类。

不过,面试官不满意,告诉我这个描述代表“ 书本知识 ”。

他问我一个更实际的回答,解释什么时候我会通过一个接口select一个抽象类,用实际的例子

我哪里做错了?

我会先给你举个例子:

public interface LoginAuth{ public String encryptPassword(String pass); public void checkDBforUser(); } 

现在假设你的应用程序中有3个数据库。 然后,该数据库的每个实现都需要定义上述2个方法:

 public class DBMySQL implements LoginAuth{ // Needs to implement both methods } public class DBOracle implements LoginAuth{ // Needs to implement both methods } public class DBAbc implements LoginAuth{ // Needs to implement both methods } 

但是如果encryptPassword()不依赖于数据库,那么每个类都是一样的呢? 那么上述不会是一个好方法。

相反,请考虑这种方法:

 public abstract class LoginAuth{ public String encryptPassword(String pass){ // Implement the same default behavior here // that is shared by all subclasses. } // Each subclass needs to provide their own implementation of this only: public abstract void checkDBforUser(); } 

现在在每个子类中,我们只需要实现一个方法 – 依赖于数据库的方法。

我尽我所能,希望这将清除你的疑惑。

这世上没有什么是完美的。 他们可能一直期待更多的实用方法。

但是在你的解释之后,你可以添加一些稍微不同的方法。

  1. 接口是规则(规则是因为你必须给予他们一个你不能忽视或避免的实现,这样他们就像规则一样),作为软件开发团队中的共同理解文件。

  2. 接口给出了想法要做什么,但不知道如何做。 所以实现完全依赖于开发人员遵循给定的规则(意味着方法的签名)。

  3. 抽象类可能包含抽象声明,具体实现或两者。

  4. 抽象声明就像是要遵循的规则,具体的实现就像是指导原则(你可以直接使用它,或者你可以忽略它,通过重写和给你自己的实现)。

  5. 而且哪些具有相同签名的方法可能会改变不同上下文中的行为作为接口声明作为规则提供,从而在不同的上下文中相应地实现。

您对使用和实施方面的实际差异做了一个很好的总结,但没有说明意义上的差异。

接口是实现类将具有的行为的描述。 实现类保证,它将有这些方法可以使用它。 这基本上是一个合同或者是class级必须作出的承诺。

抽象类是共享不需要重复创build的行为的不同子的基础。 子类必须完成行为并且可以select覆盖预定义的行为(只要它没有被定义为finalprivate )。

你将在java.util包中find很好的例子,其中包括像List这样的接口和已经实现了接口的AbstractList类的抽象类。 官方文档描述了AbstractList如下:

这个类提供了List接口的骨架实现,以最小化实现由“随机访问”数据存储(例如数组)所支持的接口所需的工作量。

一个接口由单体variables(public static final)和公共抽象方法组成。 当我们知道该做什么但是不知道如何去做的时候,我们通常更喜欢使用一个接口。

例如:这个概念可以被更好地理解:

考虑一个支付类。 支付可以通过很多方式进行,比如PayPal,信用卡等。所以我们通常把makePayment()作为我们的接口,其中包含一个makePayment()方法,CreditCard和PayPal是两个实现类。

 public interface Payment { void makePayment();//by default it is a abstract method } public class PayPal implements Payment { public void makePayment() { //some logic for PayPal payment //eg Paypal uses username and password for payment } } public class CreditCard implements Payment { public void makePayment() { //some logic for CreditCard payment //eg CreditCard uses card number, date of expiry etc... } } 

在上面的例子中,CreditCard和PayPal是两个实现类/策略。 一个接口也允许我们使用Java中的多inheritance的概念,这是抽象类无法实现的。

我们select一个抽象类,当有一些function,我们知道该怎么做,以及我们知道如何执行的其他function

考虑下面的例子:

 public abstract class Burger { public void packing() { //some logic for packing a burger } public abstract void price(); //price is different for different categories of burgers } public class VegBerger extends Burger { public void price() { //set price for a veg burger. } } public class NonVegBerger extends Burger { public void price() { //set price for a non-veg burger. } } 

如果我们将未来的方法(具体/抽象)添加到给定的抽象类中,那么实现类将不需要更改其代码。 但是,如果将来在接口中添加方法,则必须将实现添加到实现该接口的所有类中,否则编译时会发生错误。

还有其他的不同之处,但这些主要的可能是你的面试官所期望的。 希望这是有帮助的。

除了第一条语句之外,所有的语句都是有效的(在Java 8版本之后):

Java接口的方法是隐式抽象的,不能有实现

从文档页面 :

一个接口是一个引用types,类似于一个类,它只能包含常量,方法签名,默认方法,静态方法和嵌套types

方法体仅存在于默认方法和静态方法中。

默认方法:

一个接口可以有默认方法 ,但是与抽象类中的抽象方法不同。

使用默认方法,可以将新function添加到库的接口,并确保与为这些接口的旧版本编写的代码的二进制兼容性。

扩展包含默认方法的接口时,可以执行以下操作:

  1. 根本不提及默认的方法,这可以让你的扩展接口inheritance默认的方法。
  2. 重新声明默认的方法,这使得它是abstract
  3. 重新定义覆盖它的默认方法。

静态方法:

除了默认方法之外,您还可以在接口中定义静态方法。 (静态方法是一种与定义它的类相关联的方法,而不是与任何对象相关联,每个类的实例都共享它的静态方法。

这使您更容易在您的库中组织帮助器方法;

文档页面中关于具有staticdefault方法的interface示例代码。

 import java.time.*; public interface TimeClient { void setTime(int hour, int minute, int second); void setDate(int day, int month, int year); void setDateAndTime(int day, int month, int year, int hour, int minute, int second); LocalDateTime getLocalDateTime(); static ZoneId getZoneId (String zoneString) { try { return ZoneId.of(zoneString); } catch (DateTimeException e) { System.err.println("Invalid time zone: " + zoneString + "; using default time zone instead."); return ZoneId.systemDefault(); } } default ZonedDateTime getZonedDateTime(String zoneString) { return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString)); } } 

使用下面的指导来select是否使用接口或抽象类。

接口:

  1. 要定义合同 (最好是无状态 – 我的意思是没有变数)
  2. 链接无关的类有一个function。
  3. 声明公共常量variables( 不可变状态

抽象类:

  1. 在几个密切相关的类中共享代码。 它build立的是一种关系。

  2. 相关类之间共享状态(可以在具体类中修改状态)

相关文章:

界面与抽象类(通用OO)

实现vs扩展:何时使用? 有什么不同?

通过这些例子,你可以理解这一点

无关的类可以通过接口具有能力,但相关的类通过扩展基类来改变行为。

Abstact类和接口之间的区别

  1. Java 8中的抽象类与接口
  2. 概念差异:

Java 8中的接口默认方法

  1. 什么是默认方法?
  2. ForEach方法编译错误使用默认方法解决
  3. 默认方法和多inheritance歧义问题
  4. 有关java接口默认方法的重点:

Java接口静态方法

  1. Java接口静态方法,代码示例,静态方法与默认方法
  2. 关于java接口静态方法的要点:

Javafunction接口



Java 8中的抽象类与接口

Java 8接口更改包括接口中的静态方法和默认方法。 在Java 8之前,我们只能在接口中使用方法声明。 但是从Java 8开始,我们可以在接口中使用默认方法和静态方法。

引入了Default Method之后,接口和抽象类似乎是一样的。 但是,在Java 8中它们仍然是不同的概念。

抽象类可以定义构造函数。 他们更有条理,可以有一个与他们有关的国家。 而相比之下,默认方法只能在调用其他接口方法的情况下实现,而不涉及特定实现的状态。 因此,两者用于不同的目的和两者之间的select实际上取决于场景的情况。

概念差异:

抽象类适用于接口的骨架(即部分)实现,但不应该存在没有匹配的接口。

所以当抽象类被有效地减less为低可见性,接口的骨架实现时,默认的方法是否可以把这个方法带走呢? 决定:不! 实现接口几乎总是需要默认方法缺less的那些类构build工具中的一部分或全部。 如果一些界面没有,那显然是一个特例,不应该把你引入歧途。

Java 8中的接口默认方法

Java 8引入了“ 默认方法 ”或(Defender方法)的新特性,它允许开发人员在不打破这些接口的现有实现的情况下向接口添加新的方法。 它提供了灵活性来允许接口定义实现,在具体类无法为该方法提供实现的情况下,它将默认使用。

让我们考虑一个小例子来理解它的工作原理:

 public interface OldInterface {    public void existingMethod();    default public void newDefaultMethod() {        System.out.println("New default method"               + " is added in interface");    } } 

下面的类将在Java JDK 8中成功编译,

 public class OldInterfaceImpl implements OldInterface {    public void existingMethod() {     // existing implementation is here…    } } 

如果您创build一个OldInterfaceImpl的实例:

 OldInterfaceImpl obj = new OldInterfaceImpl (); // print “New default method add in interface” obj.newDefaultMethod(); 

默认方法:

默认方法永远不会是最终的,不能被同步,也不能重写Object的方法。 它们总是公开的,严重限制了编写简短和可重用方法的能力。

可以向接口提供缺省方法,而不会影响实现类,因为它包含一个实现。 如果在实现中定义的接口中添加的每个方法都没有影响到实现的类。 实现类可以覆盖接口提供的默认实现。

默认的方法可以为现有的接口添加新的function,而不会破坏这些接口的旧的实现。

当我们扩展一个包含默认方法的接口时,我们可以执行以下操作,

  1. 不覆盖默认的方法,并会inheritance默认的方法。
  2. 重写类似于我们在子类中重写的其他方法的默认方法。
  3. Redeclare的默认方法是抽象的,强制子类覆盖它。

ForEach方法编译错误使用默认方法解决

对于Java 8,JDK集合已被扩展,forEach方法被添加到整个集合(与lambda一起使用)。 用传统的方式,代码如下所示,

 public interface Iterable<T> {    public void forEach(Consumer<? super T> consumer); } 

由于这个结果每个都实现了带有编译错误的类,因此为了不改变现有的实现,添加了一个需要的实现的默认方法。

下面的默认方法的Iterable接口,

 public interface Iterable<T> {    public default void forEach(Consumer                   <? super T> consumer) {        for (T t : this) {            consumer.accept(t);        }    } } 

已经使用相同的机制在JDK接口中添加Stream ,而不会破坏实现类。


默认方法和多inheritance歧义问题

由于java类可以实现多个接口,每个接口都可以定义具有相同方法签名的缺省方法,因此inheritance的方法可以相互冲突。

考虑下面的例子,

 public interface InterfaceA {       default void defaultMethod(){           System.out.println("Interface A default method");    } } public interface InterfaceB {   default void defaultMethod(){       System.out.println("Interface B default method");   } } public class Impl implements InterfaceA, InterfaceB { } 

上面的代码将无法编译以下错误,

java:class Impl从InterfaceA和InterfaceBtypesinheritancedefaultMethod()的无关的默认值

为了解决这个类,我们需要提供默认的方法实现:

 public class Impl implements InterfaceA, InterfaceB {    public void defaultMethod(){    } } 

而且,如果我们想调用超级接口提供的默认实现而不是我们自己的实现,我们可以这样做,

 public class Impl implements InterfaceA, InterfaceB {    public void defaultMethod(){        // existing code here..        InterfaceA.super.defaultMethod();    } } 

我们可以select任何默认实现或两者作为我们新方法的一部分。

关于java接口默认方法的重点:

  1. Java接口的默认方法将帮助我们扩展接口,而不用担心破坏实现类。
  2. Java接口的默认方法弥合了接口和抽象类之间的差异。
  3. Java 8接口的默认方法将帮助我们避免实用类,比如所有的Collections类方法都可以在接口本身中提供。
  4. Java接口的默认方法将帮助我们去除基类的实现类,我们可以提供默认的实现,实现类可以select重写哪一个。
  5. 在接口中引入默认方法的主要原因之一是增强Java 8中的Collections API以支持lambdaexpression式。
  6. 如果层次结构中的任何类具有相同签名的方法,则默认方法变得不相关。 默认方法不能从java.lang.Object中覆盖方法。 推理非常简单,这是因为Object是所有java类的基类。 所以即使我们把Object类的方法定义为接口中的默认方法,也是无用的,因为总是使用Object类的方法。 这就是为什么要避免混淆,我们不能有覆盖Object类方法的默认方法。
  7. Java接口默认方法也被称为Defender方法或虚拟扩展方法。

资源链接:

  1. 在Java 8中与默认方法与抽象类的接口
  2. 抽象类与JDK 8时代的接口
  3. 通过虚拟扩展方法进行接口演变

Java接口静态方法

Java接口静态方法,代码示例,静态方法与默认方法

Java接口静态方法类似于默认方法,只是我们不能在实现类中重写它们。 这个特性帮助我们避免了在实现类中实施不当的结果。 我们来看一个简单的例子。

 public interface MyData { default void print(String str) { if (!isNull(str)) System.out.println("MyData Print::" + str); } static boolean isNull(String str) { System.out.println("Interface Null Check"); return str == null ? true : "".equals(str) ? true : false; } } 

现在让我们来看一个实现类,该实现类具有isNull()方法,实现较差。

 public class MyDataImpl implements MyData { public boolean isNull(String str) { System.out.println("Impl Null Check"); return str == null ? true : false; } public static void main(String args[]){ MyDataImpl obj = new MyDataImpl(); obj.print(""); obj.isNull("abc"); } } 

请注意,isNull(String str)是一个简单的类方法,它不覆盖接口方法。 例如,如果我们将@Override注释添加到isNull()方法中,则会导致编译器错误。

现在,当我们运行应用程序时,我们得到以下输出。

接口空检查

Impl空检查

如果我们使接口方法从静态到默认,我们将得到以下输出。

Impl空检查

MyData打印::

Impl空检查

Java接口的静态方法只对接口方法可见,如果我们从MyDataImpl类中移除了isNull()方法,我们将无法将其用于MyDataImpl对象。 然而像其他静态方法一样,我们可以使用类名的接口静态方法。 例如,一个有效的陈述将是:

 boolean result = MyData.isNull("abc"); 

关于java接口静态方法的要点:

  1. Java接口的静态方法是接口的一部分,我们不能用它来实现类对象。
  2. Java接口的静态方法可以提供实用的方法,比如空检查,集合sorting等。
  3. Java接口静态方法通过不允许实现类覆盖它们来帮助我们提供安全性。
  4. 我们不能为Object类方法定义接口静态方法,因为“这个静态方法不能从Object中隐藏实例方法”,我们会得到编译器错误。 这是因为它不允许在java中,因为Object是所有类的基类,我们不能有一个类级别的静态方法和另一个具有相同签名的实例方法。
  5. 我们可以使用java接口静态方法来移除集合等实用工具类,并将其所有的静态方法移动到相应的接口,这将很容易find和使用。

Javafunction接口

在结束这篇文章之前,我想简要介绍function接口。 具有一个抽象方法的接口被称为function接口。

引入了一个新的注释@FunctionalInterface来将接口标记为function接口。 @FunctionalInterface注释是避免在function接口中添加抽象方法的一种工具。 这是可选的,但使用它的好习惯。

function性接口是Java 8的一个长期等待的function,因为它使我们能够使用lambdaexpression式来实例化它们。 添加了一个新的包java.util.function和一堆函数接口,为lambdaexpression式和方法引用提供了目标types。 我们将在未来的post中研究函数接口和lambdaexpression式。

资源位置:

  1. Java 8接口更改 – 静态方法,默认方法

你的解释看起来很不错,但是看起来好像你是从教科书里看到的? : – /

我更烦恼的是,你的榜样有多坚实? 你是否打算包含抽象和接口之间几乎所有的差异?

就个人而言,我会build议这个链接: http : //mindprod.com/jgloss/interfacevsabstract.html#TABLE

详尽的列表

希望它能帮助你和所有其他读者在未来的访谈中

许多初级开发人员将接口,抽象和具体类作为同一事物的细微变化,并且纯粹以技术为由select其中之一: 我是否需要多重inheritance? 我需要一些地方来放置常用的方法吗? 除了具体的课程之外,我还需要打扰吗? 这是错误的,而隐藏在这些问题中的主要问题是: “我” 。 当你为自己编写代码时,你自己很less会想到其他现在或未来的开发人员正在使用或使用你的代码。

接口和抽象类虽然从技术angular度看似乎相似,但却有完全不同的含义和目的。

概要

  1. 一个接口定义了一些实现将为完成的合同

  2. 抽象类提供了 您的实现可以重用的默认行为

以上两点是我在面试时要查找的内容,并且是一个足够简洁的总结。 请阅读更多的细节。

备选摘要

  1. 一个接口用于定义公共API
  2. 抽象类用于内部使用,用于定义SPI

举例来说

换句话说,一个具体的课程以一种非常具体的方式来完成实际的工作。 例如, ArrayList使用连续的内存区域以紧凑的方式存储对象列表,提供快速的随机访问,迭代和就地更改,但是在插入,删除和偶尔添加时很糟糕; 同时, LinkedList使用双链接节点来存储对象列表,而不是提供快速迭代,就地更改以及插入/删除/添加,但在随机访问时很糟糕。 这两种types的列表针对不同的使用情况进行了优化,您将如何使用它们非常重要。 当你试图从一个你正在与之交互的列表中挤出性能,并且当select列表types取决于你时,你应该仔细select你正在实例化的那一个。

另一方面,列表的高级用户并不在意它是如何实际执行的,他们应该与这些细节隔离。 让我们设想一下,Java并没有公开List接口,但是只有一个具体的List类,它实际上就是LinkedList 。 所有的Java开发人员都会根据实现的细节量身定做他们的代码:避免随机访问,添加一个caching来加速访问,或者只是自己重新实现ArrayList ,尽pipe它与所有其他代码实际上不兼容。 这将是可怕的…但现在想象一下,Java主人实际上认识到,链表对于大多数实际的用例来说是可怕的,并决定切换到他们唯一的List类可用的数组列表。 这会影响到世界上每一个Java程序的性能,人们不会为此感到高兴。 主要的原因是实现细节是可用的,开发人员认为这些细节是一个可以依赖的永久合同。 这就是为什么隐藏实现细节非常重要,只能定义一个抽象合约。 这是一个接口的目的:定义一种方法接受什么types的input,以及期望什么样的输出,而不暴露所有的诱惑程序员调整他们的代码,以适应可能随着任何未来更新而改变的内部细节。

抽象类在接口和具体类之间。 它应该帮助实现共享共同的或无聊的代码。 例如, AbstractCollection提供了基于大小为0的isEmpty的基本实现, contains迭代和比较, addAll作为重复add ,等等。 这使得实现可以关注区分它们的关键部分:如何实际存储和检索数据。

另一个angular度:API与SPIs

接口是代码不同部分之间的低内聚网关 。 它们允许图书馆在内部发生变化时不会破坏每个图书馆用户的存在和发展。 它被称为应用程序编程接口 ,而不是应用程序编程类。 在较小规模上,他们还允许多个开发人员在大型项目上成功协作,通过良好的文档化界面分离不同的模块。

抽象类是实现接口时使用的高内聚助手 ,假定某种级别的实现细节。 或者,抽象类用于定义SPI,服务提供者接口。

API和SPI之间的区别是微妙的,但是很重要:对于API,重点在于谁使用它,对于SPI来说,关注的是谁来实现它。

向API添加方法很简单,API的所有现有用户仍将编译。 向SPI添加方法很困难,因为每个服务提供者(具体实现)都必须实现新的方法。 如果使用接口来定义一个SPI,那么只要SPI合同改变,提供者就必须发布一个新的版本。 如果使用抽象类,则可以根据现有的抽象方法定义新的方法,也可以将空的方法定义为throw not implemented exception存根,这将至less允许旧版本的服务实现继续编译和运行。

关于Java 8和默认方法的说明

尽pipeJava 8引入了接口的默认方法,这使得接口和抽象类之间的界限变得更加模糊,但是这并不是为了使实现可以重用代码,而是为了更容易地改变既可以作为API也可以作为SPI使用的接口(或错误地用于定义SPI而不是抽象类)。

“书本知识”

在OP的答案中提供的技术细节被认为是“书本知识”,因为这通常是在学校和大多数技术书籍中使用的关于语言的方法: 什么是事实,而不是如何在实践中使用它,特别是在大规模应用。

这是一个比喻:假设问题是:

在舞会,汽车或酒店房间租用什么更好?

技术答案听起来像:

那么,在一辆汽车里,你可以早点做,但在酒店房间里,你可以更舒适地做。 另一方面,酒店房间只有一个地方,而在车里,你可以在更多的地方做,比如说,你可以到景点欣赏美景,或者在一个开车的剧院里,或许多其他地方,甚至不止一个地方。 此外,酒店房间有淋浴。

这是完全正确的,但完全错过了两个完全不同的东西,两者可以同时用于不同的目的,而“做”这个方面并不是两个选项中最重要的一个。 答案缺乏透视,显示出一种不成熟的思维方式,正确地呈现真实的“事实”。

一个接口是一个“契约”,其中实现契约的类承诺实现这些方法。 我不得不写一个接口而不是一个类的例子是当我将游戏从2D升级到3D时。 我不得不创build一个界面来分享游戏的2D和3D版本之间的类。

 package adventure; import java.awt.*; public interface Playable { public void playSound(String s); public Image loadPicture(String s); } 

然后,我可以实现基于环境的方法,同时仍然可以从不知道正在加载哪个版本的游戏的对象调用这些方法。

public class Adventure extends JFrame implements Playable

public class Dungeon3D extends SimpleApplication implements Playable

public class Main extends SimpleApplication implements AnimEventListener, ActionListener, Playable

Typically, in the gameworld, the world can be an abstract class that performs methods on the game:

 public abstract class World... public Playable owner; public Playable getOwner() { return owner; } public void setOwner(Playable owner) { this.owner = owner; } 

What about thinking the following way:

  • A relationship between a class and an abstract class is of type "is-a"
  • A relationship between a class and an interface is of type "has-a"

So when you have an abstract class Mammals, a subclass Human, and an interface Driving, then you can say

  • each Human is-a Mammal
  • each Human has-a Driving (behavior)

My suggestion is that the book knowledge phrase indicates that he wanted to hear the semantic difference between both (like others here already suggested).

Abstract classes are meant to be inherited from, and when one class inherits from another it means that there is a strong relationship between the 2 classes. With an interface on the other hand, the relationship between the interface itself and the class implementing the interface is not necessarily strong. So, we can summarize this first point by saying that an abstract class would be more appropriate when there is a strong relationship between the abstract class and the classes that will derive from it. Again, this is because an abstract class is very closely linked to inheritance, which implies a strong relationship. But, with interfaces there need not be a strong relationship between the interface and the classes that implement the interface. Java interface can extend multiple interface also Java class can implement multiple interfaces, Which means interface can provide more polymorphism support than abstract class . By extending abstract class, a class can only participate in one Type hierarchy but by using interface it can be part of multiple type hierarchies.

In order to implement interface in Java, until your class is abstract, you need to provide implementation of all methods, which is very painful. On the other hand abstract class may help you in this case by providing default implementation.

Abstract classes are not pure abstraction bcz its collection of concrete(implemented methods) as well as unimplemented methods. But Interfaces are pure abstraction bcz there are only unimplemented methods not concrete methods.

Why Abstract classes?

  1. If user want write common functionality for all objects.
  2. Abstract classes are best choice for reimplementation in future that to add more functionality without affecting of end user.

Why Interfaces?

  1. If user want to write different functionality that would be different functionality on objects.
  2. Interfaces are best choice that if not need to modify the requirements once interface has been published.

The main difference what i have observed was that abstract class provides us with some common behaviour implemented already and subclasses only needs to implement specific functionality corresponding to them. where as for an interface will only specify what tasks needs to be done and no implementations will be given by interface. I can say it specifies the contract between itself and implemented classes.

I do interviews for work and i would look unfavourably on your answer aswell (sorry but im very honest). It does sound like you've read about the difference and revised an answer but perhaps you have never used it in practice.

A good explanation as to why you would use each can be far better than having a precise explanation of the difference. Employers ultimatley want programers to do things not know them which can be hard to demonstrate in an interview. The answer you gave would be good if applying for a technical or documentation based job but not a developers role.

Best of luck with interviews in the future.

Also my answer to this question is more about interview technique rather than the technical material youve provided. Perhaps consider reading about it. https://workplace.stackexchange.com/ can be an excellent place for this sort of thing.

An interface is like a set of genes that are publicly documented to have some kind of effect: A DNA test will tell me whether I've got them – and if I do, I can publicly make it known that I'm a "carrier" and part of my behavior or state will conform to them. (But of course, I may have many other genes that provide traits outside this scope.)

An abstract class is like the dead ancestor of a single-sex species (*): She can't be brought to life but a living (ie non-abstract ) descendant inherits all her genes.

(*) To stretch this metaphor, let's say all members of the species live to the same age. This means all ancestors of a dead ancestor must also be dead – and likewise, all descendants of a living ancestor must be alive.

An interface is purely abstract. we dont have any implementation code in interface.

Abstract class contains both methods and its implementation.

click here to watch tutorial on interfaces and abstract classes

The main difference what i have observed was that abstract class provides us with some common behaviour implemented already and subclasses only needs to implement specific functionality corresponding to them. where as for an interface will only specify what tasks needs to be done and no implementations will be given by interface. I can say it specifies the contract between itself and implemented classes.

You choose Interface in Java to avoid the Diamond Problem in multiple inheritance .

If you want all of your methods to be implemented by your client you go for interface. It means you design the entire application at abstract.

You choose abstract class if you already know what is in common. For example Take an abstract class Car . At higher level you implement the common car methods like calculateRPM() . It is a common method and you let the client implement his own behavior like
calculateMaxSpeed() etc. Probably you would have explained by giving few real time examples which you have encountered in your day to day job.

Even I have faced the same question in multiple interviews and believe me it makes your time miserable to convince the interviewer. If I inherent all the answers from above then I need to add one more key point to make it more convincing and utilizing OO at its best

In case you are not planning any modification in the rules , for the subclass to be followed, for a long future, go for the interface, as you wont be able to modify in it and if you do so, you need to go for the changes in all the other sub classes, whereas, if you think, you want to reuse the functionality, set some rules and also make it open for modification , go for Abstract class.

Think in this way, you had used a consumable service or you had provided some code to world and You have a chance to modify something, suppose a security check And If I am being a consumer of the code and One morning after a update , I find all read marks in my Eclipse, entire application is down. So to prevent such nightmares, use Abstract over Interfaces

I think this might convince the Interviewer to a extent…Happy Interviews Ahead.

From what I understand, an Interface, which is comprised of final variables and methods with no implementations, is implemented by a class to obtain a group of methods or methods that are related to each other. On the other hand, an abstract class, which can contain non-final variables and methods with implementations, is usually used as a guide or as a superclass from which all related or similar classes inherits from. In other words, an abstract class contains all the methods/variables that are shared by all its subclasses.

In abstract class, you can write default implementation of methods! But in Interface you can not. Basically, In interface there exist pure virtual methods which have to be implemented by the class which implements the interface.

hmm now the people are hungery practical approach, you are quite right but most of interviewer looks as per their current requirment and want a practical approach.

after finishing your answer you should jump on the example:

抽象:

for example we have salary function which have some parametar common to all employee. then we can have a abstract class called CTC with partialy defined method body and it will got extends by all type of employee and get redeined as per their extra beefits. For common functonality.

 public abstract class CTC { public int salary(int hra, int da, int extra) { int total; total = hra+da+extra; //incentive for specific performing employee //total = hra+da+extra+incentive; return total; } } class Manger extends CTC { } class CEO extends CTC { } class Developer extends CTC { } 

接口

interface in java allow to have interfcae functionality without extending that one and you have to be clear with the implementation of signature of functionality that you want to introduce in your application. it will force you to have definiton. For different functionality. public interface EmployeType {

  public String typeOfEmployee(); } class ContarctOne implements EmployeType { @Override public String typeOfEmployee() { return "contract"; } } class PermanentOne implements EmployeType { @Override public String typeOfEmployee() { return "permanent"; } } 

you can have such forced activity with abstract class too by defined methgos as a abstract one, now a class tha extends abstract class remin abstract one untill it override that abstract function.

When I am trying to share behavior between 2 closely related classes, I create an abstract class that holds the common behavior and serves as a parent to both classes.

When I am trying to define a Type, a list of methods that a user of my object can reliably call upon, then I create an interface.

For example, I would never create an abstract class with 1 concrete subclass because abstract classes are about sharing behavior. But I might very well create an interface with only one implementation. The user of my code won't know that there is only one implementation. Indeed, in a future release there may be several implementations, all of which are subclasses of some new abstract class that didn't even exist when I created the interface.

That might have seemed a bit too bookish too (though I have never seen it put that way anywhere that I recall). If the interviewer (or the OP) really wanted more of my personal experience on that, I would have been ready with anecdotes of an interface has evolved out of necessity and visa versa.

还有一件事。 Java 8 now allows you to put default code into an interface, further blurring the line between interfaces and abstract classes. But from what I have seen, that feature is overused even by the makers of the Java core libraries. That feature was added, and rightly so, to make it possible to extend an interface without creating binary incompatibility. But if you are making a brand new Type by defining an interface, then the interface should be JUST an interface. If you want to also provide common code, then by all means make a helper class (abstract or concrete). Don't be cluttering your interface from the start with functionality that you may want to change.

I will try to answer using practical scenario to show the distinction between the two.

Interfaces come with zero payload ie no state has to be maintained and thus are better choice to just associate a contract (capability) with a class.

For example, say I have a Task class that performs some action, now to execute a task in separate thread I don't really need to extend Thread class rather better choice is to make Task implement Runnable interface (ie implement its run() method) and then pass object of this Task class to a Thread instance and call its start() method.

Now you can ask what if Runnable was a abstract class?

Well technically that was possible but design wise that would have been a poor choice reason being:

  • Runnable has no state associated with it and neither it 'offers' any default implementation for the run() method
  • Task would have to extend it thus it couldn't extend any other class
  • Task has nothing to offer as specialization to Runnable class, all it needs is to override run() method

In other words, Task class needed a capability to be run in a thread which it achieved by implementing Runnable interface verses extending the Thread class that would make it a thread.

Simply put us interface to define a capability (contract), while use a abstract class to define skeleton (common/partial) implementation of it.

Disclaimer: silly example follows, try not to judge 😛

 interface Forgiver { void forgive(); } abstract class GodLike implements Forgiver { abstract void forget(); final void forgive() { forget(); } } 

Now you have been given a choice to be GodLike but you may choose to be Forgiver only (ie not GodLike) and do:

 class HumanLike implements Forgiver { void forgive() { // forgive but remember } } 

Or you may may choose to be GodLike and do:

 class AngelLike extends GodLike { void forget() { // forget to forgive } } 

PS with java 8 interface can also have static as well default (overridable implementation) methods and thus difference b/w interface and abstract class is even more narrowed down.

Almost everything seems to be covered here already.. Adding just one more point on practical implementation of abstract class:

abstract keyword is also used just prevent a class from being instantiated. If you have a concrete class which you do not want to be instantiated – Make it abstract .

From what I understand and how I approach,

Interface is like a specification/contract, any class that implements a interface class have to implement all the methods defined in the abstract class (except default methods (introduced in java 8))

Whereas I define a class abstract when I know the implementation required for some methods of the class and some methods I still do not know what will be the implementation(we might know the function signature but not the implementation). I do this so that later in the part of development when i know how these methods are to be implemented, i can just extend this abstract class and implement these methods.

Note: You cannot have function body in interface methods unless the method is static or default.

I believe what the interviewer was trying to get at was probably the difference between interface and implementation.

The interface – not a Java interface, but "interface" in more general terms – to a code module is, basically, the contract made with client code that uses the interface.

The implementation of a code module is the internal code that makes the module work. Often you can implement a particular interface in more than one different way, and even change the implementation without client code even being aware of the change.

A Java interface should only be used as an interface in the above generic sense, to define how the class behaves for the benefit of client code using the class, without specifying any implementation. Thus, an interface includes method signatures – the names, return types, and argument lists – for methods expected to be called by client code, and in principle should have plenty of Javadoc for each method describing what that method does. The most compelling reason for using an interface is if you plan to have multiple different implementations of the interface, perhaps selecting an implementation depending on deployment configuration.

A Java abstract class, in contrast, provides a partial implementation of the class, rather than having a primary purpose of specifying an interface. It should be used when multiple classes share code, but when the subclasses are also expected to provide part of the implementation. This permits the shared code to appear in only one place – the abstract class – while making it clear that parts of the implementation are not present in the abstract class and are expected to be provided by subclasses.

your answer is right but the interviewer needs you to differentiate according to software engineering perspective not according to the details of Java.

简单的话:

An Interface is like the interface of a shop anything that is shown on it should be there in the shop, so any method in the Interface must be there implemented in the concrete class. Now what if some classes share some exact methods and varies in others. Suppose the Interface is about a shop that contains two things and suppose we have two shops both contain sport equipment but one has clothes extra and the other has shoes extra. So what you do is making an abstract class for Sport that implements the Sports method and leave the other method unimplemented. Abstract class here means that this shop doesn't exist itself but it is the base for other classes/shops. This way you are organising the code, avoiding errors of replicating the code, unifying the code, and ensuring re-usability by some other class.

Your answer is ok, but I think he was looking for this kind of answer:

Abstract class

  • 抽象类可以有抽象和非抽象的方法。
  • 抽象类不支持多重inheritance。
  • 抽象类可以有最终的,非最终的,静态的和非静态的variables。
  • 抽象类可以提供接口的实现。

接口

  • Interface can have default, static and abstract methods.
  • 接口支持多重inheritance。
  • 接口只有静态和最终的variables。
  • Interface can't provide the implementation of abstract class.

Yes, your responses were technically correct but where you went wrong was not showing them you understand the upsides and downsides of choosing one over the other. Additionally, they were probably concerned/freaked out about compatibility of their codebase with upgrades in the future. This type of response may have helped (in addition to what you said):

"Choosing an Abstract Class over an Interface Class depends on what we project the future of the code will be.

Abstract classes allow better forward-compatibility because you can continue adding behavior to an Abstract Class well into the future without breaking your existing code –> this is not possible with an Interface Class.

On the other hand, Interface Classes are more flexible than Abstract Classes. This is because they can implement multiple interfaces . The thing is Java does not have multiple inheritances so using abstract classes won't let you use any other class hierarchy structure…

So, in the end a good general rule of thumb is: Prefer using Interface Classes when there are no existing/default implementations in your codebase. And, use Abstract Classes to preserve compatibility if you know you will be updating your class in the future."

Good luck on your next interview!