我已经多次看到这句话,但我不清楚它的含义。您何时以及为什么要这样做?
我知道接口的作用,但我不清楚这一点让我觉得我错过了正确使用它们的机会。
如果你这样做是不是这样:
IInterface classRef = new ObjectWhatever()
您可以使用任何实现的类IInterface?你什么时候需要这样做?我唯一能想到的是,如果您有一个方法并且您不确定将传递什么对象,除了它实现IInterface。我想不出你需要多久这样做一次。
IInterface
另外,你怎么能写一个方法来接受一个实现接口的对象呢?那可能吗?
这里有一些关于接口和松散耦合代码、控制反转等问题的精彩答案。有一些相当令人兴奋的讨论,所以我想借此机会将事情分解一下,以了解为什么接口有用。
当我第一次接触接口时,我也对它们的相关性感到困惑。我不明白你为什么需要它们。如果我们使用像 Java 或 C# 这样的语言,我们已经有了继承,我将接口视为一种 较弱 的继承形式,并想,“何必呢?” 从某种意义上说,我是对的,您可以将接口视为一种弱继承形式,但除此之外,我最终通过将它们视为对由可能有许多不相关的对象类别。
例如——假设你有一个 SIM 游戏并且有以下类:
class HouseFly inherits Insect { void FlyAroundYourHead(){} void LandOnThings(){} } class Telemarketer inherits Person { void CallDuringDinner(){} void ContinueTalkingWhenYouSayNo(){} }
显然,这两个对象在直接继承方面没有任何共同之处。但是,你可以说他们都很烦人。
假设我们的游戏需要有某种随机 的东西 ,在玩家吃晚餐时会惹恼他们。这可能是 aHouseFly或 aTelemarketer或两者兼有——但是如何通过一个函数同时允许两者?您如何要求每种不同类型的对象以相同的方式“做他们烦人的事情”?
HouseFly
Telemarketer
实现的关键是 aTelemarketer和HouseFly共享一个共同的松散解释的行为,即使它们在建模方面完全不同。所以,让我们创建一个两者都可以实现的接口:
interface IPest { void BeAnnoying(); } class HouseFly inherits Insect implements IPest { void FlyAroundYourHead(){} void LandOnThings(){} void BeAnnoying() { FlyAroundYourHead(); LandOnThings(); } } class Telemarketer inherits Person implements IPest { void CallDuringDinner(){} void ContinueTalkingWhenYouSayNo(){} void BeAnnoying() { CallDuringDinner(); ContinueTalkingWhenYouSayNo(); } }
我们现在有两个类,每个类都可能以自己的方式令人讨厌。而且它们不需要从相同的基类派生并共享共同的固有特征——它们只需要满足契约IPest——契约很简单。你只需要BeAnnoying。在这方面,我们可以建模以下内容:
IPest
BeAnnoying
class DiningRoom { DiningRoom(Person[] diningPeople, IPest[] pests) { ... } void ServeDinner() { when diningPeople are eating, foreach pest in pests pest.BeAnnoying(); } }
这里我们有一个餐厅,可以容纳一些食客和一些害虫——注意界面的使用。这意味着在我们的小世界中,pests数组的成员实际上可以是Telemarketer对象或HouseFly对象。
pests
该ServeDinner方法在提供晚餐并且我们在餐厅的人应该吃饭时调用。在我们的小游戏中,这就是我们的害虫工作的时候——每个害虫都被指示通过IPest界面变得烦人。通过这种方式,我们可以很容易地同时拥有两者Telemarketers,并HouseFlys以各自的方式令人讨厌——我们只关心我们在DiningRoom对象中有什么是害虫,我们并不真正关心它是什么,他们可能什么都没有与其他共同。
ServeDinner
Telemarketers
HouseFlys
DiningRoom
这个非常人为的伪代码示例(拖得比我预期的要长得多)只是为了说明最终在我们何时可以使用界面方面为我打开了灯的那种东西。我提前为这个例子的愚蠢道歉,但希望它有助于你的理解。而且,可以肯定的是,您在这里收到的其他发布的答案确实涵盖了当今在设计模式和开发方法中使用接口的范围。