界面奇迹问题

时间:2011-04-18 18:07:12

标签: c# .net class inheritance interface

我们将界面定义如下:

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

有什么想法吗?

7 个答案:

答案 0 :(得分:5)

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

编辑:在此示例中,不需要接口。但是,在尝试编写松散耦合的代码时,它们非常有用,您无需依赖具体对象。它们还用于定义契约,其中任何实现它们的东西也必须实现它定义的每个方法。

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

如果你真的想了解更多关于接口以及它们如何帮助编写好的代码,我会推荐Head First Design Patterns一书。 Amazon Link

答案 1 :(得分:2)

  

而不是创建一个接口,为什么   我们可以直接使用这个功能吗?   以下

你问的界面是什么意思吗?

通过创建界面,您可以将程序与特定类解耦,而不是针对abstraction进行编码。

当您的课程针对某个界面进行编码时,使用您的课程的课程可以 inject ,无论他们想要哪个类来实现此界面。这有利于单元测试,因为不易测试的模块可以用模拟和短截线代替。

答案 2 :(得分:1)

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

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());
     }
}

然而,你的例子并没有真正遵循这种模式;如果一个类实现了接口,那么确实没有多大意义。你可以用任何一种方式调用它;它只取决于你拥有什么样的对象层次结构以及你打算做什么来让我们说出使用接口是否是一个好的选择。

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

答案 3 :(得分:1)

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

然而,有一些优点:

  • 多重继承 - 一个类只能扩展一个父类,但可以实现任意数量的接口。
  • 课堂使用自由 - 如果您的代码是编写的,只关心它的实例为SomethingI,那么您就不会被绑定到特定的Something课程。如果明天你决定你的方法应该返回一个工作方式不同的类,它可以返回SomethingA,并且不需要更改任何调用代码。

答案 4 :(得分:1)

在实例化对象时,但在引用它们时找不到接口的用途。考虑一下您的示例是否已更改为:

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()方法,这可能会很快变得混乱。

答案 5 :(得分:0)

接口使对象可以使用具有 no common base type 但具有某些常用功能的各种对象。如果许多类实现IDoSomething,则方法可以接受IDoSomething类型的参数,并且可以将任何类的对象传递给它。然后,该方法可以使用适用于IDoSomething的所有方法和属性,而无需担心对象的实际基础类型。

答案 6 :(得分:0)

界面的重点是定义实现类遵守的契约。

这允许您编程到规范而不是实现。

想象一下,我们有以下几点:

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();
}