协慌网

登录 贡献 社区

接口与抽象类(通用 OO)

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

根据我的经验,我认为以下是正确的。如果我错过了重点,请告诉我。

接口:

在接口中声明的每个单独的方法都必须在子类中实现。接口中只能存在事件,代理,属性(C#)和方法。一个类可以实现多个接口。

抽象类:

只有抽象方法必须由子类实现。 Abstract 类可以有实现的常规方法。 Abstract 类还可以在 Events,Delegates,Properties 和 Methods 旁边有类变量。由于 C#中不存在多重继承,因此类只能实现一个抽象类。

  1. 毕竟,面试官想出了一个问题 “如果你有一个只有抽象方法的抽象类怎么办?那么它与界面会有什么不同?” 我不知道答案,但我认为这是上面提到的继承权吗?

  2. 另一位采访者问我,如果你在界面中有一个 Public 变量,那么它与 Abstract Class 有什么不同?我坚持认为你不能在界面中有一个公共变量。我不知道他想听到什么,但他也不满意。

另见

答案

怎么样比喻:当我在空军时,我去了飞行员训练,并成为美国空军(美国空军)的飞行员。那时我没有资格飞行任何东西,不得不参加飞机类训练。一旦我获得资格,我就是一名飞行员(抽象班)和一名 C-141 飞行员(具体班级)。在我的一项任务中,我获得了额外的职责:安全官。现在我仍然是一名飞行员和一名 C-141 飞行员,但我也履行了安全官职责(我实施了 ISafetyOfficer,可以这么说)。一名飞行员不需要担任安全官员,其他人也可以这样做。

所有美国空军飞行员都必须遵守某些空军规定,所有 C-141(或 F-16 或 T-38)飞行员都是 '美国空军飞行员'。任何人都可以成为安全官。所以,总结一下:

  • 飞行员:抽象课
  • C-141 飞行员:具体课程
  • 安全官员:界面

补充说明:这是一个类比,以帮助解释概念,而不是编码建议。请参阅下面的各种评论,讨论很有意思。

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

在. NET 中(类似于 Java):

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

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

实际上,有一种称为非虚拟接口(NVI)的 C ++ 习惯用法,其中公共方法是非虚拟方法,可以 “窃取” 私有虚拟方法:

我认为他们正在寻找的答案是基本或 OPPS 的哲学差异。

当派生类共享抽象类的核心属性和行为时,将使用抽象类继承。实际定义类的行为。

另一方面,当类共享外围行为时,使用接口继承,而不必定义派生类。

例如。汽车和卡车共享汽车抽象类的许多核心属性和行为,但它们也共享一些外围行为,如生成排气,甚至非汽车类如钻机或 PowerGenerators 共享,并不一定定义汽车或卡车,所以 Car,Truck,Driller 和 PowerGenerator 都可以共享 IExhaust 相同的界面。