How to call sub or superclass constructor when recursively creating objects
5 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
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
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
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
Respuestas (1)
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.
 
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
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"   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"   Yes.
Given the superclass, handle, I cannot think of any other approach. Or maybe, see Clone Handle Object - using MATLAB OOP by Bobby Nedelkovski
Ver también
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!