I have a large set of small, related classes linked together by an interface class. All classes implement a static method, which retrieves and processes data specific to the cla
Below's my hacky proposal. The idea is that you store the current calling class in a "static variable" of SuperClass
, then query this field and use it in feval
to call the correct subclass' method. Several notes:
SubClass#.supersStaticMethod
from more than one thread at a time under a shared memory architecture - in which case the calling class field will be overwritten erratically).SuperClass
's supersStaticMethod
cannot be Sealed
, though the subclasses' versions can.SubClass.supersStaticMethod
to ensure that this method is only ever called from a subclass.matlab.mixin.Heterogeneous
as superclass of SuperClass
for the purpose of demonstration.classdef SuperClass < handle & matlab.mixin.Heterogeneous
properties (Abstract = true, Access = private, Constant = true)
subclass@meta.class scalar;
end
methods (Static, Abstract)
[arg1, arg2] = subsStaticMethod;
end
methods (Sealed, Static)
function out = currentClass(input) % < the closest thing in MATLAB to a static variable
persistent currentClass;
if nargout == 0 && nargin == 1 % "setter" mode
currentClass = input;
out = [];
else % "getter" mode
out = currentClass;
end
end
end
methods (Static)
function [other_arg1, other_arg2] = supersStaticMethod
% Who am I?
whosCalling = SuperClass.currentClass();
if isempty(whosCalling) || ~isa(whosCalling,'meta.class')
[other_arg1,other_arg2] = deal(NaN);
return
else
whosCalling = whosCalling.Name;
end
fprintf(1,'\nCalled from: %s\n', whosCalling);
% Get data here
[arg1, arg2] = feval([whosCalling '.subsStaticMethod']);
% transform data here
other_arg1 = arg1+arg2; other_arg2=[arg1(:);arg2(:)];
fprintf(1,'other_arg1: %s, other_arg2: %s\n',...
num2str(other_arg1), mat2str(other_arg2));
% Clear the current class
SuperClass.currentClass([]);
end
end
end
classdef SubClass1 < SuperClass
properties (Constant)
subclass@meta.class scalar = ?SubClass1;
end
methods (Static)
function [other_arg1, other_arg2] = supersStaticMethod
SubClass1.currentClass(SubClass1.subclass);
[other_arg1, other_arg2] = supersStaticMethod@SuperClass;
end
function [arg1, arg2] = subsStaticMethod
arg1 = -1; arg2 = -2;
end
end % static methods
end % classdef
classdef SubClass2 < SuperClass
properties (Constant)
subclass@meta.class scalar = ?SubClass2;
end
methods (Static)
function [other_arg1, other_arg2] = supersStaticMethod
SubClass1.currentClass(SubClass2.subclass);
[other_arg1, other_arg2] = supersStaticMethod@SuperClass;
end
function [arg1, arg2] = subsStaticMethod
arg1 = 1; arg2 = 2;
end
end % static methods
end % classdef
Then you can test it like this:
function q31269260
arr = [SubClass1, SubClass2];
for ind1 = 1:numel(arr)
arr(ind1).supersStaticMethod;
end
% arr.supersStaticMethod would not work because elements are treated as "instances" of
% SuperClass, whose supersStaticMethod should not be called directly.
The output is:
Called from: SubClass1
other_arg1: -3, other_arg2: [-1;-2]
Called from: SubClass2
other_arg1: 3, other_arg2: [1;2]