为什么我们要从Interface而不是Class创build对象实例?

我已经多次看到一个从类生成的接口实例。为什么在这个方面使用接口呢?一个接口实例只在派生类的帮助下创build自己,我们只能通过这个实例访问这个接口成员。给我一个好处?我很困惑..

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

接口定义一个类必须能够做某事。 这意味着你知道正在工作的对象将做你想做的事情。 它可以让你更大的自由和优点的面向对象。 这是一个很深的话题,但是一个非常基本的例子就是:

 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!"; } } 

那么你可以使用任何你喜欢的动物!

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

这也可以让你进入像控制反转的地方,你可以像这样拿一个物品,你可以通过一只狗,猫或鹦鹉,这个方法总是有效的,不知道或者关心它是哪个动物:

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

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

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

 public class Dog : IAnimal, IMammal, ICarnivor 

这可以让你有一个小的界面(推荐),然后让你build立这样一个项目可以/必须做的最大限度的控制。

通过这种方式使用接口,您可以创build使用接口标准模板的方法。 所以在这里你可能有许多类的打印机都从IPrinterinheritance

 class SamsungPrinter : IPrinter { // Stuff and interface members. } class SonyPrinter : IPrinter { // Stuff and interface members. } interface IPrinter { void Print(); } 

所以对于每种types的SamsungPrinterSonyPrinter等,您都可以使用类似的方式进行预处理

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

您知道从IPrinterinheritance,并在方法参数中使用该types,您始终可以安全地使用传递对象的Print方法。

当然,使用接口还有很多其他用途。 其中一个例子是devise模式,特别是工厂模式和策略模式。 在这里可以find关于哪个和例子的描述。

我希望这有帮助。

但是,这与例如使用虚拟方法的基类有什么不同?

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

也许你有一个完整的程序,适用于动物,你有这个解决使用:

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

然后有一天,你会从nuget下载一些真棒animation的DLL。 类库包含一个合约 – 接口 – “IAnimal”:

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

类库也可能包含:

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

你现在可以做什么? 你的bas类Animal可以实现AwesomeAnimalLibrary IAnimal接口,就是这样。

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

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

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