Oop 我为什么要使用接口?

Oop 我为什么要使用接口?,oop,interface,Oop,Interface,我知道他们强迫你去实现一些方法,但我不明白你为什么要使用它们。有谁能给我一个很好的例子或解释我为什么要实现这个目标。这样做有很多原因。当您使用一个接口时,您已经准备好将来需要重构/重写代码。您还可以为简单的操作提供一种标准化的API 例如,如果您想编写一个像快速排序这样的排序算法,那么对任何对象列表进行排序所需的全部工作就是成功地比较两个对象。如果您创建一个接口,比如说ISortable,那么任何创建对象的人都可以实现ISortable接口,并且可以使用您的排序代码 如果您正在编写使用数据库存储

我知道他们强迫你去实现一些方法,但我不明白你为什么要使用它们。有谁能给我一个很好的例子或解释我为什么要实现这个目标。

这样做有很多原因。当您使用一个接口时,您已经准备好将来需要重构/重写代码。您还可以为简单的操作提供一种标准化的API

例如,如果您想编写一个像快速排序这样的排序算法,那么对任何对象列表进行排序所需的全部工作就是成功地比较两个对象。如果您创建一个接口,比如说ISortable,那么任何创建对象的人都可以实现ISortable接口,并且可以使用您的排序代码

如果您正在编写使用数据库存储的代码,并且您正在写入存储接口,那么您可以替换该代码


接口鼓励对代码进行更松散的耦合,这样您就可以拥有更大的灵活性。

对于希望充分利用多态性的面向对象系统来说,接口是绝对必要的

一个典型的例子可能是IVehicle,它有一个Move()方法。你可以有汽车、自行车和坦克等课程,它们实现了IVehicle。它们都可以移动(),您可以编写代码,而不关心它处理的是哪种车辆,只是为了让它可以移动()


一个具体示例:接口是指定其他人的代码必须满足的契约的好方法

如果我正在编写代码库,我可能会编写对具有特定行为集的对象有效的代码。最好的解决方案是在接口中指定这些行为(没有实现,只有描述),然后在我的库代码中使用对实现该接口的对象的引用

然后任何随机的人都可以出现,创建一个实现该接口的类,实例化该类的一个对象,并将其传递给我的库代码,期望它能够工作。注意:当然可以在忽略接口意图的情况下严格实现接口,因此仅实现接口并不能保证一切正常。愚蠢的人总能找到办法!:-)

另一个具体示例:两个团队在不同的组件上工作,必须合作。如果两个团队在第1天坐下来就一组接口达成一致,那么他们可以各奔东西,围绕这些接口实现他们的组件。团队A可以构建测试线束,模拟团队B的组件进行测试,反之亦然。并行开发,更少的bug

关键的一点是接口提供了一层抽象,这样您就可以编写忽略不必要细节的代码


大多数教科书中使用的典型示例是排序例程。只要有比较任意两个对象的方法,就可以对任意一类对象进行排序。因此,通过实现
IComparable
接口,您可以对任何类进行排序,该接口强制您实现一种比较两个实例的方法。所有排序例程都是为了处理对IComparable对象的引用而编写的,因此,一旦实现IComparable,就可以在类的对象集合上使用这些排序例程中的任何一个。

正如您所指出的,当您想要强制某人以某种格式进行排序时,接口是很好的

当数据不是特定格式可能意味着在代码中做出危险的假设时,接口是好的

例如,目前我正在编写一个将数据从一种格式转换为另一种格式的应用程序。我想强迫他们把这些领域放在一个新的位置,这样我就知道它们将存在,并且有更大的机会得到正确的实施。我不在乎是否有另一个版本出现,并且它没有为他们编译,因为更可能的是,无论如何都需要数据


因此很少使用接口,因为通常您可以做出假设,或者不需要数据来完成所需的工作。

接口仅定义接口。稍后,您可以定义方法(在其他类上),该方法接受接口作为参数(或者更准确地说,是实现该接口的对象)。通过这种方式,您的方法可以对多种对象进行操作,它们唯一的共同点是它们实现了该接口。

首先,它们为您提供了一个额外的抽象层。您可以说“对于此函数,此参数必须是具有这些参数的方法的对象”。您可能还希望以某种抽象的术语设置这些方法的含义,但允许您对代码进行推理。在duck-typed语言中,您可以免费获得。不需要显式的语法“接口”。然而,您可能仍然创建了一组概念接口,类似于契约(类似于契约式设计)

此外,接口有时用于不太“纯粹”的目的。在Java中,它们可以用来模拟多重继承。在C++中,可以使用它们来减少编译时间。 通常,它们会减少代码中的耦合。这是件好事


您的代码也可能更容易通过这种方式进行测试。

接口定义了契约,这是关键词

当您需要在程序中定义约定时,您可以使用接口,但您并不真正关心满足该约定的类的其余属性,只要它满足该约定即可

让我们看一个例子。假设您有一个方法,该方法提供对列表排序的功能。首先。。什么是列表?你真的在乎为了给列表排序它包含哪些元素吗?你的答案应该是否定的。。。例如,在.NET中,有一个名为IList的接口,它定义了列表必须支持的操作
void MoveAVehicle(IVehicle vehicle)
{
    vehicle.Move();
}
interface IComparable
{
  // Return -1 if this is less than CompareWith
  // Return 0 if object are equal
  // Return 1 if CompareWith is less than this
  int Compare(object CompareWith);
}
IComparable comp1 = list.GetItem(i) as IComparable;

if (comp1.Compare(list.GetItem(i+1)) < 0)
  swapItem(list,i, i+1)
interface Storable {
    function create($data);
    function read($id);
    function update($data, $id);
    function delete($id);
}
class Logger {
    Storable storage;

    function Logger(Storable storage) {
        this.storage = storage;
    }

    function writeLogEntry() {
        this.storage.create("I am a log entry");
    }
}
public interface IExample
{
    void Foo();
}

public class Example : IExample
{
    // explicit implementation syntax
    void IExample.Foo() { ... }
}

/* Usage */
Example e = new Example();

e.Foo(); // error, Foo does not exist

((IExample)e).Foo(); // success
IDbConnection connection = GetDatabaseConnectionFromConfig()
connection.Open()
// do stuff
connection.Close()
var animals = new IAnimal[] = {new Bear(), new Owl(), new Snake()} // here I can collect different objects in a single collection because they inherit from the same interface

foreach (IAnimal animal in animals) 
{
    Console.WriteLine(animal.Name)
    animal.Speak() // a bear growls, a owl hoots, and a snake hisses
    animal.Move() // bear runs, owl flys, snake slithers
}
When you need different classes to share same methods you use Interfaces.