这点我见过提过几次,但我不清楚是甚么意思。你什么时候为什么要这么做?
我知道接口是做什么的,但我不清楚这一点的事实使我认为我错过了正确使用它们。
如果你要做:
IInterface classRef = new ObjectWhatever()
您可以使用任何实现iinterface
的类?你什么时候需要这么做?我唯一能想到的是,如果您有一个方法,但您不确定会传递什么对象,除了它实现iinterface
。我想不出你需要多长时间这样做一次。
另外,如何编写一个方法来接受一个实现接口的对象呢?有可能吗?
这里有一些关于这些问题的精彩答案,这些问题涉及到各种关于接口、松散耦合代码、控制反转等等的非常详细的细节。有一些相当激动人心的讨论,所以我想利用这个机会把事情分解一下,以理解为什么接口是有用的。
当我刚开始接触接口时,我也对它们的相关性感到困惑。我不明白你为什么需要它们。如果我们使用的是像Java或C#这样的语言,我们已经有了继承,而我把接口看作是一种较弱的继承形式,并想,“何必费心呢?”从某种意义上说,我是对的,你可以把接口看作是一种弱的继承形式,但除此之外,我最终理解了它们作为一种语言构造的用途,把它们看作是一种对对象的许多潜在的非相关类所表现出的共同特征或行为进行分类的手段。
例如--假设您有一个SIM卡游戏,并且有以下类:
class HouseFly inherits Insect {
void FlyAroundYourHead(){}
void LandOnThings(){}
}
class Telemarketer inherits Person {
void CallDuringDinner(){}
void ContinueTalkingWhenYouSayNo(){}
}
显然,这两个对象在直接继承方面没有任何共同之处。但是,你可以说他们都很烦人。
比方说我们的游戏需要有某种随机的东西,当游戏玩家吃晚餐的时候会让他们感到恼火。这可能是housefly
或telemarketer
或者两者兼有--但是如何在一个函数中同时使用这两种功能呢?你如何要求每一个不同类型的对象以同样的方式“做他们讨厌的事情”?
要认识到的关键是,Telemarketer
和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
。在这方面,我们可以建模如下:
class DiningRoom {
DiningRoom(Person[] diningPeople, IPest[] pests) { ... }
void ServeDinner() {
when diningPeople are eating,
foreach pest in pests
pest.BeAnnoying();
}
}
这里,我们有一个餐厅,它接受了许多食客和许多害虫--请注意接口的使用。这意味着在我们的小世界中,pathers
数组的一个成员实际上可能是Telemarketer
对象或Housefly
对象。
servedinner
方法是在提供晚餐并且我们在餐厅的人应该吃饭的时候调用的。在我们的小游戏中,有害程序就是在这个时候完成它们的工作的--每个有害程序都通过ipest
接口被指示为令人讨厌的。这样,我们就可以很容易地使telemarketers
和houseflys
都以各自的方式令人讨厌--我们只关心diningroom
对象中有什么东西是有害的,我们并不真正关心它是什么,而且它们可能与其他对象没有任何共同之处。
这个非常做作的伪代码示例(拖得比我预想的要长得多)只是想要说明,在我们何时可以使用接口的问题上,什么事情最终为我打开了灯。我提前为这个例子的愚蠢道歉,但希望它有助于你的理解。而且,可以肯定的是,您在这里收到的其他贴出的答案确实涵盖了当今在设计模式和开发方法中使用接口的所有方面。
问题内容: 我已经看过几次了,但我不清楚它的含义。您何时以及为什么要这样做? 我知道接口的作用,但是我不清楚这一点,这让我觉得我错过了正确使用它们的机会。 如果要这样做,是否只是这样: 您可以使用任何实现的类吗?您什么时候需要这样做?我唯一能想到的是,如果您有一个方法并且不确定要实现的对象将传递什么对象。我想不出您需要多久这样做一次。 另外,如何编写一个方法来接受实现接口的对象?那可能吗? 问题答
问题内容: 接口允许您创建定义实现它的类的方法的代码。但是,您不能向这些方法添加任何代码。 抽象类使您可以做同样的事情,并向方法中添加代码。 现在,如果您可以使用抽象类实现相同的目标,为什么我们甚至需要接口的概念? 有人告诉我,它与从C ++到Java的OO理论有关,这是PHP的OO东西所基于的。这个概念在Java中有用但在PHP中没有用吗?这只是一种避免在抽象类中乱扔占位符的方法吗?我想念什么吗
在这段代码中,两个连接和断开是什么意思?导致停止,直到终止?
问题内容: 假设我们在A包中有A类,在B包中有B类。如果类A的对象引用了类B,则称这两个类在它们之间具有耦合。 为了解决这种耦合,建议在包A中定义一个接口,该接口由包B中的类实现。然后,类A的对象可以引用包A中的接口。这通常是“依赖倒置”的一个例子。 这是“在接口级别将两个类解耦”的示例。如果是,当两个类耦合时,它如何消除类之间的耦合并保持相同的功能? 问题答案: 让我们创建一个虚拟的例子。 套餐
问题内容: 在有效的Java书中,它指出: 语言规范保证,除非变量的类型或类型为[JLS,17.4.7],否则读写变量是原子的。 在Java编程或一般编程中,“原子”是什么意思? 问题答案: 这是一个示例,因为一个示例通常比冗长的解释更清晰。假设是类型为的变量。以下操作不是原子操作: 实际上,变量是使用两个单独的操作写入的:一个操作写入前32位,第二个操作写入后32位。这意味着另一个线程可能读取的
在有效Java书中,它指出: 语言规范保证,除非变量类型为或[JLS,17.4.7],否则读取或写入变量是原子的。 在Java编程或一般编程的背景下,“原子”是什么意思?