【问题标题】:when we need interface c# [duplicate]当我们需要接口 c# [重复]
【发布时间】:2012-08-02 14:30:58
【问题描述】:

可能重复:
Why would I want to use Interfaces? Why I need Interface?

我想知道何时何地使用它?

例如,

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?");
 }

这两个类具有相同的函数名称,但主体不同。 这甚至可以在没有接口的情况下实现。 那么为什么我们需要一个接口在哪里以及何时使用它呢?

【问题讨论】:

  • 请使用代码格式化按钮{ }
  • 你的例子太笼统了。您不会仅仅因为两个类具有相似的方法名称而对继承进行建模。
  • 为什么将其作为完全重复的对本身已关闭的问题关闭
  • @EricJ.:这不是一件坏事。增加链接网络,因此只需通过可能的重复和相关链接页面的“走链”,您就会看到很多问题 - 希望其中一个(及其答案)将以有助于 OP 的方式表达.

标签: c#


【解决方案1】:

在您的简单情况下,您可以通过使用实现show()(或者可能将其定义为抽象)的公共基类来实现与接口所获得的类似的东西。让我将您的通用名称更改为更具体的名称,EagleHawk,而不是 MyClass1MyClass2。在这种情况下,您可以编写类似的代码

Bird bird = GetMeAnInstanceOfABird(someCriteriaForSelectingASpecificKindOfBird);
bird.Fly(Direction.South, Speed.CruisingSpeed);

这使您可以编写可以处理任何 *Bird* 的代码。然后,您可以编写代码,使 Bird 执行其作用于它视为 Bird 的实例的操作(飞行、进食、产卵等)。无论 Bird 是否真的是 EagleHawk 或任何其他从 Bird 派生的东西,该代码都可以工作。

但是,当您没有真正的 is a 关系时,该范式开始变得混乱。假设您想编写在天空中飞行的代码。如果您编写该代码以接受 Bird 基类,则突然间很难改进该代码以在 JumboJet 实例上工作,因为虽然 Bird em> 和 JumboJet 肯定都可以飞,JumboJet 肯定不是 Bird

进入界面。

Bird(以及 EagleHawkdo 的共同点是它们都能飞.如果您编写上述代码而不是作用于接口 IFly,则该代码可以应用于任何提供该接口实现的东西。

【讨论】:

    【解决方案2】:

    当您拥有相互依赖的组件时,最需要接口。 一个常见的示例是日志记录控制器和一些记录器类。

    class LoggingController {
    
        private ILogger _logger
    
        // expecting an interface here removes the dependency 
        // to a specific implemenentation.
        // all it cares about is that the object has a Log() method
        public LoggingController(ILogger logger) {
            _logger = logger;
        }
    
        public void Log() { _logger.Log(); }
    }
    
    interface ILogger { 
        void Log(); 
    }
    
    class DbLogger : ILogger { 
        public void Log(){ //log into db }
    }
    
    class TxtLogger : ILogger {
        public void Log(){ //log into a txt file }
    }
    

    在运行时,日志控制器可以注入 ILogger 的任何实现,它完全不知道记录器实际执行什么来实际记录内容。

    对接口进行编程的另一个好处是它可以更轻松地进行单元测试。 控制器可以通过注入一个同样实现接口的模拟记录器来轻松进行单元测试。

    【讨论】:

    • 我能问一下为什么这被否决了吗?如果有什么不对的地方,我更希望解释和纠正......
    【解决方案3】:

    这里有几个不错的链接。

    http://www.daniweb.com/software-development/csharp/threads/114364/why-use-interfaces

    http://fci-h.blogspot.com/2008/03/oop-design-concepts-interfaces_05.html

    细化:基本上它们提供了更多的抽象。如果你有一个对象说Alien,在这种情况下,所有外星人都来自外太空。好吧,并非所有外星人都完全相同,但它们都消耗食物并消耗能量。他们消耗食物和使用能量的方式可能有所不同,但保留一个基类 Alien 并拥有从该类抽象出来的接口比为每种类型都有单独的类更有意义。

    基类中的核心逻辑可以保持不变,接口可以在需要时更改部分。

    【讨论】:

    • 我之所以懒惰是因为任何人都可以快速谷歌并从那里阅读有关“为什么使用接口”的解释。
    猜你喜欢
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-17
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 2013-12-17
    相关资源
    最近更新 更多