Хотя интерфейс - это одна из возможностей, вы также можете попасть в классы с наследованием и полиморфизмом. Таким образом, у вашего базового класса могут быть общие свойства и методы с заданными сигнатурами. Сделайте методы «виртуальными», что позволит вам «переопределить» их на производных классах из этой базы.
Этот параметр может помочь предотвратить дублирование кода и в таких общих вещах, как работа со списком (ofThings). Вы можете создать виртуальный метод «GetThings ()», и ваш основной базовый класс все еще может переключаться между ними и работать с ними.
Так что есть много путей, по которым вы можете пойти.
Из вашего поста вы звучите довольно хитроумно, так что вы можете также захотеть взглянуть на "дженерики", которые также являются мощной функцией.
Интерфейс похож на контракт, согласно которому все, что использует мой интерфейс, должно иметь все компоненты, свойства, методы, которые вы выражаете. Это заставляет вас объявлять их все отдельно для каждого класса, использующего его.
Абстрактный класс - это скорее объявление класса того, что должно быть найдено в классе.
Однако, определяя код класса WITH, который работает с (чем угодно), вы можете получить его, не повторяя код повсюду.
Надеюсь, что эти варианты помогут вам в чем-то, и если вы спросите более подробно о том, что вы пытаетесь сделать, многие из них могут помочь вам найти подход, который может быть лучше, чем другие.