Call subclass static method from inside superclass static method

后端 未结 1 1635
春和景丽
春和景丽 2021-01-25 18:42

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

相关标签:
1条回答
  • 2021-01-25 19:32

    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:

    • 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.
    

    The output is:

    Called from: SubClass1
    other_arg1: -3, other_arg2: [-1;-2]
    
    Called from: SubClass2
    other_arg1: 3, other_arg2: [1;2]
    
    0 讨论(0)
提交回复
热议问题