How to call sub or superclass constructor when recursively creating objects

조회 수: 3 (최근 30일)
Tom Clark
Tom Clark 2016년 8월 28일
댓글: Guillaume 2016년 8월 30일
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
per isakson
per isakson 2016년 8월 30일
@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 2016년 8월 30일
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

댓글을 달려면 로그인하십시오.

답변 (1개)

per isakson
per isakson 2016년 8월 28일
편집: per isakson 2016년 8월 30일
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
per isakson
per isakson 2016년 8월 28일
편집: per isakson 2016년 8월 28일
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 2016년 8월 29일
I added an alternative to feval to the answer.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Construct and Work with Object Arrays에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by