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

以下是我的回答:

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.

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

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

我哪里错了?


当前回答

我为工作做面试,我也会不看好你的答案(抱歉,但我很诚实)。听起来你确实读过不同之处并修改了答案,但也许你从未在实践中使用过。

一个好的解释为什么你会使用每一种,比一个精确的解释差异要好得多。雇主最终希望程序员做一些他们不了解的事情,而这些事情很难在面试中展示出来。如果你申请的是技术或文档相关的工作,而不是开发人员的职位,你给出的答案会很好。

祝你以后面试顺利。

另外,我对这个问题的回答更多的是关于面试技巧,而不是你提供的技术材料。或许可以考虑读一读。https://workplace.stackexchange.com/是做这类事情的好地方。

其他回答

就连我也在多次面试中遇到过同样的问题,相信我,说服面试官会让你很痛苦。 如果我固有以上所有的答案,那么我需要增加一个关键点,使它更有说服力,并充分利用OO

如果你不打算在规则中进行任何修改,对于子类来说,在很长一段时间内,去接口,因为你不能在其中修改,如果你这样做,你需要在所有其他子类中进行更改,然而,如果你认为,你想重用功能,设置一些规则并使其开放修改,去抽象类。

想象一下,你使用了一个可消费的服务,或者你向世界提供了一些代码,你有机会修改一些东西,假设是一个安全检查 如果我是代码的消费者,并且在更新后的某个早上,我发现Eclipse中所有的读标记,整个应用程序都关闭了。 因此,为了避免这样的噩梦,请在接口上使用抽象

我想这会在一定程度上说服面试官……愉快的面试。

接口由单例变量(公共静态final)和公共抽象方法组成。当我们知道要做什么但不知道如何做时,我们通常更喜欢实时使用接口。

这个概念可以通过以下例子更好地理解:

考虑一个支付类。支付方式有很多种,比如PayPal,信用卡等。因此,我们通常将Payment作为接口,其中包含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
        //e.g. Paypal uses username and password for payment
    }
}
public class CreditCard implements Payment
{
    public void makePayment()
    {
        //some logic for CreditCard payment
        //e.g. CreditCard uses card number, date of expiry etc...
    }
}

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

当我们知道某些特性该做什么,而其他特性又知道如何执行时,我们就会选择一个抽象类。

考虑下面的例子:

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

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

还有其他不同之处,但这些都是面试官所期望的。希望这对你们有帮助。

是的,从技术上讲,你的回答是正确的,但你的错误之处在于,你没有向他们表明你理解选择其中一个的利弊。此外,他们可能担心将来升级时代码库的兼容性问题。这种类型的回答可能有帮助(除了你说的):

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

祝你下次面试好运!

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.

接口就像一组公开记录的具有某种影响的基因:DNA测试会告诉我是否有它们——如果我有,我可以公开让人们知道我是“携带者”,我的部分行为或状态将符合它们。(当然,我可能还有很多其他基因,这些基因提供的特征超出了这个范围。)

抽象类就像单性别物种的死去的祖先(*):她不能被复活,但一个活着的(即非抽象的)后代继承了她所有的基因。

为了扩展这个比喻,我们假设这个物种的所有成员都活到相同的年龄。这意味着一个死去的祖先的所有祖先也必须是死的——同样,一个活着的祖先的所有后代也必须是活着的。