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