Любой реальный пример использования интерфейса, связанного с множественным наследованием - PullRequest
7 голосов
/ 18 декабря 2009

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

Ответы [ 9 ]

10 голосов
/ 18 декабря 2009

Хорошим примером интерфейса является шаблон репозитория. Ваш интерфейс будет определять методы, такие как Get, GetAll, Update, Delete и т. Д. Никакой реализации, только сигнатуры функций.

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

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

Множественное наследование не существует в C # в том смысле, что вы можете наследовать только от одного «конкретного» класса; хотя вы можете наследовать (или «реализовывать») столько интерфейсов, сколько хотите.

4 голосов
/ 18 декабря 2009

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

Итак, я создал интерфейс IForce, который имеет функцию обновления для своей подписи. Все мои силы реализуют этот интерфейс:

public interface IForce
{
    void Update(Particle particle, GameTime gameTime);
}

Вот пример реализации.

public class Spring : IForce
{
    private Particle ThisParticle;
    private Particle ThatParticle;

    private float K;

    public Spring(Particle thisParticle, Particle thatParticle, float k)
    {
        ThisParticle = thisParticle;
        ThatParticle = thatParticle;
    }

    public void Update(Particle particle, GameTime gameTime)
    {            
        float X = Vector3.Length(ThisParticle - ThatParticle);

        ThisParticle.Forces.Add(K * X);
    }
}

Функция обновления имеет упрощенное обновление силы пружины для облегчения понимания.

Это помогает несколькими способами.

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

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

Я использую интерфейсы каждый день в самых разных ситуациях. Они фантастические!

3 голосов
/ 28 июня 2012

Примечание. Интерфейс используется для ограничения и доступа к методам, событиям и т. Д. Из разных классов любой ценой. Это означает, что мы можем определить гораздо больше методов внутри любого класса, но когда мы вызываем методы через интерфейс, это означает, что мы хотим только другие, чем ограниченные. методы. В приведенной ниже программе User1 может использовать Read & Write, но User2 может Write и Execute. Смотрите эту программу ниже .........

namespace ExplConsole
{
    class Program 
    {
        static void Main ()
        {
            System.Console.WriteLine("Permission for User1");
            User1 usr1 = new Test(); // Create instance.
            usr1.Read(); // Call method on interface.
            usr1.Write();
            System.Console.WriteLine("Permission for User2");
            User2 usr2 = new Test();
            usr2.Write();
            usr2.Execute();
            System.Console.ReadKey();
        }
    }
    interface User1
    {
        void Read();
        void Write();
    }
    interface User2
    {
        void Write();
        void Execute();
    }
    class Test : NewTest,User1, User2 
    {
        public void Read()
        {
            Console.WriteLine("Read");
        }
        public void Write()
        {
            Console.WriteLine("Write");
        }
    }
    class NewTest 
    {
        public void Execute()
        {
            Console.WriteLine("Execute");
        }
    }
}

Выход:

    Permission for User1
    Read
    Write
    Permission for User2
    Write
    Execute
2 голосов
/ 18 декабря 2009

Интерфейсы просто определяют контракт открытых элементов (например, свойств, методов, событий) для вашего объекта, а не поведения.

interface IDog
{
    void WagTail();    //notice no implementation
    ISound Speak();    //notice no implementation
}

class Spaniel : IDog
{
    public void WagTail()
    {
        Console.WriteLine("Shook my long, hairy tail");
    }

    public ISound Speak()
    {
        return new BarkSound("yip");
    }

}

class Terrier : IDog
{
    public void WagTail()
    {
        Console.WriteLine("Shook my short tail");
    }

    public ISound Speak()
    {
        return new BarkSound("woof");
    }
}

UPDATE

В «реальных примерах» я использую интерфейсы с: - Модульное тестирование - ОБЩИЕ СВЕДЕНИЯ (например, хранилище, шлюз, настройки)

interface Repository<T>{
    T Find(Predicate<T>);
    List<T> ListAll();
}

interface Gateway<T>{
    T GetFrom(IQuery query);
    void AddToDatabase(IEntity entityItem);
}

interface Settings<T>{
    string Name { get; set; }
    T Value { get; set; }
    T Default { get; }
}
1 голос
/ 18 декабря 2009

Простой ответ, на мой взгляд, и то, что я сам несколько новичок в интерфейсах, заключается в том, что реализация интерфейса в классе по существу означает: «Этот класс ДОЛЖЕН определять функции (и параметры) в интерфейсе».

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

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

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

public interface IGenerator {
    public void generateNow(int period);
}

Что говорит им определить по крайней мере функцию "public generateNow (int period)".

Независимо от того, какой генератор у меня изначально был, после того, как я приведу его к «IGenerator», я могу вызвать на нем «generateNow (4)». Мне не нужно быть уверенным, какой тип генератора я возвратил, что по сути означает, что больше нет «переменной instanceof Class1», «переменной instanceof Class2» и т. Д. В гигантском операторе if.

1 голос
/ 18 декабря 2009

Множественное наследование означает, что класс может использоваться в нескольких ситуациях: [псевдокод]

interface Shape {
    // shape methods like draw, move, getboundingrect, whatever.
}

interface Serializable {
    // methods like read and write
}

class Circle : public Shape, public Serializable {
    // TODO: implement Shape methods
    // TODO: implement Serializable methods
}

// somewhere later
{
    Circle circle;
    // ...
    deserializer.deserialize(circle);
    // ...
    graphicsurface.draw(circle);
    // ...
    serializer.serialize(circle);
}

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

1 голос
/ 18 декабря 2009

Вот один из них (на Java, но это не важно, поскольку они похожи): В моем проекте я создал простой интерфейс:

public interface Identifiable<T> {
    public T getId();
}

Что является простой заменой некоторым видам аннотаций. Следующий шаг: я заставил все классы сущностей реализовать этот интерфейс.

Третий шаг - написать несколько синтаксически-подобных методов:

public <T> List<T> ids(List<? extends Identifiable<T> entities) { ... }

Это был просто пример.

Более сложный пример - это что-то вроде правил валидации: у вас есть какой-то механизм валидации (вероятно, написанный вами) и простой интерфейс для правила:

public interface ValidationRule {
    public boolean isValid(...);
}

Итак, этот движок требует от вас соблюдения правил. И, конечно, будет множественное наследование, так как вы, несомненно, пожелаете больше, чем одно правило.

1 голос
/ 18 декабря 2009

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

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

Назначение интерфейсов состоит в том, что вы можете неявно приводить класс, реализующий интерфейс I, к экземпляру интерфейса I:

interface I {
    void doStuff();
}

class Foo : I {
    void doStuff() {}

    void useAnI(I i) {}
}

var foo = new Foo();
I i = foo;  // i is now a reference to the vtable pointer for I in foo.
foo.useAnI(i);  // Works.  You've passed useAnI a Foo, which can be used as an I.
0 голосов
/ 18 декабря 2009

Взгляните на что-то, с чем вы знакомы - например, коллекцию List в C #. Списки определяют интерфейс IList, а общие списки определяют интерфейс IList. IList предоставляет такие функции, как Add, Remove, и List реализует эти функции. Есть также BindingList, которые реализуют IList немного по-другому.

Я бы также рекомендовал Head First Design Patterns . Примеры кода на Java, но легко переводятся на C #, плюс они познакомят вас с реальной мощью интерфейсов и шаблонов проектирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...