Class Property: Array of Objects

70 views (last 30 days)
Nycholas Maia
Nycholas Maia on 28 Apr 2017
Answered: Nycholas Maia on 29 Apr 2017
I would like to create a "Dependent Property" inside a "Main Class" that will handle a array of objects of "Sub Class".
Exemple:
classdef main_class
properties
number
end
properties (Dependent)
% prop will be a array of sub_class object
% the size of this array will depend/change on the "number" property
prop = sub_class();
end
end
If I set:
main = main_class();
main.number = 3;
I would like to get:
main.prop = [sub_class(1) sub_class(2) sub_class(3)]
To me is important that "prop" be a dependent property to automatic change the number of the elements in the array.
How could I do that? Thanks!
  1 Comment
Adam
Adam on 28 Apr 2017
Edited: Adam on 28 Apr 2017
I would strongly recommend reconsidering your wish to have this as a dependent property. I use dependent properties a lot and I like them, but in this case they have some serious difficulties.
Creating objects in a dependent property is highly unlikely to be what you want to do. This means that every time you access the dependent property it will create a new array of objects, you will never be able to access the same objects within the class (though you can, of course, if you store main.prop in a local variable and use it thereafter) because they will keep getting replaced every time you get the property 'prop'.
Even if this does happen to produce the behaviour you want it is not very transparent and I would always do something as fundamental as object creation in a function named e.g. createXXXX to be clear what it is doing, not as a side-effect of accessing a dependent property.
Also it is not clear - is sub_class actually a sub class of main_class? As in does it inherit from it, or do you just call it sub_class because it sits inside it? Objects containing objects of their own subclass feels like an odd design to me that would cause a lot of potential problems. Maybe I'm just not thinking of a usage though...

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 28 Apr 2017
Edited: Guillaume on 28 Apr 2017
I'm with Adam, I don't think you want a dependent property. dependent does not mean that the property value is recalculated when some other property change, it means that property value is created every time you ask for it. That value is not stored in the class.
In your case, you would be better off creating a setter method for your number property that automatically update the array size of the normal prop property:
classdef main_class
properties
number
prop
end
methods
function this = main_class(number) %constructor
if nargin == 0
this.number = 0;
else
this.number = number;
end
this = this.create_subarray;
end
function this = set.number(this, value) %set method for number. reset prop at the same time
this.number = value;
this = this.create_subarray;
end
function this = create_subarray(this)
this.prop = sub_class.empty;
for n = 1:this.number
this.prop(n) = sub_class(n);
end
end
end
end
As Adam and Andrew have commented, hopefully sub_class is not actually a subclass of main class.
  6 Comments
Guillaume
Guillaume on 28 Apr 2017
Yes, as Adam pointed out there were a few typos in my example (now corrected). In addition, I'd forgotten that arrayfun cannot create arrays of object, so I've changed the implementation to an explicit loop.
prop can be anything you want, array of class objects (whose class you define in a separate m file, a structure array (in which case you don't need another file), or something else.
Note that I've ignored methods and properties attributes in my example. I assumed that prop would be read-only. If prop is read/write as your
Main.prop(5).color = 'blue';
would require (assumin that sub_class is a value class), then the user can also change the size of the prop array independently of the number property, breaking your class. If you want to avoid that, you'd also need a property setter for prop, e.g:
function this = set.prop(this, value);
assert(isequal(size(value), size(this.prop)), 'Resizing prop is not allowed');
this.prop = value;
end

Sign in to comment.

More Answers (2)

Andrew Newell
Andrew Newell on 28 Apr 2017
You need to define a get method (see Access Methods for Dependent Properties). For example, the method block could look like this:
methods
function value = get.prop(obj)
value(obj.number) = sub_class(obj.number);
for ii=1:obj.number-1
value(ii) = sub_class(ii);
end
end
end
Note that, since sub_class would share this method, the dependent variable is endlessly recursive; if you ran
main = main_class();
main.number = 1;
then main.prop = main.prop.prop = ...
  2 Comments
Andrew Newell
Andrew Newell on 28 Apr 2017
If sub_class is actually a subclass of main_class, it inherits the properties and methods of main_class. That would include the property number and the method get.prop. So if you type
main.prop.prop
get.prop will create a sub_class object and return it as main.prop. Then, in main.prop, get.prop will create yet another sub_class object and return it as main.prop.prop. I agree with Adam and Guillaume - this is not the way to go!

Sign in to comment.


Nycholas Maia
Nycholas Maia on 29 Apr 2017
Thank you all....now I got everything working great! Thank you so much!

Community Treasure Hunt

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

Start Hunting!