Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override the empty() method for an abstract class in matlab

Tags:

oop

matlab

I've come across this problem many times, and I was hoping to solve it finally.

Context

When creating a heterogeneous class hierarchy in MATLAB, there is a protected static method called getDefaultScalarElement, which allows you to define the default scalar object for creating arrays. If an element of the hierarchy is abstract, you can override that method to use a different class.

For example

classdef (Abstract) AbstractRoot < matlab.mixin.Heterogeneous

    methods (Static, Access = protected)
        function DefaultObj = getDefaultScalarElement()
            DefaultObj = ConcreteSubclass1();
        end
    end

end

classdef ConcreteSubclass1 < AbstractRoot

end

classdef ConcreteSubclass2 < AbstractRoot

end

Every concrete class in matlab has a public static hidden method called empty, which creates an empty array of that object. I would like to create an empty method for the abstract class which is similar in functionality to the getDefaultScalarObject method. This would allow me to call AbstractRoot.empty() and receive an empty array of the default kind.

For example:

classdef (Abstract) AbstractRoot < matlab.mixin.Heterogeneous

    methods (Static, Hidden)
        function EmptyObj = empty()
            EmptyObj = ConcreteSubclass1.empty();
        end
    end

    methods (Static, Access = protected)
        function DefaultObj = getDefaultScalarElement()
            DefaultObj = ConcreteSubclass1();
        end
    end

end

Unfortunately, this doesn't work (infinite recursion). The main problem I have is that I'm not sure how to override empty, and still be able to call the built-in version of it from the subclass, since empty is not inherited from anywhere

Questions

  1. Is it possible to call the built-in version of empty? If so, how?
  2. Is there a way of overriding empty in the abstract base class, so that subclasses will still call the built-in version of empty. Similarly, can I check which version of the static method was called (eg. 'AbstractRoot.empty' or 'ConcreteSubclass1.empty') from inside the method, so I can handle it on a case by case basis?
like image 516
hoogamaphone Avatar asked Nov 11 '22 06:11

hoogamaphone


1 Answers

Better late than never...

Its completely undocumented as far as I can tell: (can only verify for 2013a)

  • Indexing a 1x1 array of any class
  • with an empty double array of any possible size (0 in at least 1 dimension)
  • will create a empty array the given class with the given size.

With this we can recreate an equivalent of the builtin version of empty for any class.

This can then be used to override the builtin version. Thus it can be defined, separately, for the subclasses, which will prevent the defined superclass method being called (and avoid the recursion).

So with 3 classdef m-files Firstly the second AbstractRoot definition from the question; Then two subclasses having the empty method defined as below (with the Obj variable created as the required class)

classdef ConcreteSubclass1 < AbstractRoot 

    methods (Static, Hidden)
        function EmptyObj = empty( varargin )
            if isempty( varargin )   
                ind = double.empty;  %// as calling double.empty([]) errors
            else
                ind = double.empty( [varargin{:}] );  
            end
            Obj = ConcreteSubclass1();  %// or Obj = ConcreteSubclass2();
            EmptyObj = Obj(ind);
        end
    end

end

we can now call all 3 class.empty methods

a = AbstractRoot.empty
b = ConcreteSubclass2.empty
c = ConcreteSubclass1.empty

a = 

  0x0 ConcreteSubclass1 array with no properties.


b = 

  0x0 ConcreteSubclass2 array with no properties.


c = 

  0x0 ConcreteSubclass1 array with no properties.

Finally if the empty definition is omitted from a subclass of AbstractRoot, the overloaded version for abstract root will be called resulting in a ConcreteSubclass1 array

 d = ConcreteSubclass3.empty

d = 

  0x0 ConcreteSubclass1 array with no properties.
like image 107
RTL Avatar answered Nov 15 '22 09:11

RTL