我有一个大组由一个接口类连接在一起的小,相关类。 所有的类实现一个静态方法,以检索并处理特定于类的数据。
需要一个静态方法的输出中的至少2种方式来进行格式化。 由于一个格式转换为其他转型始终是相同的,相当琐碎(虽然长),我想我会实现它作为一个具体的,密封,静中有超类方法。
不过,后来我碰到以下问题:
% (in Superclass.m)
classdef SuperClass < handle
methods (Static, Abstract)
[arg1, arg2] = subsStaticMethod;
end
methods (Sealed, Static)
function [other_arg1, other_arg2] = supersStaticMethod
% Get data here
[arg1, arg2] = (???).subsStaticMethod
% transform data here
% ...
end
end
end
% (in Subclass.m)
classdef SubClass < SuperClass
methods (Static)
function [arg1, arg2] = subsStaticMethod
% Get class-specific data here
% ...
end
end
end
据我所看到的,调用SubClass.supersStaticMethod()
是不可能用这种设计,因为静态方法需要使用类名显式调用。 换句话说,没有办法插入子类名称而不是(???)
在SuperClass.supersStaticMethod
上方。
事情我已经尝试:
-
mfilename('class')
这是不行的,因为这会返回'SuperClass'
-
dbstack
不包含信息,该方法实际上是被从一个子类,称为
我知道我可以通过使解决此问题supersStaticMethod
非静态,并呼吁一个临时的实例方法(如SubClass().supersStaticMethod()
或创建只是调用与超类方法的每个子类中的小包装方法mfilename('class')
作为参数。 或任何的其他100分的东西,似乎同样笨拙。
但我真的很想知道,如果有一些meta.class
弄虚作假或东西,可以干净地解决这个问题。 所有我发现是这种过时的线程 ,它处理的MATLAB命令行程序来获取子类的名称。
然而,我的课都在里面的脚本/功能被使用,以及命令行使用将是仅用于调试的目的...
有任何想法吗?
下面是我的哈克建议。 这个想法是,你存储当前调用类的“静态变量” SuperClass
,然后查询该字段,并用它在feval
来调用正确的子类的方法。 有几个注意事项:
- 因为你没有做并行一些计算(即调用它只能长工作
SubClass#.supersStaticMethod
-在这种情况下,调用类字段将覆盖不稳定从多个线程在共享内存架构下的时间)。 -
SuperClass
的supersStaticMethod
不能Sealed
,虽然子“的版本即可 。 - “静态变量”之后被清除
SubClass.supersStaticMethod
确保这一方法永远只在一个子类调用。 - 我已经添加
matlab.mixin.Heterogeneous
作为超SuperClass
为示范的目的。
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
然后,你可以这样测试:
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.
输出是:
Called from: SubClass1
other_arg1: -3, other_arg2: [-1;-2]
Called from: SubClass2
other_arg1: 3, other_arg2: [1;2]