Исходя из фона С++, Im используется для множественного наследования. Мне нравится ощущение дробовика, прямо направленного на мою ногу. В настоящее время я больше работаю на С# и Java, где вы можете наследовать только один базовый класс, но реализовать любое количество интерфейсов (правильно ли я получил терминологию?).
Например, рассмотрим два класса, которые реализуют общий интерфейс, но разные (но требуемые) базовые классы:
public class TypeA : CustomButtonUserControl, IMagician
{
public void DoMagic()
{
// ...
}
}
public class TypeB : CustomTextUserControl, IMagician
{
public void DoMagic()
{
// ...
}
}
Оба класса UserControl
, поэтому я не могу заменить базовый класс. Оба должны реализовать функцию DoMagic
. Моя проблема в том, что обе реализации функции идентичны. И я ненавижу код копирования и вставки.
Возможные решения:
- Я, естественно, хочу, чтобы
TypeA
иTypeB
делили общий базовый класс, где я могу написать это идентичное определение функции только один раз. Однако из-за ограничения только одного базового слоя я не могу найти место по иерархии, где он подходит. - Можно также попытаться реализовать своего рода составной шаблон. Помещение функции
DoMagic
в отдельный вспомогательный класс, но функция здесь нуждается (и изменяет) довольно много внутренних переменных/полей. Отправка их всех в качестве (ссылочных) параметров выглядела бы плохо. - Моя кишка говорит мне, что шаблон адаптера может иметь место здесь, некоторый класс для преобразования между ними, когда это необходимо. Но он также чувствует себя взломанным.
Я отметил это агностиком языка, поскольку он применяется ко всем языкам, использующим этот подход с одним базовым классом и множеством интерфейсов.
Кроме того, пожалуйста, укажите, что я, по-видимому, неправильно понял какие-либо шаблоны, которые я назвал.
В С++ я бы просто создал класс с частными полями, эту реализацию функции и поместил ее в список наследования. Каков правильный подход к С#/Java и тому подобное?