web-dev-qa-db-fra.com

Pourquoi crée-t-on une instance d'objet à partir d'Interface au lieu de Class?

J'ai souvent vu une instance d'interface générée à partir d'une classe. Pourquoi utilise-t-on une interface de cette manière? Une instance d'interface créée uniquement à l'aide de la classe dérivée et nous ne pouvons accéder à cette interface que par l'intermédiaire de cette instance. Comment cela donne-t-il un avantage? Je suis tellement confus..

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

Les interfaces définissent qu'une classe DOIT être capable de faire quelque chose. Cela signifie que vous savez que l'objet sur lequel vous travaillez va faire ce que vous voulez pouvoir faire. Il vous permet une plus grande liberté et des avantages de la programmation orientée objet. C'est un sujet profond mais un exemple très basique serait le suivant:

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

Ensuite, vous pouvez utiliser n'importe quel animal que vous aimez!

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

Cela vous permet également d'entrer dans des choses comme Inversion Of Control où vous emporteriez un article dans ce genre et vous pourriez passer un chien, un chat ou un perroquet et la méthode fonctionnerait toujours, sans savoir ni vous soucier quel animal c'était:

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

Cela rend alors ShoutLoud nité testable parce que vous pouvez utiliser un objet fictif plutôt qu'un animal réel. En gros, votre code est flexible et dynamique plutôt que rigide et étroitement couplé.

Également, développer la question de Matthew. En C #, vous ne pouvez hériter que d'une classe de base, mais vous pouvez avoir plusieurs interfaces. Donc, vous pourriez avoir:

public class Dog : IAnimal, IMammal, ICarnivor

Cela vous permet d’avoir de petites interfaces (recommandées) qui vous permettent ensuite de vous construire afin de donner un contrôle maximum sur ce qu’un élément peut/doit faire.

94
Belogix

L'utilisation d'une interface de cette façon vous permet de créer des méthodes utilisant le modèle standard de l'interface. Donc ici, vous pourriez avoir beaucoup de classes d’imprimantes qui héritent toutes de IPrinter

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

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

interface IPrinter
{
    void Print();
}

Donc, pour chaque type SamsungPrinter, SonyPrinter, etc., vous pouvez prétraiter en utilisant quelque chose comme

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

Vous savez qu'en héritant de IPrinter et en utilisant ce type dans les paramètres de méthode, vous pouvez toujours utiliser en toute sécurité la méthode Print quel que soit l'objet transmis.

Bien sûr, il existe de nombreuses autres utilisations des interfaces. Un exemple de leur utilisation est dans les modèles de conception, en particulier les modèles Usine et Stratégie. La description et des exemples peuvent être trouvés ici .

J'espère que ça aide.

8
MoonKnight

Mais en quoi cela diffère-t-il de l'utilisation, par exemple, d'une classe de base avec des méthodes virtuelles?

Vous êtes tous dans l'hypothèse qu'un programmeur ou un programme écrit l'interface et les classes, mais cela ne doit pas toujours être ainsi.

Vous avez peut-être un programme complet qui fonctionne avec les animaux et que vous avez réussi à utiliser:

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

Et puis, un jour, vous téléchargez des fichiers géniaux DLL de nuget affichant des images pour animaux. La bibliothèque de classes contient un contrat - interface - 'IAnimal':

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

La bibliothèque de classes contient peut-être aussi:

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

Que pourriez-vous faire maintenant? Votre classe de base Animal peut implémenter l'interface IA Awimal AwesomeAnimalLibrary et c'est tout.

Ne supposez pas que d’autres personnes vont utiliser vos classes de base abstraites mais travaillent ensemble à l’aide de contrats d’interface.

1
Krijn

Interface ne peut pas avoir d'instance car l'interface n'implémente que les signatures de propriétés ou de méthodes. L'interface est juste un pointeur sur une instance d'une classe:

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