Наследование от Запечатанных классов в MATLAB
В MATLAB, один из атрибутов класса (определяется после classdef
) является Sealed
, что означает, что ни один класс не может использовать его как суперкласс (или, если быть более точным, " чтобы указать, что эти классы не были разработаны для поддержки подклассов". 1).
Например, если я пытаюсь создать экземпляр класса, который определен ниже table
является Sealed
):
classdef SomeLie < table
end
Я бы получил 'MATLAB:class:sealed'
ошибка:
>> A = SomeLie;
Error using SomeLie
Class 'table' is Sealed and may not be used as a superclass.
Поскольку я отказываюсь получать от машины информацию о том, что я могу или не могу делать, я бы хотел Sealed
класс, независимо. Как я могу сделать это в MATLAB R2017a?
Мне трудно поверить, что эта система полностью герметична, поэтому я ищу решение, которое бы Sealed
атрибут, который будет игнорироваться (или что-то в этом роде). Желаемое решение должно работать без изменения каких-либо "определений классов библиотеки" для удаления Sealed
от них.
Я попытался поиграть с "отражением", но зашел в тупик...
classdef SomeLie % < table
properties (Access = private)
innerTable table;
end
properties (GetAccess = public)
methodHandles struct = struct();
end
methods
function slObj = SomeLie(varargin)
slObj.innerTable = table(varargin{:});
% methodHandles = methods(slObj.innerTable);
ml = ?table; ml = {ml.MethodList.Name}.';
ml = setdiff(ml,'end');
tmpStruct = struct;
for indM = 1:numel(ml)
tmpStruct.(ml{indM}) = str2func([...
'@(varargin)' ml{indM} '(slObj.innerTable,varargin{:})']);
end
slObj.methodHandles = tmpStruct;
end
function varargout = subsref(slObj,varargin)
S = struct(slObj);
varargout{:} = S.methodHandles.(varargin{1}.subs)(varargin{:});
end
end
end
(Нет необходимости исправлять приведенный выше код, я просто делюсь)
1 ответ
Я не думаю, что машина - проблема, но у дизайнера класса и у него, конечно, есть хорошие мотивы, чтобы запечатать класс. "Философия" кодирования, часть, вы можете "владеть" классом в классе-обертке, не определяя его запечатанным.
Например, предположим, что класс Hello запечатан и имеет метод (или функцию, если вы хотите), sayHello, который вы хотели бы использовать в унаследованных классах, вы можете определить класс FreeHello (public), который содержит экземпляр Hello. В конструкторе вы создаете соответствующий Hello, а затем определяете метод sayHello, тело которого просто вызывает ваш экземпляр Hello и заставляет его выполнить метод sayHello (и, соответственно, возвращает выходные данные).
Чтобы "открыть" запечатанный класс, вы должны сделать это для всех свойств и открытых методов; Конечно, вы по-прежнему не можете получить доступ к закрытым методам, но теперь вы можете создавать подклассы своего класса-обёртки, как хотите.