从超类静态方法内部调用子类静态方法 [英] Call subclass static method from inside superclass static method
问题描述
我有一大堆小型的,相关的类,这些类通过接口类链接在一起.所有类都实现一个静态方法,该方法检索和处理特定于该类的数据.
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 class.
该静态方法的输出至少需要两种格式.由于一种格式到另一种格式的转换始终是相同的,而且比较琐碎(尽管很长),所以我认为我将在超类中将其实现为一种具体的,密封的,静态的方法.
The output of that static method needs to be formatted in at least 2 ways. Since the transformation of one format to the other is always the same and rather trivial (though long), I thought I'd implement it as a concrete, sealed, static method in the superclass.
但是,然后我遇到了以下问题:
However, then I run into the following problem:
% (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
中的(???)
.
As far as I can see, calling SubClass.supersStaticMethod()
is impossible with this design, because static methods need to be called using the class name explicitly. In other words, there is no way to insert the subclass name instead of the (???)
in SuperClass.supersStaticMethod
above.
我尝试过的事情:
-
mfilename('class')
这不起作用,因为它总是返回'SuperClass'
-
dbstack
不包含该信息实际上是从子类中调用的信息
mfilename('class')
this doesn't work, because this always returns'SuperClass'
dbstack
does not contain the information that the method is actually being called from a subclass
我知道我可以通过使supersStaticMethod
为非静态并在临时实例(如SubClass().supersStaticMethod()
)上调用该方法来解决此问题.或在每个子类内创建一个小的包装方法,该包装方法仅使用mfilename('class')
作为参数来调用超类方法.或其他100件看上去同样笨拙的东西.
I know that I can work around this problem by making supersStaticMethod
non-static, and calling the method on a temporary instance (like SubClass().supersStaticMethod()
). Or create a small wrapper method inside each subclass that just calls the superclass method with mfilename('class')
as argument. Or any of a 100 other things that seem equally clumsy.
但是我真的很想知道是否存在某些meta.class
骗术或可以完全解决此问题的东西.我发现的只是此已过期的线程,它可以以编程方式处理MATLAB命令行获取子类名称.
But I'd really like to know if there is some meta.class
trickery or something that can cleanly solve this problem. All I've found is this dated thread, which processes the MATLAB command line programmatically to get the subclass name.
但是,我的类将在脚本/函数内部使用,并且命令行使用将仅用于调试目的...
However, my classes are to be used inside scripts/functions, and command line use is going to be for debugging purposes only...
有什么想法吗?
推荐答案
以下是我的恶意提案.想法是将当前的调用类存储在SuperClass
的静态变量"中,然后查询该字段并在feval
中使用它来调用正确的子类的方法.一些注意事项:
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
时),该方法才有效-在这种情况下,调用类字段将被错误地覆盖). -
SuperClass
的supersStaticMethod
不能为Sealed
,尽管子类的版本可以. - 在
SubClass.supersStaticMethod
之后清除静态变量",以确保仅从子类调用此方法. - 出于演示目的,我添加了
matlab.mixin.Heterogeneous
作为SuperClass
的超类.
- It could only work as long as you're not doing some computations in parallel (i.e. calling
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
'ssupersStaticMethod
cannot beSealed
, though the subclasses' versions can.- The "static variable" is cleared after
SubClass.supersStaticMethod
to ensure that this method is only ever called from a subclass. - I've added
matlab.mixin.Heterogeneous
as superclass ofSuperClass
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.
输出为:
Called from: SubClass1
other_arg1: -3, other_arg2: [-1;-2]
Called from: SubClass2
other_arg1: 3, other_arg2: [1;2]
这篇关于从超类静态方法内部调用子类静态方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!