界面奇迹问题

本文关键字:问题 奇迹 界面 | 更新日期: 2023-09-27 17:50:24

我们定义接口如下:

interface IMyInterface
{
    void MethodToImplement();
}

和实现如下:

class InterfaceImplementer : IMyInterface
{
    static void Main()
    {
        InterfaceImplementer iImp = new InterfaceImplementer();
        iImp.MethodToImplement();
    }
    public void MethodToImplement()
    {
        Console.WriteLine("MethodToImplement() called.");
    }
}

而不是创建一个接口,为什么我们可以像下面这样直接使用函数:-)

class InterfaceImplementer
{
    static void Main()
    {
        InterfaceImplementer iImp = new InterfaceImplementer();
        iImp.MethodToImplement();
    }
    public void MethodToImplement()
    {
        Console.WriteLine("MethodToImplement() called.");
    }
}

任何想法吗?

界面奇迹问题

您没有实现底部示例中的接口,您只是创建了InterfaceImplementer的对象

编辑:在本例中不需要接口。然而,当试图编写松散耦合的代码时,它们是非常有用的,因为您不必依赖于具体对象。它们也被用来定义契约,其中任何实现它们的东西也必须实现它所定义的每个方法。

有很多信息,这里只是一个简短的介绍http://www.csharp-station.com/Tutorials/Lesson13.aspx

如果你真的想了解更多关于接口的知识,以及它们如何帮助你写出好的代码,我推荐你看《Head First Design Patterns》这本书。亚马逊链接

而不是创建接口,为什么我们可以像这样直接使用这个函数吗在

你是在问接口的意义是什么吗?

创建一个接口允许你你的程序与一个特定的类解耦,而不是针对抽象编写代码。

当你的类是针对一个接口编码时,使用你的类的类可以注入任何它们想要实现这个接口的类。这有利于单元测试,因为不容易测试的模块可以用模拟和存根代替。

接口的目的是使其他类能够在不知道具体实现的情况下使用该类型,只要该类型符合接口契约中定义的一组方法和属性。

public class SomeOtherClass
{
     public void DoSomething(IMyInterface something)
     {
          something.MethodToImplement();
     }
}
public class Program
{
     public static void Main(string[] args)
     {
          if(args != null)
              new SomeOtherClass().DoSomething(new ImplementationOne());
          else
              new SomeOtherClass().DoSomething(new ImplementationTwo());
     }
}

你的例子并没有真正遵循这种模式,然而;如果只有一个类实现了接口,那么就没有什么意义了。你可以这样称呼它;它只是取决于你有什么样的对象层次和你打算做什么,让我们说使用接口是否是一个好选择。

总而言之:您提供的两个代码段都是有效的代码选项。我们需要上下文来确定哪个是"更好"的解决方案。

接口不是必需的,你发布的最后一段代码没有任何问题。它只是一个类,你调用它的一个公共方法。它不知道存在这个类恰好满足的接口。

但是,也有优点:

  • 多重继承——一个类只能继承一个父类,但可以实现任意数量的接口。
  • 自由使用类——如果你的代码只关心它有一个SomethingI的实例,你就不会被绑定到一个特定的Something类。如果明天你决定你的方法应该返回一个工作方式不同的类,它可以返回SomethingA,任何调用代码都不需要更改。

接口的目的不在于实例化对象,而在于引用它们。考虑一下您的示例是否更改为:

static void Main()
{
    IMyInterface iImp = new InterfaceImplementer();
    iImp.MethodToImplement();
}

现在iTmp对象的类型是IMyInterface。它的具体实现是InterfaceImplementer,但有时实现可能不重要(或不需要)。考虑如下内容:

interface IVehicle
{
    void MoveForward();
}
class Car : IVehicle
{
    public void MoveForward()
    {
        ApplyGasPedal();
    }
    private void ApplyGasPedal()
    {
        // some stuff
    }
}
class Bike : IVehicle
{
    public void MoveForward()
    {
        CrankPedals();
    }
    private void CrankPedals()
    {
        // some stuff
    }
}

现在假设你有一个这样的方法:

void DoSomething(IVehicle)
{
    IVehicle.MoveForward();
}

接口的目的在这里变得更加清晰。您可以将IVehicle的任何实现传递给该方法。实现并不重要,重要的是接口可以引用它。否则,您将需要为每个可能的实现使用DoSomething()方法,这会很快变得混乱。

接口使一个对象能够与具有没有公共基类型但具有某些公共功能的各种对象一起工作。如果许多类实现了IDoSomething,那么方法可以接受IDoSomething类型的参数,并且可以将这些类中的任何一个对象传递给它。然后,该方法可以使用适用于IDoSomething的所有方法和属性,而不必担心对象的实际底层类型。

接口的意义在于定义一个你的实现类所遵守的契约。

这允许您按照规范而不是实现进行编程。

假设我们有以下内容:

public class Dog
{
    public string Speak()
    {
        return "woof!";
    }
}

想看看他说什么:

public string MakeSomeNoise(Dog dog)
{
    return dog.Speak();
}

我们确实没有从接口中受益,但是如果我们还想看到Cat发出什么样的噪音,我们需要另一个可以接受Cat的MakeSomeNoise()重载,但是有了接口,我们可以有以下内容:

public interface IAnimal
{
    public string Speak();
}
public class Dog : IAnimal
{
    public string Speak()
    {
        return "woof!";
    }
}
public class Cat : IAnimal
{
    public string Speak()
    {
        return "meow!";
    }
}

并同时运行:

public string MakeSomeNoise(IAnimal animal)
{
    return animal.Speak();
}