我最近接受了两次电话采访,被问及接口类和抽象类之间的区别。我已经解释了我能想到的每一个方面,但似乎他们在等我提一些具体的事情,我不知道是什么。

根据我的经验,我认为以下是正确的。如果我遗漏了一个要点,请告诉我。

接口:

接口中声明的每个方法都必须在子类中实现。接口中只能存在事件、委托、财产(C#)和方法。一个类可以实现多个接口。

抽象类:

子类只能实现抽象方法。抽象类可以具有具有实现的普通方法。除了事件、委托、财产和方法之外,抽象类还可以有类变量。由于C#中不存在多重继承,一个类只能实现一个抽象类。

在这之后,面试官提出了一个问题:“如果你有一个只有抽象方法的抽象类呢?这和接口有什么不同?”我不知道答案,但我认为这是上面提到的继承,对吧?另一位面试官问我,“如果你在接口中有一个公共变量,那会和抽象类中有什么不同?”我坚持认为你不能在接口中使用公共变量。我不知道他想听什么,但他也不满意。

另请参阅:

何时使用接口而不是抽象类,反之亦然接口与抽象类如何决定使用抽象类和接口?接口和抽象类之间的区别是什么?


当前回答

从我的另一个答案来看,主要是关于何时使用一个而不是另一个:

根据我的经验,界面是最好的有几个类时使用每个都需要对相同的方法,以便可由其他代码互换使用将针对这些类的公共接口。最好的当协议很重要,但底层逻辑可能不同于每个类别。如果你不是复制逻辑,考虑抽象类或标准类继承相反

其他回答

简而言之:抽象类用于建模类似类的类层次结构(例如,Animal可以是抽象类,Human、Lion、Tiger可以是具体的派生类)

AND

接口用于2个相似/非相似类之间的通信,这些类不关心实现接口的类的类型(例如,Height可以是接口属性,它可以由Human、Building、Tree实现。无论你能不能吃东西,你能不能游泳,你能死什么都不重要。重要的是你需要有Height(在你的类中实现))。

接口:-==合约。无论哪个类实现它都必须遵循接口的所有规范。

一个实时的例子是任何ISO标记的产品。ISO给出了一套规则/规范,说明产品应该如何构建以及它必须具备的最小功能集。

这只是产品必须具备的财产的子集。SO只有在产品满足其标准时才会签署产品。

现在看看这个代码

public interface IClock{       //defines a minimum set of specification which a clock should have

    public abstract Date getTime();
    public abstract int getDate();
}
public class Fasttrack: Clock {
    // Must have getTime() and getTime() as it implements IClock
    // It also can have other set of feature like 
    public void startBackgroundLight() {
        // watch with internal light in it.
    }
    .... //Fastrack can support other feature as well
    ....
    ....
}

在这里,Fastrack被称为手表,因为它具有手表必须具备的所有功能(最小功能集)。

原因和时间摘要:

来自MSDN:

抽象类的目的是提供多个派生类可以共享的基类的公共定义。

例如,类库可以定义一个抽象类,该抽象类用作其许多函数的参数,并要求使用该库的程序员通过创建派生类来提供自己的类实现。抽象只是指如果你不能定义它,就将它完全声明为抽象。实现类将完成这个实现。

例如:假设我声明一个类配方是抽象的,但我不知道该是哪个配方然后我将推广这个类来定义任何菜谱的通用定义。菜谱的植入将取决于菜品的实现。

抽象类既可以由抽象方法组成,也可以由非抽象方法组成。因此,您可以注意到接口中的差异。因此,实现类不一定必须具有每个方法。您只需要重写抽象方法。

简单来说,如果您想要紧密耦合,请使用接口o/w,以防失去耦合抽象类

第二个问题的答案:接口中定义的公共变量默认为静态final,而抽象类中的公共变量为实例变量。

虽然您的问题表明它是针对“通用OO”的,但它似乎真正关注的是.NET对这些术语的使用。

在.NET中(类似于Java):

接口可以没有状态或实现实现接口的类必须提供该接口的所有方法的实现抽象类可以包含状态(数据成员)和/或实现(方法)抽象类可以在不实现抽象方法的情况下继承(尽管这样的派生类本身是抽象的)接口可能是多继承的,抽象类可能不是(这可能是接口与abtract类分开存在的关键具体原因——它们允许实现多继承,从而消除了一般MI的许多问题)。

作为通用OO术语,差异不一定定义明确。例如,有些C++程序员可能持有类似的严格定义(接口是抽象类的严格子集,不能包含实现),而有些人可能会说,具有某些默认实现的抽象类仍然是接口,或者非抽象类仍然可以定义接口。

事实上,有一种叫做非虚拟接口(NVI)的C++习惯用法,其中公共方法是“thunk”到私有虚拟方法的非虚拟方法:

http://www.gotw.ca/publications/mill18.htmhttp://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-虚拟界面(_I)

After all that, the interviewer came up with the question "What if you had an 
Abstract class with only abstract methods? How would that be different
from an interface?" 

文档明确指出,如果抽象类只包含抽象方法声明,则应将其声明为接口。

An another interviewer asked me what if you had a Public variable inside
the interface, how would that be different than in Abstract Class?

默认情况下,接口中的变量是公共静态变量和最终变量。问题的框架可以是,如果抽象类中的所有变量都是公共的呢?与接口中的变量不同,它们仍然可以是非静态和非最终的。

最后,我想对上面提到的内容再补充一点——抽象类仍然是类,属于单个继承树,而接口可以存在于多个继承中。