matlabclasspolymorphismsuperclassheterogeneous-array

How to test the class of elements in a heterogenous array?


MATLAB supports grouping objects belonging to subclasses of a common root class implementing matlab.mixin.Heterogeneous into a single array, which would have the class of the closest common ancestor, for example:

hObj = [ uifigure, uibutton, gobjects(1) ];
K>> class(hObj)
ans =    
    'matlab.graphics.Graphics'    

I would like to write a function that tests whether the passed-in list of handles of unspecified size (usually a scalar, but possibly an array) belongs to a specific hard-coded class or its descendants.

If the input is a scalar or a homogeneous array (i.e. all objects have the same class), and we are testing for the target class itself (not including subclasses), we will get the correct result from a function like this:

function tf = isCorrectClass(hCandidate)
  TARGET = 'matlab.ui.Figure';
  tf = isa(hCandidate, TARGET);
end

However, this will not work if hCandidate is a heterogeneous array, so we must do:

function tf = isCorrectClass(hCandidate)
  TARGET = 'matlab.ui.Figure';
  tf = arrayfun(@(x)isa(x, TARGET), hCandidate);
end

which works because selecting individual elements from a heterogeneous array makes them revert to their own specific class.

Question: How can I adapt the isCorrectClass function shown above to the following hierarchy, where the target class is Middle (assuming my input array may contain objects of any of the hierarchy's classes)?

%                  HierarchyRoot "implements" matlab.mixin.Heterogeneous
%                   /        \
%               Middle       LeafD
%             /    |   \ 
%        LeafA   LeafB  LeafC

Solution

  • A simple way to achieve this is using the relational operators of metaclass objects:

    function tf = isCorrectClass(hCandidate)
      TARGET = ?Middle; % Assuming such a class exists
      tf = arrayfun(@(x)metaclass(x) <= TARGET, hCandidate);
    end
    

    Where:

    mc = ?ClassName returns the meta.class object for the class with name, ClassName. The ? operator works only with a class name, not an object.

    and the meaning of metaclass(x) <= TARGET is that x can either be a subclass or the same class as TARGET.