Любой реальный пример использования интерфейса, связанного со множественным наследованием

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

7
задан Sarah Vessels 18 December 2009 в 19:49
поделиться

8 ответов

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

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

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

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

10
ответ дан 6 December 2019 в 07:50
поделиться

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

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

ОБНОВЛЕНИЕ

В "реальном" примеры "Я использую интерфейсы с: - Модульное тестирование - ОБЩИЕ (например, репозиторий, шлюз, настройки)

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; }
}
2
ответ дан 6 December 2019 в 07:50
поделиться

Вот один (на 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
ответ дан 6 December 2019 в 07:50
поделиться

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

Интерфейс - это просто способ объявить, что класс реализует некоторые виртуальные функции, и как эти виртуальные функции должны быть размещены в классе 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.
1
ответ дан 6 December 2019 в 07:50
поделиться

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

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

0
ответ дан 6 December 2019 в 07:50
поделиться

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

Итак, я создал интерфейс 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);
    }
}

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

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

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

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

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

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

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

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

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

4
ответ дан 6 December 2019 в 07:50
поделиться

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

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
ответ дан 6 December 2019 в 07:50
поделиться

В качестве примечания, вы можете отключить функцию автоматического изменения размера Firefox, отправив (несколько плохо задокументированную) команду enableObjectResizing в документ:

document.execCommand("enableObjectResizing", false, false);

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

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

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

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

Какой бы генератор у меня ни был изначально, после того, как я передал его в «IGenerator» I может вызвать на нем "generateNow (4)". Мне не нужно будет точно знать, какой тип генератора я вернул, что по сути означает, что больше никаких «экземпляров переменной класса 1», «экземпляра переменной класса 2» и т. Д. В гигантском операторе if.

1
ответ дан 6 December 2019 в 07:50
поделиться
Другие вопросы по тегам:

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