【发布时间】:2010-11-10 15:26:44
【问题描述】:
最近几天,我经常遇到“实现接口”这个词……我知道它是什么意思,但我想了解更多信息和一些关于它的资源。类什么时候实现接口?
【问题讨论】:
-
这是一个骗局……更不用说如果被问到 Google 会找到无数非 SO 来源。
-
那你为什么不提供链接呢?
标签: design-patterns class interface
最近几天,我经常遇到“实现接口”这个词……我知道它是什么意思,但我想了解更多信息和一些关于它的资源。类什么时候实现接口?
【问题讨论】:
标签: design-patterns class interface
接口是一种约定,它指定类必须创建的一组必需方法。
例如:
public interface ITest
{
public void DoSomething(int someInt);
}
public class MyClass : ITest
{
public void DoSomething(int someInt)
{
... Do some stuff
}
}
如果没有包含DoSomething 方法,编译器会抛出错误。
【讨论】:
实现接口是什么意思?
也许我们最好先从接口是什么开始,然后再研究实现接口的含义。
示例 #1:
世界上每一家麦当劳都有一定的共同点。事实上,如果您想经营一家麦当劳特许经营店,您必须遵守他们的特许经营规则:
这是他们的规则。它在合同中。每家餐厅都必须遵守该合同。每家餐厅略有不同,但在上面的规则上是相同的。
这对客户来说也是一件非常好的事情。如果你走进世界上任何一家麦当劳餐厅,你肯定会知道你可以买到一个巨无霸。
麦当劳与接口有什么关系?
“接口”只不过是一份合同。任何“执行”或签订合同的餐厅,都必须遵守。或者换句话说,任何实现了麦当劳加盟商接口的餐厅,都必然会效仿。
为什么叫麦当劳的界面而不是麦当劳的界面?
当您命名接口时,通常的做法是名称以“I”开头。
示例 #2
世界上所有的位面都有一定的共性,不管是什么类型。也就是说,它们都实现了Iplane接口。
IPlane 接口规定任何实现它的平面必须具有:
因此,如果波音 737 遵循这些规则,作为客户,您可以保证您购买的飞机将有翅膀并且会飞。以下是波音 737 实现上述接口的示例:
public interface IPlane
{
void Fly();
void HasTWoWings();
void Engine();
}
class Boeing737 : IPlane // <-------------- the Boeing 737 implements the interface
{
// this means that the Boeing737 MUST have a fly, hastwowings and an engine method.
// the interface doesn't specify HOW the plane must fly. So long as it does fly
// the compiler doesn't care.
public void Fly()
{
Console.WriteLine("Come fly with me, let's fly, let's fly awaaaaaaaay");
}
public void HasTWoWings()
{
Console.WriteLine("I've got two wings");
}
public void Engine()
{
Console.WriteLine("BRrrrrrrrooooooooooooooooooooooooooooooooom!");
}
}
希望对大家有所帮助。
那么这个有什么用呢?
例如,如果您是想要预订飞机的乘客,这将变得非常方便。您不确定哪些飞机可供您使用。而且你并不在乎,只要它们是飞机,只要它们会飞,并且有两个机翼和一个引擎。当你在机场时,你可能会得到一架波音,或者你可能会得到一架空中客车,或者你可能会得到一个 Stig - 但你知道,无论你得到什么实际的飞机,他们都会做某项工作。它们的飞行方式可能不同,但它们都会飞。
这使您能够以这样的方式编写代码,以最大限度地降低维护成本,并使其更容易修改而不会导致错误。
【讨论】:
接口是类必须实现的功能规范。当你实现一个接口时,你是在向你的类的任何消费者指定你提供给定接口中定义的功能。例如(在 C# 中):
public interface ISearchable
{
List<object> Search(string query);
}
ISearchable 是一个接口,它指定了一个方法,理论上,该方法应该为类提供一些搜索功能。现在,任何想要实现搜索功能的类都可以实现ISearchable 接口:
public class ConcreteSearchable : ISearchable
{
public List<object> Search(string query)
{
// Implementation
}
}
您现在有了一个实现ISearchable 接口的类。这提供了几个好处。一方面,您已经明确声明了类行为的某个部分。其次,您现在可以多态地处理您的类(和接口的其他实现)。
例如,如果有许多类型实现了ISearchable 接口,您可以创建一个SearchableFactory,它将基于某些参数构造一个具体类型。工厂的消费者不会关心具体的类型......只要他们可以搜索它:
public class SearchableFactory
{
public static ISearchable CreateInstance(string query)
{
if(query.Contains("SELECT"))
return new SqlSearchable();
else
return new ConcreteSearchable();
}
}
【讨论】:
接口是类需要实现的方法列表。这是一种将类的工作方式与类提供的服务分离的方法。
您可以想象一个 Stack 数据结构。它的界面中可能有以下内容:
push(Node);
Node pop();
Node peek();
现在,如果您使用数组来实现堆栈,您将在数组中保存索引并使用它来执行操作。如果你有一个链表,你只需保留一个指向头部的指针。接口的重点是,只要您的实现提供所需的方法,您的实现的用户就不需要知道您的实现类是如何工作的。
Java 和 C# 等一些语言提供明确的 interfaces。其他的,如 ruby 或 python,允许你使用相同的技术,但不要用关键字强制它。您可能会听到Duck Typing 一词。这是一种说法,如果某个东西实现了正确的接口,那么无论实现如何,它都可以使用。
【讨论】:
接口增加了代码的透明度。接口定义了由类实现的契约。假设我告诉你,你可以成为我帮派的一员,但你需要一直穿绿衬衫。如果您说是,那么您正在执行合同,现在您必须始终穿绿色衬衫。
【讨论】:
接口通常是对函数的描述,它们需要什么作为参数以及它们将返回什么。描述如何使用函数以及期望从它们返回什么。
实现一个接口意味着实际编写一些代码来实现接口的描述,包括函数名、属性和返回值。
【讨论】: