Bidirectional property and method definition with classes

1 view (last 30 days)
Roys
Roys on 18 Feb 2022
Edited: Roys on 21 Feb 2022
Hi all,
Here is a little conundrum with MATLAB classes (at least for me). I am looking for an elegant way, naturally, to implement this. I have a data structure that repeats several times, and includes properties such as "origin", "shift", "span", for each of the axes x,y,z. For brevity, I give an example here with just three properties:
classdef boxClass
properties
x, y, z
end
end
I now create a class as follows:
classdef supClass
properties
updatevalues = true;
seed = 1
box1 boxClass
box2 boxClass
% ...
end
The functionality I would like to have is:
  1. The properties in box1 will be set according to set functions specific for each property in box1, dependent on the current property values in box1 and the value of seed in the current instance of supClass.
  2. The properties in box2 will be set according to different set functions, and also dependent on seed as in the previous case.
  3. Changing seed immediately affects the appropriate values in box1 and box2.
  4. If updatevalues is false, update properties normally (no links with other properties) <-- this means I cannot use the Dependent attribute for properties; the reason is I would like a functionality where I change the values manually and it doesn't affect anything else.
I can implement this without using boxClass in a non-elegant way, though this would become even less elegant considering more and more properties:
classdef supClass
properties
updatevalues = true;
seed = 1
box1x, box1y, box1z
box2x, box2y, box2z
% ...
end
methods
function obj = set.seed(obj,val)
obj.seed = val;
if ~obj.updatevalues, return; end
obj.box1x = val*1;
obj.box1y = val*2;
end
function obj = set.box1x(obj,val)
obj.box1x = val;
if ~obj.updatevalues, return; end
obj.box1z = obj.box1x*obj.seed; % depends on obj.seed ("outside" what would be boxClass)
end
function obj = set.box2x(obj,val)
obj.box2x = val;
if ~obj.updatevalues, return; end
obj.box2z = obj.box2x*100; % different than the implemetation of set.box1x
end
end
end
I understand I cannot change the set/get methods of an instance of a class, which is why I didn't bother implementing any in boxClass. My guess is that I have to make new classes for each box1, box2, etc. that inherit the properties from boxClass and implement specific set methods. However, I'm not sure how to pass the supClass instance into the set method of box1, to be able to read its properties (in the above case - updatevalues and seed). In effect I would want to know the parent object of the parent of the set method, something like:
<pseudo-code>
classdef supClass
properties
updatevalues = true;
seed = 1
box1 box1Class
box2 box2Class
% ...
end
methods
function obj = set.seed(obj,val)
obj.seed = val;
if ~obj.updatevalues, return; end
obj.box1.x = val*1;
obj.box1.y = val*2;
end
end
classdef boxClass
properties
x, y, z
end
end
classdef box1Class < boxClass
methods
function obj = set.x(obj,parent,val)
obj.x = val;
if ~parent.updatevalues, return; end
obj.z = obj.x*parent.seed; % depends on seed ("outside" what would be box1Class)
end
end
end
Is it possible to do something like this easily?
Thanks!

Accepted Answer

Roys
Roys on 21 Feb 2022
What I resorted to so far is this:
  1. supClass < handle creates two box1Class instances. Note that I initialize them in the constructor function and not the properties - this is because doing so will mean that additional instances of supClass will share the same instance of boxClass (see this answer).
  2. boxClass is a "generic" box that defines protected set methods, which can be overwritten in particular implementation of these set functions.
  3. box1Class and box2Class are these specific implementations. Notice that I link them to the supClass instance using a "parent" property, set when supClass is constructed.
  4. Then I can control the property values of each box1 and box2 using values from the parent or other properties in the tree.
I'm still wondering if there's a better way to do this? Consolidating all functionalities of box#Class implementations would be nice.
One thing I'm also not sure about is why this works correctly only when I use the < handle super-class. I understand it adds some functionality as a super-class that enables this, probably something with the set/get functions.
Here is a working example code - perhaps it would be useful to others:
classdef supClass < handle
properties
updateproperties = true
seed = pi
box1, box2
end
methods
function obj = supClass()
obj.box1 = box1Class(obj);
obj.box2 = box2Class(obj);
end
end
end
classdef boxClass
properties
x,y,z
end
methods
function obj = set.x(obj,value), obj.x = setx(obj,value); end
function obj = set.y(obj,value), obj.y = sety(obj,value); end
function obj = set.z(obj,value), obj.z = setz(obj,value); end
end
methods (Access = protected)
function value = setx(obj,value), end
function value = sety(obj,value), end
function value = setz(obj,value), end
end
end
classdef box1Class < boxClass
properties, parent, end
methods function obj = box1Class(parent), obj.parent = parent; end end
methods (Access = protected)
function value = setx(obj,value), if ~obj.parent.updateproperties, return; end
value = value * obj.parent.seed;
end
function value = sety(obj,value), if ~obj.parent.updateproperties, return; end
obj.parent.box2.y = value;
end
end
end
classdef box2Class < boxClass
properties, parent, end
methods function obj = box2Class(parent), obj.parent = parent; end end
end

More Answers (1)

Catalytic
Catalytic on 19 Feb 2022
  • If updatevalues is false, update properties normally (no links with other properties) <-- this means I cannot use the Dependent attribute for properties;
I don't see why not. just make the behavior of the set and get methods of the Dependent properties refer to the current value of updatevalues. When it is false, just draw and deposit property values to a Hidden properties, box1_, ox2_ etc..
  1 Comment
Roys
Roys on 21 Feb 2022
Thanks, that's a possibility - but it requires more lines of code (implementing a set function and a get function, as well as additional hidden variable), plus the if clause, instead of just one set function with an if clause. Seems a bit more elegant in my mind, at least.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!

Translated by