0

对接口进行编码被认为是一种很好的做法,允许以后更改对象而不影响程序行为的可能性,但是如果它没有效果,为什么我们需要更改一些东西呢?我理解这种做法提供的灵活性,我只是不理解定义。

4

2 回答 2

2

它们意味着您可以更改该类的实现,并且您将 100% 确定更改后程序的其余部分没有损坏。因为您不会更改该类实现之外的任何一行。当然,您可以中断实现。

于 2013-05-25T20:19:38.730 回答
0

使用接口不仅允许您更改类的实现。它还允许您更改类本身。休息后的细节。

接口还有助于减少开发(和理解)复杂代码所需的脑力劳动。如果您可以清楚地定义程序的两个部分之间的交互,则可以在这两个部分上进行工作,而无需知道另一个部分如何实现接口。这种愉快的情况可以一直持续到两个部分都准备好组合在一起,这时称为“集成测试”的事情就会发生。

在上面描述的意义上,接口是一个相当抽象的概念。例如,函数的签名是“接口”。

其他形式的接口是使用interface关键字的构造(例如在 Java 或 C# 中)或具有纯虚拟方法的类(在 C++ 中)。当人们说“对接口编程”时,他们通常指的是这些结构。

不是世界上最好的例子,但假设我们有这个:

interface ICooking
{
void Chop();
void Grill();
// other cooking functions
}

这是由这个类实现的:

class Chef implements ICooking
{
void Chop()
{
...
}

void Grill()
{
...
}

// other cooking functions
}

现在你想编写一个制作牛排的函数。您将需要有人来操作厨房(即实施 ICooking 的人)。

你可以这样写函数:

void MakeASteak( Chef ThePersonWhoCooks )
{
...
}

并将其称为:

Chef Joe;

MakeASteak( Joe );

或者你可以这样写:

void MakeASteak( ICooking ThePersonWhoCooks )
{
...
}

并将其称为:

Chef Joe;

MakeASteak( Joe );

您应注意以下事项:

  • 你在两种情况下都调用MakeASteak完全相同

  • 您可以更改的实现Chef::Grill,只要它仍然“烧烤”(例如,您从中等稀有到中等),您就不需要更改代码MakeASteak

这是使用明确定义的接口的好处之一。只要该Grill方法完成了它应该做的事情,它的调用者就不需要知道它是如何做到的。

第二个版本完全不同。这是人们在说“接口编程”时想到的。它允许添加以下内容:

class HomeCook implements ICooking
{
void Chop()
{
...
}

void Grill()
{
...
}

// other cooking functions
}

并打电话

HomeCook AverageJoe;

MakeASteak( AverageJoe );

所以,如果MakeASteak函数只使用ICookingthen 中定义的方法,它不仅不关心函数是如何实现的ICooking,也不关心什么对象实现了接口。

然后,您还可以使用复杂对象:

Class ComplicatedPerson implements ICooking, IWriting, IActing, ISwimming
{
}

并像以前一样使用它:

ComplicatedPerson person;
MakeASteak( person );

另一个例子是std使用迭代器的算法。库编写者只需要知道迭代器“迭代”并且可以专注于算法本身。负责为 avector或 a编写迭代器代码的程序员set可以专注于他的代码,而不必担心binary search算法细节。如果两个程序员都正确地完成了他们的工作,那么无论哪个容器提供迭代器,算法都将可用。

于 2013-05-25T22:09:41.010 回答