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

С# - Может кто-нибудь, пожалуйста, покажет мне очень простой пример интерфейсов

Я не могу понять, как использовать интерфейсы и почему они нужны. Может кто-нибудь, пожалуйста, покажет мне простой пример?

4b9b3361

Ответ 1

interface IFlyable
{
    void Fly();
}

class Bird : IFlyable
{
    public void Fly() { }
}

class Plane : IFlyable
{
    public void Fly() { }
}

List<IFlyable> things = GetBirdInstancesAndPlaneInstancesMixed();
foreach(IFlyable item in things)
{
   item.Fly();
}

Bird и Plane не имеют общего базового класса, кроме Object, но вы можете видеть, используя тот же интерфейс, что мы можем иметь дело с ними группово в нашей программе, потому что у них есть одна и та же "функция": Fly.

Ответ 2

public interface ISpeaks
{
    string Speak();
}

public class Dog : Mammal, ISpeaks
{
    public string Speak() { return "Woof!"; }
}

public class Person : Mammal, ISpeaks
{
    public string Speak() { return "Hi!"; } 
}

//Notice Telephone has a different abstract class
public class Telephone : Appliance, ISpeaks
{
   public Person P { get; set; }

   public Telephone(Person p)
   {
     P = p;
   }

   public string Speak() { return P.Speak(); } 
}


[Test]
public void Test_Objects_Can_Speak()
{
    List<ISpeaks> thingsThatCanSpeak = new List<ISpeaks>();
    //We can add anything that implements the interface to the list
    thingsThatCanSpeak.Add(new Dog());
    thingsThatCanSpeak.Add(new Person());
    thingsThatCanSpeak.Add(new Telephone(new Person()));

   foreach(var thing in thingsThatCanSpeak)
   {
       //We know at compile time that everything in the collection can speak
       Console.WriteLine(thing.Speak());
   }
}

Это полезно, потому что мы можем кодировать интерфейс, а не реализацию, и поскольку мы можем использовать несколько интерфейсов в одном классе, мы более гибки, чем если бы мы использовали класс Abstract.

Ответ 3

Interfaces - это как-то определение класса, своего рода контракт между interface и класс, реализующий его.

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

Класс .NET не может использовать множественное наследование. Таким образом, мы полагаемся на интерфейсы, и класс может реализовать столько интерфейсов, сколько пожелаете. Напротив, наследование класса должно быть единым. Например:

public class Customer : Person, Company {
}

Этот код не разрешен ни на каких .NET-языках, которые я знаю (С#/VB.NET).

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

public interface IPerson {
    string Name
    string Address
    string StateProvince
    string ZipPostalCode
    string Country
    long PhoneNumber
}

public interface ICompany {
    string CreditTerm
    string BillingAddress
    string ShippingAddress
    string ContactName
    long ContactPhoneNumber
    long FaxNumber
}

public class Customer : IPerson, ICompany {
    // Properties implementations here.
}

Таким образом, интерфейсы как-то похожи на многоуровневое.

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

public BillCompany(ICompany company) {
    // Bill company here...
}

Затем ваш класс Customer соответствует ожидаемому, поскольку он реализует интерфейс ICompany.

Позвольте создать другой класс, определение которого будет реализовывать только интерфейс IPerson.

public class Individual : IPerson {
    // Interface implementation here...
}

Затем ваш метод BillCompany() не смог принять экземпляр класса Individual, поскольку он не показывает требования (свойства и т.д.) для компании.

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

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

Помогает ли это?

Ответ 4

Мне нравится этот пост в блоге, который я прочитал на днях: http://simpleprogrammer.com/2010/11/02/back-to-basics-what-is-an-interface/

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

Ответ 5

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

Итак, скажем, у вас есть метод, который задает для обработки запросов на сохранение. Он не выполняет фактический акт сохранения, он просто обрабатывает запросы. В результате может потребоваться List<ICanSave>, где ICanSave - это интерфейс. Объектами в этом списке могут быть любые типы, реализующие этот интерфейс. Это может быть смесь, или она может содержать только один тип. Вы просто обеспокоены тем, что он реализует интерфейс.

public interface ICanSave
{
    void Save();
}

В вашем методе у вас может быть что-то простое, например

public void SaveItems(List<ICanSave> items)
{
    foreach (var item in items)
    {
        item.Save();
    }
}

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

У вас может быть класс, который реализует интерфейс, который сохраняет данные в файловой системе. Другой может сохранить базу данных. Другой может вызвать некоторую внешнюю услугу. И т.д. Это позволило автору класса решить. Возможно, у вас даже есть класс с заглублением для unit test, который ничего не делает.

Это всего лишь один сценарий использования, есть много других, несколько в BCL. IEnumerable<T> является хорошим, он реализуется такими вещами, как ICollection<T> и IList<T>, которые, в свою очередь, реализуются конкретными типами, такими как Array и List<T>. Это интерфейс, который делает многие из конструкций программирования, которые вы привыкли использовать, например LINQ. LINQ не заботится о фактической реализации * класса, он просто хочет иметь возможность перечислять его и выполнять правильную фильтрацию и/или проецирование.

IDisposable - еще один хороший пример BCL. Вы хотите знать, что класс должен очищаться после себя. То, что конкретно нужно очистить, остается за классом, но по своей природе он реализует IDisposable, вы знаете, что ему нужно очистить после себя, поэтому вы предпочитаете его использовать в инструкции using или вручную что вы вызываете .Dispose после того, как вы закончили работу с объектом.

* LINQ фактически оптимизирует некоторые интерфейсы.

Ответ 6

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

public interface IAnimal
{
   string GetDescription();
}

class Cat : IAnimal
{     
   public string GetDescription()
   {
      return "I'm a cat";
   }
}

class Program
{
    static void Main(string[] args)
    {
       Cat myCat = new Cat();

       Console.WriteLine(myCat.GetDescription());
    }
}

Ответ 7

"У меня здесь есть куча классов, которые я хочу рассматривать одинаково, для определенной функциональности".

Итак, вы пишете контракт.

Пример реального мира: я пишу мастера. У него есть куча страниц, некоторые из которых (но не все) - это UserControls. Все они нуждаются в общем наборе операций, поэтому контрольный класс может относиться к ним одинаково. Таким образом, у меня есть интерфейс IPage, который они все реализуют, с такими операциями, как инициализация страницы, сохранение пользовательских настроек и т.д. В моем контроллере у меня просто есть список и не нужно знать, что делает страница; Я просто вызываю интерфейс Save() s и Initialize() s.

Ответ 8

Вот основные моменты интерфейса,

1. Мы можем вызывать тот же метод, используя разные классы с разными значениями из тех же методов.

Простой пример:

 class Mango : abc
{
    public static void Main()
    {
        System.Console.WriteLine("Hello Interfaces");
        Mango refDemo = new Mango();
        refDemo.mymethod();
        Orange refSample = new Orange();
        refSample.mymethod();

    }

    public void mymethod()
    {
        System.Console.WriteLine("In Mango : mymethod");
    }
}

interface abc
{
    void mymethod();
}

class Orange : abc
{
    public void mymethod()
    {
        System.Console.WriteLine("In Orange : mymethod");
    }
}

2.может вызывать тот же метод, используя тот же интерфейс с разными классами.

class Mango : abc
{
    public static void Main()
    {
        System.Console.WriteLine("Hello Interfaces");
        abc refabc = new Mango();
        refabc.mymethod();
        abc refabd = new Orange();
        refabd.mymethod();
        Console.ReadLine();
    }

    public void mymethod()
    {
        System.Console.WriteLine("In Mango : mymethod");
    }
}

interface abc
{
    void mymethod();
}

class Orange : abc
{
    public void mymethod()
    {
        System.Console.WriteLine("In Orange : mymethod");
    }
}

Ответ 9

Ну, из MSDN: "Интерфейс определяет контракт. Класс или структура, реализующая интерфейс, должны придерживаться своего контракта".

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

Надеюсь, это поможет некоторым.