I've come across this problem many times, and I was hoping to solve it finally.
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
Better late than never...
Its completely undocumented as far as I can tell: (can only verify for 2013a)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With