使用接口变量

Pos*_*Guy 38 c#

我仍然试图更好地理解接口.我知道它们是什么以及如何在课堂上实现它们.

我不明白的是,当您创建一个属于您的某种接口类型的变量时:

IMyInterface somevariable;
Run Code Online (Sandbox Code Playgroud)

你为什么要这样做?我不明白IMyInterface如何像类一样使用...例如调用方法,所以:

somevariable.CallSomeMethod();
Run Code Online (Sandbox Code Playgroud)

为什么要使用IMyInterface变量来执行此操作?

Dav*_*all 64

您没有创建接口的实例 - 您正在创建实现接口的实例.

接口的关键在于它保证实现它的内容将提供在其中声明的方法.

现在,使用您的示例,您可以:

MyNiftyClass : IMyInterface
{
    public void CallSomeMethod()
    {
        //Do something nifty
    }
}

MyOddClass : IMyInterface
{
    public void CallSomeMethod()
    {
        //Do something odd
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你有:

IMyInterface nifty = new MyNiftyClass()
IMyInterface odd = new MyOddClass()
Run Code Online (Sandbox Code Playgroud)

调用CallSomeMethod方法现在可以做一些漂亮或奇怪的事情,当你使用IMyInterface作为类型传入时,这变得特别有用.

public void ThisMethodShowsHowItWorks(IMyInterface someObject)
{
    someObject.CallSomeMethod();
}
Run Code Online (Sandbox Code Playgroud)

现在,根据您是使用漂亮的还是奇怪的类调用上述方法,您会得到不同的行为.

public void AnotherClass()
{
    IMyInterface nifty = new MyNiftyClass()
    IMyInterface odd = new MyOddClass()

    // Pass in the nifty class to do something nifty
    this.ThisMethodShowsHowItWorks(nifty);

    // Pass in the odd class to do something odd
    this.ThisMethodShowsHowItWorks(odd);

}
Run Code Online (Sandbox Code Playgroud)

编辑

这解决了我认为您想要的问题 - 为什么要将变量声明为接口类型?

也就是说,为什么使用:

IMyInterface foo = new MyConcreteClass();
Run Code Online (Sandbox Code Playgroud)

优先于:

MyConcreteClass foo = new MyConcreteClass();
Run Code Online (Sandbox Code Playgroud)

希望很明显为什么在声明方法签名时会使用接口,但这会留下有关本地范围变量的问题:

public void AMethod()
{
    // Why use this?
    IMyInterface foo = new MyConcreteClass();

    // Why not use this?
    MyConcreteClass bar = new MyConcreteClass();
}
Run Code Online (Sandbox Code Playgroud)

通常没有技术原因可以选择接口.我通常使用界面,因为:

  • 我通常注入依赖项,因此需要多态性
  • 使用界面清楚地表明我的意图是仅使用界面的成员

您在技术上需要接口的地方是您正在利用多态性的地方,例如使用工厂创建变量或使用依赖注入创建变量(如上所述).

借用itowlson的一个例子,使用具体的声明你不能这样做:

public void AMethod(string input)
{               
    IMyInterface foo;

    if (input == "nifty")
    {
        foo = new MyNiftyClass();
    }
    else
    {
        foo = new MyOddClass();
    }
    foo.CallSomeMethod();
}
Run Code Online (Sandbox Code Playgroud)

  • coffeeaddict:"多态...如果你有一个类型IMyInterface someVar的变量那么基本上...可以切换到任何实现IMyInterface的类型,因为具体的类型是IMyInterface?" 究竟.`IMyInterface nifty = new MyNiftyClass()`是人为的:你通常不会费心去写它.但是,考虑一下,`IMyInterface imi = oddness> 0?new OddClass():new NiftyClass()`.我们在编译时不知道我们是否会得到Odd或Nifty对象,我们*不关心*:我们所关心的是我们可以将它传递给TMSHIW,即它是一个IMyInterface. (4认同)
  • 查看public void的签名ThisMethodShowsHowItWorks(IMyInterface someObject)该参数是IMyInterface类型的变量.这就是为什么你使用接口变量 - 他们可以采取任何实现变量 (2认同)
  • 另外,您需要记住 IMyInterfaces blah = new MyConcreteClass() 中 *Declaration* 和 *Instantiation* 之间的区别,左侧是声明,右侧是实例化。您正在实例化 MyConcreteClass 的实例,而不是接口的实例。 (2认同)

Cha*_*ion 7

因为这:

public void ReadItemsList(List<string> items);
public void ReadItemsArray(string[] items);
Run Code Online (Sandbox Code Playgroud)

可以成为这样:

public void ReadItems(IEnumerable<string> items);
Run Code Online (Sandbox Code Playgroud)

编辑

可以这样想:

你必须能够做到这一点.

而不是:

你必须是这个.

基本上这是方法和它的调用者之间的契约.