调用子类的静态方法从内部超静态方法(Call subclass static method from

2019-10-23 16:01发布

我有一个大组由一个接口类连接在一起的小,相关类。 所有的类实现一个静态方法,以检索并处理特定于类的数据。

需要一个静态方法的输出中的至少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命令行程序来获取子类的名称。

然而,我的课都在里面的脚本/功能被使用,以及命令行使用将是仅用于调试的目的...

有任何想法吗?

Answer 1:

下面是我的哈克建议。 这个想法是,你存储当前调用类的“静态变量” SuperClass ,然后查询该字段,并用它在feval来调用正确的子类的方法。 有几个注意事项:

  • 因为你没有做并行一些计算(即调用它只能长工作SubClass#.supersStaticMethod -在这种情况下,调用类字段将覆盖不稳定从多个线程在共享内存架构下的时间)。
  • SuperClasssupersStaticMethod不能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]


文章来源: Call subclass static method from inside superclass static method