C# 为什么我们从接口而不是类创建对象实例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16832280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 07:54:04  来源:igfitidea点击:

Why we do create object instance from Interface instead of Class?

c#classinterfacederived-class

提问by user2282567

I have seen an Interface instance being generated from a class many times. Why do we use interface this way? An interface instance is created only itself with the help of the derived class and we can access only these interface members through this instance. How does this give an advantage? I'm so confused.

我已经多次看到从一个类生成一个接口实例。为什么我们这样使用接口?接口实例仅在派生类的帮助下创建,我们只能通过该实例访问这些接口成员。这如何带来优势?我很困惑。

interface IPrint
{
    void Print();
}

class Sample : IPrint
{
    public void Print()
    {
        Console.WriteLine("Print...");
    }

    public void Sample()
    {
        Console.WriteLine("Sample...");
    }
}

class Program
{
    static void Main(string[] args)
    {
        IPrint print = new Sample();
        print.Print();
    }
}

采纳答案by Belogix

Interfaces define that a class MUST be able to do something. This means that you know the object being worked on will do what you want to be able to do. It allows you greater freedom and advantages of OOP. This is a deep topic but a very basic example would be this:

接口定义了一个类必须能够做一些事情。这意味着您知道正在处理的对象将执行您希望能够执行的操作。它让您拥有更大的自由度和 OOP 的优势。这是一个很深的话题,但一个非常基本的例子是:

public interface IAnimal
{
    string Speak();
}

public class Dog : IAnimal
{
    public string Speak()
    {
        return "Woof, woof";
    }
} 

public class Cat : IAnimal
{
    public string Speak()
    {
        return "Meow";
    }
} 

public class Parrot : IAnimal
{
    public string Speak()
    {
        return "Sqwark!";
    }
} 

Then you could use any animal you like!

然后你可以使用任何你喜欢的动物!

class Program
{
    static void Main(string[] args)
    {
        // Writes Woof, Woof
        IAnimal animal = new Dog();
        Console.WriteLine(animal.Speak());        

        // Now writes Meow
        animal = new Cat();
        Console.WriteLine(animal.Speak());

        // Now writes Sqwark etc
        animal = new Parrot();
        Console.WriteLine(animal.Speak());
    }
}

This also allows you to then get into things like Inversion Of Controlwhere you would take an item in like this and you could pass a dog, cat or parrot and the method would always work, not knowing or caring which animal it was:

这也允许你进入控制反转之类的事情,那里你可以像这样接收一个项目,你可以通过一只狗、猫或鹦鹉,这个方法总是有效的,不知道或关心它是哪种动物:

public void ShoutLoud(IAnimal animal)
{
    MessageBox.Show("Shout " + animal.Speak());
}

This then makes ShoutLoud unit testablebecause you could use a mock object rather than a real animal. It basically makes your code flexible and dynamic rather than rigid and tightly coupled.

这使得 ShoutLoud单元可测试,因为您可以使用模拟对象而不是真正的动物。它基本上使您的代码灵活和动态,而不是僵化和紧耦合。

Also, expanding on Matthew's question. In C# you can only inherit from one base class but you can have multiple interfaces. So, you could have:

此外,扩展马修的问题。在 C# 中,您只能从一个基类继承,但可以有多个接口。所以,你可以有:

public class Dog : IAnimal, IMammal, ICarnivor

This allows you to have small interfaces (recommended) that then allow you to build up so giving maximum control over what an item can / must do.

这允许您拥有小型接口(推荐),然后允许您进行构建,从而最大限度地控制项目可以/必须做什么。

回答by MoonKnight

Using an interface this way gives you the ability to create methods that use standard template of the interface. So here you might have many classes of printer that all inherit from IPrinter

以这种方式使用接口使您能够创建使用接口标准模板的方法。所以在这里你可能有很多打印机类都继承自IPrinter

class SamsungPrinter : IPrinter
{
    // Stuff and interface members.
}

class SonyPrinter : IPrinter
{
    // Stuff and interface members.
}

interface IPrinter
{
    void Print();
}

So for each type SamsungPrinter, SonyPrinter, etc. you can pre-process using something like

因此,对于每种类型SamsungPrinterSonyPrinter等,您可以使用类似的方法进行预处理

public static void PreProcessAndPrint(IPrinter printer)
{
    // Do pre-processing or something.
    printer.Print();
}

You know from inheriting from IPrinterand using that type in the method parameters that you can always safely use the Printmethod on what ever object is passed.

IPrinter通过在方法参数中继承和使用该类型,您知道您始终可以Print在传递的任何对象上安全地使用该方法。

Of course there are many other uses for using interfaces. One example of their use is in design patterns, in particular the Factory and Strategy patterns. The description of which and examples can be found here.

当然,使用接口还有许多其他用途。它们的使用示例之一是在设计模式中,特别是工厂和策略模式。可以在此处找到其说明和示例。

I hope this helps.

我希望这有帮助。

回答by Krijn

But how does this differ from, for example, using a base class with virtual methods?

但这与例如使用具有虚方法的基类有何不同?

You are all in the assumption that one programmer or one program writes the interface and the classes, but this doesn't always have to be this way.

你们都假设一个程序员或一个程序编写接口和类,但这并不总是这样。

Maybe you have a complete finished program that works with animals and you have this worked out using:

也许你有一个完整的与动物一起工作的完成的程序,你已经使用以下方法解决了这个问题:

public abstract class Animal { public abstract string Speak(); }

And then some day you download some awesome DLL from nuget that shows pictures for animals. The class library contains a contract - interface - 'IAnimal':

然后有一天你从 nuget 下载了一些很棒的 DLL,它显示了动物的图片。类库包含一个契约 - 接口 - 'IAnimal':

namespace AwesomeAnimalLibrary
{
public interface IAnimal
{
string AnimalName;
}
}

The class library also maybe contains :

类库也可能包含:

namespace AwesomeAnimalLibrary
{
public class AnimalPhotos
{
[Byte] GetPhotos(IAnimal animal);
}
}

What could you do now ? Your bas class Animal can implement the AwesomeAnimalLibrary IAnimal interface and that's it.

你现在能做什么?您的基类 Animal 可以实现 AwesomeAnimalLibrary IAnimal 接口,仅此而已。

Don't assume that other people will use you abstract base classes but work together using interface contracts.

不要假设其他人会使用您的抽象基类,而是使用接口契约一起工作。

回答by cembo

Interface can not have instance because interface implements only signatures of properties or methods. Interface is just a pointer to an instance of some class:

接口不能有实例,因为接口只实现属性或方法的签名。接口只是指向某个类的实例的指针:

interface IExample
{
   // method signature
   void MyMethod();
}
public class MyClass : IExample
{
   // method implementation
   public void MyMethod()
   {
      ConsoleWriteline("This is my method");
   }
}

// interface pointing to instance of class
IExample ie = new MyClass();
ie.MyMethod();