Почему мы создаем экземпляр объекта из интерфейса вместо класса?


Я много раз видел экземпляр интерфейса, созданный из класса. Почему используется интерфейс таким образом? Экземпляр интерфейса создается только сам с помощью производного класса, и мы можем получить доступ только к этим членам интерфейса через этот экземпляр. Как это дает преимущество? Я так запуталась..

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   51   2013-05-30 13:20:32

4 ответа:

интерфейсы определить, что класс должен быть в состоянии сделать что-то. Это означает, что вы знаете, что объект, над которым работает, будет делать то, что вы хотите. Это позволяет вам большую свободу и преимущества ООП. Это глубокая тема, но очень простой пример будет следующим:

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 единица проверяемых потому что вы могли бы использовать макет объекта, а не реальное животное. Это в основном делает ваш код гибким и динамичным, а не жестким и тесно связанным.

также, расширяясь на вопрос Мэтью. В C# вы можете наследовать только от одного базового класса, но вы можете иметь несколько интерфейсов. Итак, вы могли бы:

public class Dog : IAnimal, IMammal, ICarnivor

Это позволяет вам иметь небольшие интерфейсы (рекомендуется), которые затем позволяют вам создавать так, чтобы дать максимальный контроль над тем, что элемент может / должен делать.

использование интерфейса этот способ дает вам возможность создавать методы, которые используют стандартный шаблон интерфейса. Так что здесь у вас может быть много классов принтера, которые все наследуют от IPrinter

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

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

interface IPrinter
{
    void Print();
}

так что для каждого типа SamsungPrinter,SonyPrinter и т. д. вы можете предварительно обработать, используя что-то вроде

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

вы знаете от наследования от IPrinter и используя этот тип в параметрах метода, вы всегда можете безопасно использовать Print метод на какой-либо объект пройденный.

конечно, есть много других применений для использования интерфейсов. Одним из примеров их использования является разработка шаблонов, в частности фабричных и стратегических шаблонов. Описание которых можно найти здесь.

Я надеюсь, что это помогает.

но чем это отличается, например, от использования базового класса с виртуальными методами?

вы все в предположении, что один программист или одна программа пишет-интерфейс и классы, но это не всегда так.

может быть, у вас есть полная готовая программа, которая работает с животными, и вы это разработали с помощью:

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

и тогда в один прекрасный день вы загрузите некоторые удивительные DLL из nuget, который показывает картинки для животных. Библиотека классов содержит контракт-интерфейс- '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();