Значение интерфейсов C#

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

Я записал небольшую программу. Я определил Интерфейс Itest.Class(Manager) реализовал Interface.Another class(Employee) не реализовал интерфейс. Но определенный тот же метод (DoSomething()) в интерфейсе в классе (Employee). Я могу назвать метод от объекта класса. Тогда, почему я должен пойти и реализовать интерфейс. Я могу непосредственно реализовать метод в классе и назвать метод. Почему я должен пойти для дополнительного шага реализации метода в Интерфейсе и затем наследовании интерфейса классом. Я знаю, что интерфейс поддерживает множественное наследование, но я не использую множественное наследование в этом примере.

Спасибо за любые идеи или вход.

public interface Itest
{
    void DoSomething();
}

public class Manager:Itest
{
    public void DoSomething()
    {
        Console.WriteLine("test....");
    }

}
class Employee
{
    public void DoSomething()
    {
        Console.WriteLine("test....");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Manager m = new Manager();
        m.DoSomething();
        Employee e = new Employee();
        e.DoSomething();
        Console.ReadLine();
    }
}
11
задан Shikha 8 February 2010 в 12:25
поделиться

12 ответов

Интерфейсы позволяют вам вроде как использовать множественное наследование. В вашем примере это позволит вам поместить экземпляр Employee или Manager в ту же переменную, а затем вызвать DoSomething для этой переменной, при этом вызов метода будет отправлен в экземпляр, на который в данный момент ссылается эта переменная. Переменная. Например:

public interface IEmployee {
    void DoSomething();
}
// assume Manager and Employee both implement IEmployee

IEmployee ie = new Manager();
ie.DoSomething();    // calls Manager.DoSomething()
ie = new Employee();
ie.DoSomething();    // calls Employee.DoSomething()

Если вы не использовали интерфейсы, вам нужно было бы сделать:

object o;

// assign Manager or Employee (or something else!) to o

if (o is Manager)
    ((Manager)o).DoSomething();
else if (o is Employee)
    ((Employee)o).DoSomething();

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

Один из примеров, в котором я сейчас использую интерфейсы, - это определение объектной модели - у меня есть интерфейсы для различных свойств ( IHasStorage , IHasPrivileges , IHasCheezburger ]), то классы, представляющие конкретные объекты, реализуют те интерфейсы, которые подходят для свойств этого класса

16
ответ дан 3 December 2019 в 01:44
поделиться

Наследование реализации моделирует отношение «ЭТО ВИД», в то время как наследование интерфейса моделирует отношение «МОЖЕТ ВЕСТИ КАК». Неслучайно многие имена интерфейсов BCL заканчиваются на «-able», что означает способность что-то делать. Чтобы продемонстрировать это, изобразите следующий код:

class Person
{
  public string Name{get;set;}
  public void Walk() {/*code elided*/}
}

class Employee : Person
{
  public int Id{get;private set;}
}

Ясно, что «Сотрудник» - это своего рода «Человек. Все сотрудники - люди, поэтому у всех есть Имя и они могут ходить (). Безусловно, абстрагируйте Person или Employee, это не меняет того факта, что все сотрудники - люди.

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

Давайте подумаем о транспортных средствах. Автомобиль, конечно, но как насчет человека? Они могут двигаться и останавливаться (а когда я даю своим племянникам и племянницам спинки спинки, я тоже везу пассажиров!) Кресло-колесико? Я вечно бродил по офису. Я тоже заядлый моряк и использую ветер, чтобы ускорять и замедлять свою машину.

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

Погостик (с извинениями перед профессиональными погостиками) ЯВЛЯЕТСЯ ВИДОМ игрушки, но МОЖЕТ ДЕЙСТВОВАТЬ В КАЧЕСТВЕ транспортного средства. Не все игрушки являются транспортными средствами. Человек не имеет никакого отношения к Автомобилю, кроме того факта, что он МОЖЕТ ДЕЙСТВОВАТЬ КАК транспортное средство.

interface IVehicle
{
  void Move();
  void Stop();
}

class Toy{}

class PogoStick : Toy, IVehicle
{
  public void Move(){ /* boing boing */}
  public void Stop(){ /* fall over */}
}

class Car: IVehicle
{
  public void Move(){ /* vroom vroom */}
  public void Stop(){ /* <screeeech!> */}
}

class Person : IVehicle
{
  public string Name{get;set;}
  public void Walk() {/*code elided*/}
  void IVehicle.Move() { Walk(); }
  void IVehicle.Stop() { /*whatever!*/}
}

class Program
{
  static void Main()
  {
    IVehicle[] vehicles = new IVehicle[3];
    vehicles[0] = new PogoStick();
    vehicles[1] = new Car();
    vehicles[2] = new Employee(); //implements IVehicle because it IS A KIND OF Person

    vehicles.ForEach(v => v.Move());

    //it's worth pointing out that
    vehicles[2].Stop();
    //works fine, but
    Person p = new Person();
    p.Move();
    //won't, as I explicitly implemented the interface, meaning I can only get at the
    //methods via a reference to the interface, not to the implementing class.
  }
}

Чтобы использовать пример из.NET, что общего у строки со списком? Немного, за исключением того, что я могу выполнить "foreach" их обоих:

class Demo
{
  static void Main()
  {
    string s = "Hello!";
    List<Employee> payroll = new List<Employee>();

    for each (var item in s)
    {
      Console.WriteLine(item);
    }

    for each (var item in payroll)
    {
      Console.WriteLine(item);
    }
}

Общий базовый класс для строки и списка - это объект, но не все объекты "для каждого-способны", поэтому должно быть что-то еще. на. А именно, что они оба реализуют интерфейс IEnumerable (вот и -able!)

4
ответ дан 3 December 2019 в 01:44
поделиться

Когда вы добавляете интерфейс в Сотрудник, два класса становятся совместимыми через этот интерфейс:

public class Manager:Itest { ... }

class Employee:Itest { ... }

static void ShowSomething(Itest test)
{
   test.DoSomething();
}

static void Main(string[] args)
{

    Manager m = new Manager();            
    Employee e = new Employee();

    ShowSomething(m);
    ShowSomething(e);
}

Посмотрите, как BCL использует интерфейс, чтобы начать работу, найдите IDisposable, ISerializable, IComprable и IEnumerable

2
ответ дан 3 December 2019 в 01:44
поделиться

Конечно, можно реализовать метод, объявленный в интерфейсе, без реализации интерфейса. Просто положите, интерфейсы просто убедитесь, что вы не забыли об этом (они дадут вам компилировать ошибки, если какой-либо из членов интерфейса в не реализован).

-121--2890435-

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

-121--2186220-

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

В C # они позволяют использовать множественное наследование, что означает возможность реализации множества различных интерфейсов в одном классе.

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

Например,

IAnimal может быть реализован с помощью Cat и Dog . В другом коде требуется вызвать метод Talk , объявленный в интерфейсе. Код не обязательно должен быть объектом Cat или Dog . Можно добавить утку или человека и не изменять этот фрагмент кода.

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

Некоторые интерфейсы используются в качестве маркеров, поэтому отражение может легко воспринимать их (например, интерфейс ISerializable , помечая класс как сериализуемый).

10
ответ дан 3 December 2019 в 01:44
поделиться

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

1
ответ дан 3 December 2019 в 01:44
поделиться

Знаете, забавно, что сегодня я как раз разговаривал на эту тему с одним из наших разработчиков на работе.

Самый простой способ для меня объяснить, что такое интерфейс и его удобство, это следующий пример.

interface IGraphicsRenderer
{
     Render(List<Triangle> triangles);
}

Тогда у вас может быть 2 типа движков рендеринга, Direct3D или OpenGL

class Direct3DRenderer : IGraphicsRenderer
{
   public void Render(List<Triangle> triangles);
}

class OpenGLRenderer: IGraphicsRenderer
{
   public void Render(List<Triangle> triangles);
}

Чтобы показать его полезность, вы можете иметь что-то вроде

IGraphicsRenderer renderer = new Direct3DRenderer();
renderer.Render(foo);

чтобы изменить рендерер, все, что вам нужно сделать, это изменить инициализацию.

IGraphicsRenderer renderer = new OpenGLRenderer();
1
ответ дан 3 December 2019 в 01:44
поделиться

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

Затем, если ваш интерфейс изменится (например:

       public Interface IAnimal
            {
                public void Talk();
                public void Eat();
            }

, а затем вы добавите другой метод

       public Interface IAnimal
            {
                public void Talk();
                public void Sleep();
                public void Eat();
            }

, тогда вы можете убедиться, что все они будут реализовывать метод Sleep (). Если у вас слишком много классов, которые работают с IAnimal Inteface то вам необходимо реализовать Sleep () для всех из них. Это поможет вам максимально упростить расширение производных классов

1
ответ дан 3 December 2019 в 01:44
поделиться

Конечно, вы можете реализовать метод, объявленный в интерфейсе, без реализации интерфейса. Проще говоря, интерфейсы просто убедитесь, что вы не забыли об этом (они выдадут вам ошибки компиляции, если какой-либо из элементов интерфейса не реализован).

0
ответ дан 3 December 2019 в 01:44
поделиться

Я полагаю, вам нужен очень простой ответ.

Существует 2 типа наследования:

  • ТИП 1: наследование интерфейса (в простых терминах : когда наследуется внешняя часть класса )
  • ТИП 2: {{ 1}} наследование реализации (когда наследуется внутри класса)

Если вы пишете

class MyClass : Base {}

, вы используете ОБА типа 1 и 2. Но если вы реализуете интерфейс с чистым типом 1.

Тип 1 предназначен для полиморфного использования, а тип 2 - для повторного использования кода.

Итак, суть в том, что если вы хотите использовать полиморфизм, но вы

  • не хотите предоставлять какую-либо реализацию
  • или просто не можете этого сделать. В основном в случае множественного наследования - примечание: c ++ допускает это, он следует другой философии

интерфейсы для вас:)

Есть и другие варианты использования (например, принудительная реализация метода), но, на мой взгляд, это суть .

0
ответ дан 3 December 2019 в 01:44
поделиться

интерфейсы полезны в немного более сложных сценариях, например

(1) Вам необходимо множественное наследование (в C # вы не можете наследовать от 2 классов), например у вас есть интерфейсы IProduct, IDisposable. Не каждый продукт нужно утилизировать, поэтому нет смысла внедрять его во все продукты и т. Д.

(2) Когда вы используете внедрение зависимостей (инверсию управления) и фреймворк (например, RhinoMocks) для вас модульное тестирование - тогда вам придется работать с интерфейсами, иначе ваш mocking framework не будет работать.

1
ответ дан 3 December 2019 в 01:44
поделиться

Приведена очень хорошая аналогия для интерфейсов Мэтью Кокран

«Это значительно упрощает« мир кода », в котором для навигации. Представьте, если бы вместо того, чтобы научиться водить машину, а затем уметь водить любую машину, мы должны были бы научиться управлять каждым экземпляром каждой машины, в которую мы садимся. Было бы действительно неэффективно, если бы после того, как мы научились водить Ford Pinto нам пришлось начать все сначала, чтобы понять Мустанг. Намного более эффективный способ - иметь дело с интерфейсом автомобиля: рулевое колесо, поворотники, педаль газа и тормоз. Таким образом, независимо от того, что реализовано на бэкэнде интерфейса нам все равно, потому что в конце концов он подписывается на базовый автомобильный контракт, и именно так мы будем с ним справляться (через интерфейс) .2

Наряду с общим объяснением Как указано выше, большая часть современного шаблона проектирования программного обеспечения в значительной степени полагается на такие интерфейсы, как внедрение зависимостей

. Рассмотрим этот пример:

У вас есть класс, способный воспроизводить медиафайлы (mp3). Вы даете этот класс своему другу, который пытается воспроизвести файлы типа MPEG. Он не смог бы сделать это, не внося существенных изменений в ваш класс.

public class MusicPlayer 
    {
       void Play(Mp3 _mp3File){}
    }

рассмотрите это

Вместо того, чтобы передавать тип mp3-файла методу воспроизведения, что если вы передадите этот метод, производный от интерфейса типа MediaType.

    public interface MediaType { }

    public class Mp3 : MediaType
    { }

    public class MPEG : MediaType
    { }

и класс:

    public class MusicPlayer 
    {
       void Play(MediaType _mediaFile){}
    }

В этом сценарии вы можете получить другой тип MediaFile и из MediaType, например MPEG, и передать его методу воспроизведения, и он с радостью примет его и воспроизведет для вас (при условии логики).

   public class TestPlayers
    {
        public void PlayMedia()
        {
            MusicPlayer musicPlayer = new MusicPlayer();
            musicPlayer.Play(new Mp3());
            musicPlayer.Play(new MPEG());
        }       
    }

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

1
ответ дан 3 December 2019 в 01:44
поделиться

Интерфейсы предназначены для дизайна. Фактическая реализация соответствует тому, что определено в дизайне (интерфейс чтения). Концепция интерфейса дает гибкость при проектировании системы, не вдаваясь в детали реализации или сохраняя расширяемость проекта за счет реализации интерфейсов в будущем. Это также известно как абстракция.

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

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

0
ответ дан 3 December 2019 в 01:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: