从超类静态方法内部调用子类静态方法 [英] Call subclass static method from inside superclass static method

查看:143
本文介绍了从超类静态方法内部调用子类静态方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一大堆小型的,相关的类,这些类通过接口类链接在一起.所有类都实现一个静态方法,该方法检索和处理特定于该类的数据.

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时),该方法才有效-在这种情况下,调用类字段将被错误地覆盖).
  • SuperClasssupersStaticMethod不能为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's supersStaticMethod cannot be Sealed, 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 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.

输出为:

Called from: SubClass1
other_arg1: -3, other_arg2: [-1;-2]

Called from: SubClass2
other_arg1: 3, other_arg2: [1;2]

这篇关于从超类静态方法内部调用子类静态方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆