【问题标题】:The point of an Interface [duplicate]接口的点[重复]
【发布时间】:2011-04-27 15:29:30
【问题描述】:

可能重复:
How will I know when to create an interface?

我想知道使用接口的意义。

你使用接口吗?如果是这样,您什么时候决定使用它们,什么时候决定不使用它们?

我目前已经为我的服务层和存储库层定义了接口,但我想知道我是否错过了其他有用的地方。

我想我只是不完全理解他们的目的。

【问题讨论】:

标签: design-patterns oop interface class-design


【解决方案1】:

界面就像一个规则列表。您指定一个类的要求,并且对于任何实现此接口的类,您知道它们将遵循这些规则。您可以将这些类转换为此接口类型,并在知道它们具有您认为需要的方法、属性和事件的情况下对它们进行操作。

ASP.Net 中一些重要的接口有:

  • ICallbackEventHandler
  • 一次性使用

我最近创建了自己的接口,当时我想确保用于特定目的的所有类都有特定的方法和事件。知道了这一点,我可以首先通过强制转换和验证来检查它是否实现了接口:

IMyInterface myinterface = myclass as IMyInterface;
if (myinterface == null)
{
    //did NOT implement the interface
}
else
{
    //did implement the interface
    //call the method we KNOW is there.
    myinterface.MyMethod(myparemeter);
}

【讨论】:

    【解决方案2】:

    一个接口定义了一个契约。任何实现接口的类都必须履行该契约。这意味着该类必须实现接口中定义的方法。

    一个接口基本上说“我正在定义所有实现者必须做的事情。我不在乎如何你做到了,但你必须支持我指定的这些操作”。

    接口的另一个用途是您可以在方法签名或类型定义中使用它们来指定对象的最通用类型。例如,在 Java 中,Map 是一个由其他类实现的接口,例如 HashMapLinkedHashMapHashMapLinkedHashMap 本质上都是 Map 类型。它们实现相同的方法,但做事不同(LinkedHashMap 保留插入顺序)。

    考虑您有一个接受地图的方法的情况。如果您没有接口,则需要为每种类型的地图指定一个方法。实际上,您可以通过重载方法来做到这一点,但这种方法不是很好。更好的方法是将方法参数的类型指定为Map。然后,任何实现Map 的类都可以传入该方法。这样,您不必为每种类型的地图指定方法,而且您也不会将使用您方法的人限制在地图的特定实现中。

    接口还保证指定的功能存在于实现类中。因此,它还提供了访问该功能的标准方法。在设计 API 时,接口也很有用(这样您就可以为要公开的内容指定标准接口)。

    接口的另一个好处是它使重构变得容易。假设您要切换出某种对象的实现。该对象可能是一个方法参数,也可能是一个类属性。由于您已将该参数或对象键入为接口,因此您可以简单地创建一个实现该接口的新类并传递该类。由于您使用了接口,因此您没有对类的细节做出额外的假设。该接口抽象出您正在使用的类的实现细节。这样,您最终不会做出使您的代码与特定实现紧密耦合的假设。

    总而言之,接口是关于抽象契约的。使用 abstraction,您可以隐藏底层细节并仅公开您需要公开的最低限度。这样,使用你的类或接口的人就不会被实现细节所累。所有这些信息都巧妙地隐藏在实现接口的特定类中。 合同确保全面标准化;使用该接口的人确信所有实现该接口的类都公开相同的方法。

    【讨论】:

    • 很好的解释...在我的问题结束之前给你检查 ;-)
    【解决方案3】:

    接口是用来告诉别人一个类做某事的。

    例如如果你有一个实现IInjurableSoccerPlayer 类——你从类代码的第一行知道,SoccerPlayer 实例知道受伤时该怎么做(你可能在连字符之后就知道了)。

    现在考虑实现 IEnumerableIQueryableIDisposable 会告诉您有关对象的信息,而这对实现本身一无所知..
    好像很多..

    【讨论】:

      【解决方案4】:

      许多其他答案遗漏的一点是接口允许非常有限的多重继承形式,因为两个或多个不相关的类可以实现一个公共接口,并且代码可以接受实现该接口的对象,而不考虑其他任何关于他们的类型。否则,代码接受多种类型的对象并利用任何通用功能的唯一方法是让它们都从一个本身实现此类功能的通用基类型下降。

      【讨论】:

      • 在谷歌搜索“为什么接口有用”一小时后,这个简短的、没有示例的解释终于让我明白了。
      • @Tom:我不知道为什么很少提到这一点。能够拥有一个对象,该对象可以提供给需要 X 的代码,也可以提供给需要 Y 的代码,而这些类型不必相关,这是有用的。如果一个类派生自两个中级类,这两个中级类从一个公共基础定义但以不同方式覆盖其中一个方法,则完全多重继承可能会导致语义困难。接口不会遇到这个问题,因为虽然接口 W 可以从 X 和 Y 派生,这两者都从 Z 派生,但 X 和 Y 都不能覆盖 Z 的任何方法。
      【解决方案5】:

      正如其他人所说,接口定义了可以由类和结构实现的协定。这允许像对象继承这样的接口启用多态性。

      然而实现一个接口不同于从一个对象继承

      1. 结构可以实现它们。
      2. 接口不能有实现。
      3. 可以实现多个接口。这可以实现一种没有相关问题的多重继承(无论好坏,C# 都没有实现多重继承)

      所以一般来说,如果你想要多态并且你想要它,那么接口是好的

      1. 结构
      2. 共享实现没有意义或可能导致脆弱的基类
      3. 目标类上已经存在对象继承

      标准示例是 IDisposable、IComparable 和 IEnumerable,它们显示了最明显的用途。

      要避免的一些事情是标记接口(没有方法的接口)和不受支持的接口。由系统。例如您有 IPost、BasePost、Question、Answer 和 Comment,但系统只使用 BasePost。

      【讨论】:

        猜你喜欢
        • 2011-08-24
        • 2012-05-26
        • 2015-10-16
        • 1970-01-01
        • 2015-03-10
        • 2016-06-26
        • 2014-12-31
        • 2021-08-10
        相关资源
        最近更新 更多