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

以下是我的回答:

Methods of a Java interface are implicitly abstract and cannot have implementations. A Java abstract class can have instance methods that implements a default behaviour. Variables declared in a Java interface are by default final. An abstract class may contain non-final variables. Members of a Java interface are public by default. A Java abstract class can have the usual flavours of class members like private, protected, etc. A Java interface should be implemented using keyword “implements”; A Java abstract class should be extended using keyword “extends”. An interface can extend another Java interface only, an abstract class can extend another Java class and implement multiple Java interfaces. A Java class can implement multiple interfaces but it can extend only one abstract class.

然而,面试官并不满意,他告诉我这种描述代表了“书本知识”。

他让我给出一个更实际的回答,用实际的例子解释我什么时候会选择抽象类而不是接口。

我哪里错了?


当前回答

这个世界上没有什么是完美的。他们可能期待的是更实际的方法。

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

Interfaces are rules (rules because you must give an implementation to them that you can't ignore or avoid, so that they are imposed like rules) which works as a common understanding document among various teams in software development. Interfaces give the idea what is to be done but not how it will be done. So implementation completely depends on developer by following the given rules (means given signature of methods). Abstract classes may contain abstract declarations, concrete implementations, or both. Abstract declarations are like rules to be followed and concrete implementations are like guidelines (you can use it as it is or you can ignore it by overriding and giving your own implementation to it). Moreover which methods with same signature may change the behaviour in different context are provided as interface declarations as rules to implement accordingly in different contexts.

编辑:Java 8简化了在接口中定义默认方法和静态方法。

public interface SomeInterfaceOne {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
    }
}

现在,当一个类将实现SomeInterface时,并不强制为interface的默认方法提供实现。

如果我们有另一个具有以下方法的接口:

public interface SomeInterfaceTwo {

    void usualAbstractMethod(String inputString);

    default void defaultMethod(String inputString){
        System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
    }

}

Java不允许扩展多个类,因为这会导致“钻石问题”,即编译器无法决定使用哪个超类方法。如果使用默认方法,接口也会出现菱形问题。因为如果一个类同时实现这两个

SomeInterfaceOne and SomeInterfaceTwo

并且没有实现常见的默认方法,编译器不能决定选择哪一个。 为了避免这个问题,在java 8中必须实现不同接口的通用缺省方法。如果任何类实现了上述两个接口,它必须提供defaultMethod()方法的实现,否则编译器将抛出编译时错误。

其他回答

抽象类不是纯粹的抽象,因为它是具体方法(已实现方法)和未实现方法的集合。 但 接口是纯抽象的,因为只有未实现的方法,没有具体的方法。

为什么是抽象类?

如果用户想为所有对象编写通用功能。 抽象类是未来重新实现的最佳选择,可以在不影响最终用户的情况下增加更多的功能。

为什么接口?

如果用户想要编写不同的功能,那将是对象上的不同功能。 一旦接口发布,如果不需要修改需求,接口是最好的选择。

你的解释看起来还不错,但可能看起来像是你从课本上读的?: - /

我更关心的是,你的例子有多可靠?你是否费心去包括抽象和接口之间几乎所有的区别?

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

对于差异的详尽列表..

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

这里似乎已经涵盖了几乎所有的东西。在抽象类的实际实现上再补充一点:

Abstract关键字也用于防止类被实例化。如果你有一个具体的类,你不想被实例化-让它抽象。

接口是纯粹抽象的。我们在接口中没有任何实现代码。

抽象类包含方法及其实现。

点击这里观看接口和抽象类教程

简而言之,我想这样回答:

通过类层次结构进行继承意味着状态继承; 而通过接口继承则代表行为继承;

抽象类可以被视为介于这两种情况之间的东西(它引入了一些状态,但也迫使你定义一个行为),完全抽象类是一个接口(据我所知,这是c++中仅由虚拟方法组成的类的进一步发展)。

当然,从Java 8开始,事情发生了轻微的变化,但思想仍然是一样的。

我想这对于一个典型的Java面试来说已经足够了,如果你不是被编译器团队面试的话。