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

时间:2021-06-03 20:51:42

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

我已经多次看到从类生成的Interface实例。为什么以这种方式使用接口? Interface实例仅在派生类的帮助下创建,我们只能通过此实例访问此接口成员。这有什么优势?我很困惑..

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

4 个解决方案

#1


81  

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 Control where 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 testable because 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.

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

#2


7  

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

因此,对于每种类型的SamsungPrinter,SonyPrinter等,您都可以使用类似的方式进行预处理

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

You know from inheriting from IPrinter and using that type in the method parameters that you can always safely use the Print method 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.

我希望这有帮助。

#3


1  

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.

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

#4


0  

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

#1


81  

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 Control where 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 testable because 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.

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

#2


7  

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

因此,对于每种类型的SamsungPrinter,SonyPrinter等,您都可以使用类似的方式进行预处理

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

You know from inheriting from IPrinter and using that type in the method parameters that you can always safely use the Print method 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.

我希望这有帮助。

#3


1  

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.

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

#4


0  

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