Подтвердить что ты не робот

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

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

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

Ответ 1

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

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

Это также позволяет вам входить в такие вещи, как Inversion Of Control, где вы могли бы взять такой предмет, и вы могли бы передать собаку, кошку или попугай, и метод всегда будет работать, а не зная или заботясь о том, какое это животное:

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

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

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

public class Dog : IAnimal, IMammal, ICarnivor

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

Ответ 2

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

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

Надеюсь, это поможет.

Ответ 3

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

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

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

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

Что вы можете сделать сейчас? Ваш базовый класс Animal может реализовать интерфейс AwesomeAnimalLibrary IAnimal и что он.

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

Ответ 4

Интерфейс не может иметь экземпляр, поскольку интерфейс реализует только подписи свойств или методов. Интерфейс - это просто указатель на экземпляр некоторого класса:

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