How to call sub or superclass constructor when recursively creating objects

5 visualizaciones (últimos 30 días)
Hi,
I'm writing a tree class. I'd like a superclass to contain generic construction / maintenance methods, then be able to subclass it for a range of different, more specific purposes.
Something like:
classdef SuperTree < handle
properties
BranchLocation
Parent
Children
end
methods
function obj = SuperTree(varargin)
% construct the the object
end
function subdivide(obj, limit_criterion)
% Lots of code that's difficult to maintain and
% shouldn't be overloaded in a subclass
if limit_criterion
% Create child branches
chld1 = SuperTree(args);
chld2 = SuperTree(args);
obj.Children = [chld1; chld2]
end
end
end
The problem is that if I create a subclass, then the subdivision method still makes a call to SuperTree() to construct its children.
Is there a way of getting (say) a handle to the constructor function of the current object? I don't want to be overloading the subdivide method for each of my subclasses. Something like this would be ideal:
function subdivide(obj, limit_criterion)
% Lots of code that's difficult to maintain and
% shouldn't be overloaded in a subclass
if limit_criterion
% Create child branches
chld1 = obj.Constructor(args);
chld2 = obj.Constructor(args);
obj.Children = [chld1; chld2]
end
At the moment I'm working around this with a small utility method, that I overload in each subclass. Working? Yes. Elegant? No. So I'd be interested in any 'proper' solutions.
Thanks!
Tom
  3 comentarios
per isakson
per isakson el 30 de Ag. de 2016
@Guillaume, which problems do you see in using class(obj) in this context?
This "small utility method" does it contain expressions like chld=Tree(args);?
Guillaume
Guillaume el 30 de Ag. de 2016
I don't see any problem in using class(obj). It works fine. It's probably because I come from C++ where reflection does not exist that I find it inelegant. It's probably irrational
If I understood correctly (and the way I'd do it), the small utility method is a one-liner method that is overloaded in each class and just call the class constructor:
classdef SuperTree < handle
%... props definition
methods
function obj = SuperTree(varargin)
% construct the the object
end
function subdivide(obj, limit_criterion)
% Lots of code that's difficult to maintain and
% shouldn't be overloaded in a subclass
if limit_criterion
% Create child branches
chld1 = NewMe(args);
chld2 = NewMe(args);
obj.Children = [chld1; chld2]
end
%small utility function to be overloaded in each subclass
function this = NewMe(args)
error('Must be overloaded by children');
this = SuperTree(args);
end
end
end
and child
classdef Child < SuperTree
%... props definition
methods
function obj = Child(varargin)
% construct the the object
end
function this = NewMe(args)
this = Child(args);
end
end
end

Iniciar sesión para comentar.

Respuestas (1)

per isakson
per isakson el 28 de Ag. de 2016
Editada: per isakson el 30 de Ag. de 2016
I think, I understand and that it's doable. Replace
chld1 = obj.Constructor(args);
by
str = class( obj );
chld1 = feval( str, args );
And in the constructor of the subclass
obj@SuperTree( arguments )
Whether this is the proper way, I don't know.
&nbsp
ADDENDUM 2016-08-29 in response to the comment: "2. this will eliminate any possibility for code generation."
Would this allow code generation? Replace
chld1 = feval( str, args );
by
chld1 = TreeFactory( str, args );
where the simplest form of TreeFactory is an ordinary function
function tree = TreeFactory( str, args )
switch str
case 'oak', tree = Oak( args );
otherwise
end
end
  3 comentarios
per isakson
per isakson el 28 de Ag. de 2016
Editada: per isakson el 28 de Ag. de 2016
There has been complains regarding the performance of MATLAB OOP. However, its improving. I've learned to avoid solutions with thousands of simple objects.
"feval() is likely to be quite slow" &nbsp Based on some simple tests (R2016a) I don't think so. (That is, it's not slow compared to other ways to create objects in Matlab.)
"will eliminate any possibility for code generation" &nbsp Yes.
Given the superclass, handle, I cannot think of any other approach. Or maybe, see Clone Handle Object - using MATLAB OOP by Bobby Nedelkovski
per isakson
per isakson el 29 de Ag. de 2016
I added an alternative to feval to the answer.

Iniciar sesión para comentar.

Categorías

Más información sobre Construct and Work with Object Arrays en Help Center y File Exchange.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by