编码到接口被认为是一种很好的做法,允许以后更改对象而不影响程序行为的可能性,但为什么我们需要更改某些东西,如果它没有效果?我理解这种做法给出的灵活性,我只是不明白这个定义。
答案 0 :(得分:2)
他们意味着您可以更改该类的实现,并且您将100%确定更改后该程序的其余部分未被破坏。因为您不会在该类实现之外更改单行。当然你可以打破执行。
答案 1 :(得分: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
的实现,只要它仍然“格栅”(例如,您从中等稀有到中等),您就不需要更改{{1}中的代码1}}
这是使用明确定义的界面的好处之一。只要MakeASteak
方法执行它应该执行的操作,其调用者就不需要知道 它是如何做的。
第二个版本完全不同。这是人们在说“程序到界面”时所想到的。它允许人们添加:
Grill
并致电
class HomeCook implements ICooking
{
void Chop()
{
...
}
void Grill()
{
...
}
// other cooking functions
}
因此,如果HomeCook AverageJoe;
MakeASteak( AverageJoe );
函数仅使用MakeASteak
中定义的方法,那么它不仅不关心如何实现ICooking
函数,它也不关心 对象实现接口。
您也可以使用复杂的对象:
ICooking
并像以前一样使用它:
Class ComplicatedPerson implements ICooking, IWriting, IActing, ISwimming
{
}
另一个例子是使用迭代器的ComplicatedPerson person;
MakeASteak( person );
算法。库编写器只需要知道迭代器“迭代”并且可以专注于算法本身。负责编写std
或vector
的迭代器代码的程序员可以专注于他的代码,而不必担心set
算法细节。如果两个程序员都正确地完成了他们的工作,那么无论什么容器提供迭代器,算法都是可用的。