Java 我应该如何解释接口和抽象类之间的区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18777989/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 10:58:02  来源:igfitidea点击:

How should I have explained the difference between an Interface and an Abstract class?

javaoopinheritanceinterfaceabstract-class

提问by Thinker

In one of my interviews, I have been asked to explain the difference between an Interfaceand an Abstract class.

在我的一次采访中,我被要求解释InterfaceAbstract class之间的区别。

Here's my response:

这是我的回应:

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.

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

在 Java 接口中声明的变量默认是 final 的。抽象类可能包含非最终变量。

Java 接口的成员默认是公共的。Java 抽象类可以具有类成员的常见风格,如私有、受保护等。

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

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

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

However, the interviewer was not satisfied, and told me that this description represented "bookish knowledge".

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

He asked me for a more practical response, explaining when I would choose an abstract class over an interface, using practical examples.

他要求我给出更实际的答复,并使用实际示例解释了我何时会选择抽象类而不是接口

Where did I go wrong?

我哪里做错了?

回答by VictorCreator

Your explanation looks decent, but may be it looked like you were reading it all from a textbook? :-/

你的解释看起来不错,但可能看起来你是从教科书中读到的?:-/

What I'm more bothered about is, how solid was your example? Did you bother to include almostall the differences between abstract and interfaces?

我更担心的是,你的例子有多可靠?您是否费心包括抽象和接口之间的几乎所有差异?

Personally, I would suggest this link: http://mindprod.com/jgloss/interfacevsabstract.html#TABLE

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

for an exhaustive list of differences..

有关差异的详尽列表..

Hope it helps you and all other readers in their future interviews

希望它对您和所有其他读者在未来的采访中有所帮助

回答by Niklas

An interface is a "contract" where the class that implements the contract promises to implement the methods. An example where I had to write an interface instead of a class was when I was upgrading a game from 2D to 3D. I had to create an interface to share classes between the 2D and the 3D version of the game.

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

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

Then I can implement the methods based on the environment, while still being able to call those methods from an object that doesn't know which version of the game that is loading.

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

public class Adventure extends JFrame implements Playable

public class Adventure extends JFrame implements Playable

public class Dungeon3D extends SimpleApplication implements Playable

public class Dungeon3D extends SimpleApplication implements Playable

public class Main extends SimpleApplication implements AnimEventListener, ActionListener, 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;
    }

回答by Shailesh Saxena

Nothing is perfect in this world. They may have been expecting more of a practical approach.

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

But after your explanation you could add these lines with a slightly different approach.

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

  1. 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.

  2. 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).

  3. Abstract classes may contain abstract declarations, concrete implementations, or both.

  4. 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).

  5. 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.

  1. 接口是规则(规则,因为你必须给它们一个你不能忽视或避免的实现,所以它们像规则一样被强加),它作为软件开发中各个团队之间的共同理解文档。

  2. 接口提供了要做什么的想法,但没有提供如何完成的想法。因此,通过遵循给定的规则(意味着给定的方法签名),实现完全取决于开发人员。

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

  4. 抽象声明就像要遵循的规则,而具体的实现就像指导方针(您可以按原样使用它,也可以通过覆盖并提供您自己的实现来忽略它)。

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

Edit:Java 8 facilitates to define default and static methods in interface.

编辑:Java 8 有助于在接口中定义默认和静态方法。

public interface SomeInterfaceOne {

    void usualAbstractMethod(String inputString);

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

Now when a class will implement SomeInterface, it is not mandatory to provide implementation for default methods of interface.

现在当一个类将实现 SomeInterface 时,不需要为接口的默认方法提供实现。

If we have another interface with following methods:

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

public interface SomeInterfaceTwo {

    void usualAbstractMethod(String inputString);

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

}

Java doesn't allow extending multiple classes because it results in the “Diamond Problem”where compiler is not able to decide which superclass method to use. With the default methods, the diamond problem will arise for interfaces too. Because if a class is implementing both

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

SomeInterfaceOne and SomeInterfaceTwo

and doesn't implement the common default method, compiler can't decide which one to chose. To avoid this problem, in java 8 it is mandatory to implement common default methods of different interfaces. If any class is implementing both the above interfaces, it has to provide implementation for defaultMethod() method otherwise compiler will throw compile time error.

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

回答by Daniel Lerps

You made a good summary of the practical differences in use and implementation but did not say anything about the difference in meaning.

您对使用和实现中的实际差异做了很好的总结,但没有说明含义上的差异。

An interfaceis a description of the behaviour an implementing class will have. The implementing class ensures, that it will have these methods that can be used on it. It is basically a contract or a promise the class has to make.

一个接口是行为实现的类都会有一个描述。实现类确保它将具有可以在其上使用的这些方法。它基本上是班级必须做出的合同或承诺。

An abstract classis a basis for different subclasses that share behaviour which does not need to be repeatedly created. Subclasses must complete the behaviour and have the option to override predefined behaviour (as long as it is not defined as finalor private).

一个抽象类是针对不同的子类份额行为,不需要重复创建的基础。子类必须完成行为并且可以选择覆盖预定义的行为(只要它没有定义为finalprivate)。

You will find good examples in the java.utilpackage which includes interfaces like Listand abstract classes like AbstractListwhich already implements the interface. The official documentationdescribes the AbstractListas follows:

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

This class provides a skeletal implementation of the List interface to minimize the effort required to implement this interface backed by a "random access" data store (such as an array).

此类提供 List 接口的骨架实现,以最大限度地减少实现由“随机访问”数据存储(例如数组)支持的此接口所需的工作。

回答by Adrian

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.

此外,我对这个问题的回答更多是关于面试技巧,而不是你提供的技术材料。也许考虑阅读它。https://workplace.stackexchange.com/是处理此类事情的绝佳场所。

回答by Vimal Bera

I will give you an example first:

我先给大家举个例子:

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

Suppose you have 3 databases in your application. Then each and every implementation for that database needs to define the above 2 methods:

假设您的应用程序中有 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
}

But what if encryptPassword()is not database dependent, and it's the same for each class? Then the above would not be a good approach.

但是如果encryptPassword()不依赖于数据库,并且每个类都相同呢?那么上面的方法就不是一个好方法。

Instead, consider this approach:

相反,请考虑这种方法:

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();
}

Now in each child class, we only need to implement one method - the method that is database dependent.

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

回答by MaheshVarma

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

您选择 Java 中的接口来避免多重继承中钻石问题

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.

如果您已经知道什么是共同点,则可以选择抽象类。例如拿一个抽象类Car。在更高级别上,您可以实现常见的汽车方法,例如calculateRPM(). 这是一种常见的方法,您可以让客户实现他自己的行为等
calculateMaxSpeed()。您可能会通过提供您在日常工作中遇到的几个实时示例来解释。

回答by user2822053

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

单击此处观看有关接口和抽象类的教程

回答by Marz

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.

据我了解,一个Interface由final变量和方法组成,没有实现,是通过一个类来实现,得到一组相互关联的方法或方法。另一方面,抽象类可以包含非最终变量和具有实现的方法,通常用作指南或作为所有相关或相似类继承的超类。换句话说,抽象类包含其所有子类共享的所有方法/变量。

回答by Marz

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.

我观察到的主要区别是抽象类为我们提供了一些已经实现的常见行为,而子类只需要实现与它们相对应的特定功能。其中 as for 接口只会指定需要完成哪些任务,接口不会给出任何实现。我可以说它指定了它自己和实现的类之间的契约。