Множественное наследование - избежать из-за алмазной пробы?
Это часто возникает у меня: у меня есть класс A, который расширен классом B, а затем есть классы, которые являются производными либо от класса A, либо от обоих (множественное наследование).
Пример: у меня есть объект, представляющий математическую модель, которая определяет интерфейс IModel, чтобы применить его и найти его коэффициенты.
Исходя из этого, я получил PolynomialModel, который определяет большой класс полиномиальных моделей.
С другой стороны, я определяю третий интерфейс "IAdaptiveModel", который определяет операторы, такие как "+" и "-", для адаптивного создания моделей. Для полиномиальной модели это добавило бы их коэффициенты. С другой стороны, для нейронной сети это не имеет смысла.
Должен ли теперь IAdaptiveModel происходить из IModel (что приводит к возникновению проблемы с бриллиантами) или этого следует избегать?
Преимущество: когда я делаю проверку во время выполнения для IAdaptiveModel, я могу быть уверен, что это также IModel, который должен быть. Недостаток: например, PolynomialModel наследовал бы IModel дважды.
Вопрос не нацелен на конкретный язык программирования, а вот псевдокод:
classdef IModel
methods (Abstract)
y = apply(obj, x);
obj = solve(obj, x, y);
end
end
classdef IAdaptiveModel % should this derive from IModel ??
methods (Abstract)
obj = plus(obj, other);
obj = minus(obj, other);
end
end
% derives from IModel and can be used by objects requiring apply/solve
% derives from IAdaptiveModel to be used from adaptive algorithms which use plus/minus
classdef PolyModel < IBehavioralModel & IAdaptiveModel
[...]
end
% in a different piece of code in an adaptive algorithm I would have
if isa(modelObject,'IAdaptiveModel')
% technically this could fail because solve does not need to be implemented when IAdaptiveModel does not derive from IModel
modelObject = modelObject.solve(x,y);
modelObject = modelObject + const * deltaModel;
else
error('We require an object that supports IAdaptiveModel');
end