Множественное наследование с использованием интерфейса C#

Я пытаюсь использовать выборочные функции двух классов в 3-м классе. Например, у меня есть класс Button1, который создает причудливую рамку кнопки, и класс Button2, который записывает текст в цветном формате. Теперь эти классы предоставляются мне сторонними поставщиками, где у меня нет доступа к коду. Классы не запечатаны, поэтому я могу наследовать их, и оба они являются производными от базового класса Button.

Теперь мое требование состоит в том, чтобы создать третий класс с именем Button3 class, который имел бы функциональность как для создания причудливой рамки, так и для цветного текста. В идеале я бы наследовал оба класса и использовал определенные функции. Это невозможно в C#, так как он не имеет множественного наследования.

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


person K Singh    schedule 31.12.2009    source источник
comment
Интерфейсы не содержат реализации. В вашем случае вы не сможете использовать классы, предоставляемые вашими поставщиками. Вы знаете, верно?   -  person o.k.w    schedule 31.12.2009
comment
Множественное наследование! = Реализация нескольких интерфейсов. Интерфейсы не являются решением этой проблемы, они являются альтернативой, как и сдерживание.   -  person Muhammad Hasan Khan    schedule 31.12.2009
comment
Я упомянул множественное наследование и интерфейсы, потому что я читал, что интерфейсы помогают в создании множественных взаимодействий (в первую очередь веб), поэтому я хотел знать, можно ли решить проблему, подобную упомянутой выше, с помощью интерфейсов или нет?   -  person K Singh    schedule 31.12.2009


Ответы (5)


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

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

  • Полное наследование подразумевает отношение типа «есть-а». Ваши кнопки с причудливыми рамками — это кнопки, но они не могут быть кнопками с причудливым текстом.

  • Интерфейсы определяют отношение «имеет». Здесь у вас есть «возможность установить причудливую рамку на кнопке» и «возможность установить причудливый текст на кнопке». С этой точки зрения ничто не мешает вам применить обе «способности» к одному и тому же классу кнопок.

Таким образом, интерфейс позволяет выполнять агрегацию. Рассмотрим два класса DoerOfThis: IThis и DoerOfThat: IThat. Чтобы создать третий класс Something, который выполняет как DoThis, так и DoThat, агрегируйте:

public class Something : IThis, IThat
{
  public This DoerOfThis { set; }
  public That DoerOfThat { set; }

  public void DoThis()
  {
     DoerOfThis.DoThis();
  }

  public void DoThat()
  {
     DoerOfThat.DoThat();
  }
}
person Jeremy McGee    schedule 31.12.2009

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

person user366312    schedule 31.12.2009

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

Что вам нужно сделать, так это взять исходный код одного из двух классов Button и изменить его, используя исходный код другого класса Button в качестве вдохновения (маловероятно, что вы сможете использовать код напрямую). Если у вас нет доступа (или законного права на использование) исходного кода, то, боюсь, вы не сможете сделать это таким образом.

Ваши оставшиеся варианты:

  • Свяжитесь с авторами Button1 и попросите их добавить нужные функции из Button2.
  • Свяжитесь с авторами Button2 и попросите их добавить нужные функции из Button1.
  • Напишите новый класс кнопки самостоятельно.
person Mark Byers    schedule 31.12.2009

Интерфейс просто определяет сигнатуру метода, но не тело метода. Это означает, что вы все еще не можете получить поведение в Button1 и Button2, даже если вы используете интерфейс.

Вы можете попросить своего поставщика сделать следующее:

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

Затем вы наследуете свой button3 от обоих интерфейсов, вызываете вышеуказанные методы, чтобы делать все, что нужно.

person Graviton    schedule 31.12.2009

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

Пользовательские элементы управления — если вы используете winforms. Вложенные элементы управления — если вы используете WPF.

person FernandoZ    schedule 31.12.2009