【问题标题】:Why are interfaces useful? (OOP)为什么接口有用? (哎呀)
【发布时间】:2013-04-11 01:24:44
【问题描述】:

我已经了解了实现和接口的基础知识。我不明白什么时候使用接口。有接口需要什么条件?

例子:

/// Interface demo
Interface IDemo
{
    // Function prototype
    public void Show();
}

// First class using the interface
Class MyClass1 : IDemo
{
public void Show()
{
    // Function body comes here
    Response.Write("I'm in MyClass");
}
}

// Second class using the interface
Class MyClass2 : IDemo
{
public void Show()
{
    // Function body comes here
    Response.Write("I'm in MyClass2");
    Response.Write("So, what?");
}
}

这两个类具有相同的函数名和不同的主体。这也可以在没有接口的情况下实现。有方法参考的目的是什么?当我扩展一个超类时,至少我得到了超类的属性和方法。

请给我一个清晰的解释和一个真实世界的场景,以便我很好地理解。

【问题讨论】:

    标签: oop interface implements


    【解决方案1】:

    首先,他们为用户提供合同,因此用户不需要知道使用了什么底层实现,而只需要知道合同。这会在底层实现发生变化时产生松散耦合。

    现实世界的例子

    通过这种方式,我们可以使用某些模式,例如策略和命令模式:Using a strategy pattern and a command pattern

    Real World Example of the Strategy Pattern

    Real world example of application of the command pattern

    抽象类和接口的区别

    其中大部分内容都与抽象类有关,请参阅此处了解不同之处:Interface vs Abstract Class (general OO)

    【讨论】:

      【解决方案2】:

      如果你需要多重继承,你需要一个接口。

      假设您有一个需要可比较的类和一个列表。由于在某些语言中只能继承一个类,为了向编译器证明它同时具有 Comparable 的 compareTo() 方法和 List 的 add() 方法,就需要接口。这是最简单的解释,但我相信其他人会给出更多理由。

      在某些情况下,接口也使多重继承更容易,因为“在后台”没有任何事情发生。他们只在方法方面指定对象需要提供什么。

      【讨论】:

      • (这是一个 java 示例,但 CSharp 类似)
      【解决方案3】:

      使用接口的两个原因:

      1. 您需要多重继承,而您的编程语言不支持它(例如 Java、C#)。在这种情况下,您在派生类中继承的大多数(除了一个)基类都需要定义为接口类。

      2. 您希望使用某个类的多个实现。在这种情况下,类可以是抽象类或接口。您的客户端提供此类的特定具体实现,它可能因客户端而异。接口(或抽象类)要求每个实现都具有相同的行为(方法)。

      【讨论】:

        【解决方案4】:

        我认为使用接口最重要的原因之一是类型匹配。通过对接口而不是实现进行编程,您的程序可以更加灵活。

        你可以看看不同的设计模式(我建议你从策略模式开始,http://en.wikipedia.org/wiki/Strategy_pattern#Example)我想你会立刻明白程序到接口如何让你的代码更加灵活。

        希望这能有所帮助。

        【讨论】:

          【解决方案5】:

          大部分功能来自于一个对象可以被接口类型的变量引用。这是微妙的变化强大。

          private foo()
          {
               IDemo demoOne = new MyClass1();
               IDemo demoTwo = new MyClass2();
          }
          

          这可以变得非常强大,因为您可以封装不同的行为。例如:

          private foo(bool option)
          {
               IDemo demo = option ? new MyClass1() : new MyClass2();
          }
          
          private bar (IDemo demo)
          {
               demo.Show();
          }
          

          现在 bar 可以使用 IDemo 对象,而不必知道传入哪个 IDemo 的具体实现。关于使用哪个实现的决定封装在 foo 方法中。在这样一个简单的例子中,这似乎没什么大不了的。如果您查看 tigger 的答案中发布的链接,您会发现这在哪里变得非常有用。

          这特别有用的一种情况是单元测试。你可以有一个业务逻辑类,它接受一个数据层对象的接口。当应用程序运行时,业务逻辑类被传递一个真实数据层对象的实例。当类被单元测试时,它被传递一个返回测试数据的对象的实例。这允许单元测试以可预测的数据输入运行。这在依赖注入中是已知的。

          另一个有用的情况是当您想要与框架或第三方代码交互时。假设您要实现自定义集合。如果您的类实现了 IEnumerable 接口,则可以在 foreach 循环中遍历集合中的项目。框架不需要知道您的类如何存储项目或项目中的内容,但如果它知道您实现了 IEnumerable,它可以允许您使用 foreach 循环。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-06-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-02-23
            • 1970-01-01
            • 1970-01-01
            • 2015-04-03
            相关资源
            最近更新 更多