MATLAB Answers


What is best way to define 2 way dependence between class properties

Say I am defining a class called Point which describes a point in 3D space. The class has a coordinate property which is a 3 entry vector ([x, y, z]) and also a separate property for each component of the coordinate (Point.X, Point.Y, and Point.Z).
A point object is always instantiated using a coordinate vector but, once instantiated, I would like the user to be able to update the value of either the coordinate vector OR the individual component values and have the two stay consistent with each other, in other words:
If the user changes the coordinate vector:
Point.coord = [newX, newY, newZ]
The X, Y and Z properties should be updated to newX, newY and newZ respectively
OR, if the user updates one of the X, Y or Z properties:
Point.X = newerX;
Point.Y = newerY;
Point.Z = newerZ;
The coord property should be updated to [newerX, newerY, newerZ]
What is the preffered way to implement this? Is it even possible at all?
My first thought was to just update the coordinate vector in the set.X, set.Y and set.Z methods and vice versa but I'm guessing this will cause some sort of infinite loop and Matlab complains saying you shouldn't set the values of properties inside the set method of another property. I know that one way dependence is easy to define using dependent properties but for this 2 way dependence I am stumped.

  댓글 수: 0

로그인 to comment.

답변 수: 2

Steven Lord 님의 답변 4 Oct 2019
 채택된 답변

You have essentially two "views" into one underlying "truth". While you can ignore the warning, I would make both the "view" properties Dependent upon one private "truth" property.
classdef Temperature
offsetC = -273.5;
function obj = Temperature(temp, unit)
switch lower(unit(1))
case 'c'
obj.Celcius = temp;
case 'f'
obj.Fahrenheit = temp;
error('Expected a temperature in C or F')
function y = get.Celcius(obj)
y = obj.Kelvin + obj.offsetC;
function obj = set.Celcius(obj, newvalue)
obj.Kelvin = newvalue - obj.offsetC;
function y = get.Fahrenheit(obj)
y = c2f(obj.Celcius);
function obj = set.Fahrenheit(obj, newvalue)
obj.Celcius = f2c(newvalue);
function seeValueOfKelvin(obj)
fprintf('The temperature in Kelvin is %f.\n', obj.Kelvin);
function c = f2c(f)
c = (f-32)*(5/9);
function f = c2f(c)
f = (9/5)*c+32;
Here's how you can use this:
>> obj = Temperature(0, 'C')
obj =
Temperature with properties:
Celcius: 0
Fahrenheit: 32
>> obj.Fahrenheit = 212
obj =
Temperature with properties:
Celcius: 100
Fahrenheit: 212
>> seeValueOfKelvin(obj)
The temperature in Kelvin is 373.500000.
The "truth" is the temperature in Kelvin. Both the temperature in Celcius and in Fahrenheit are derived from Kelvin.

  댓글 수: 1

Thanks Steven, this seems like the right way to do it!

로그인 to comment.

Gaurav Garg 님의 답변 4 Oct 2019

Assuming you are using MATLAB R2019a, you can set a property in other property’s set method, though it shows a warning. So, you can set the properties of Point X, Y and Z in the set method of coord.
Also, if you go through the documentation of the Set methods, it mentions that MATLAB does not call a property set method if value is assigned to a property from within its own property set method, to prevent recursive calling of the set method.
For better understanding, we look on the code below. Run the code as a script and type o=PropertySetMethod("method") in the command window.
In line 11, we display str, and the output for str is method” (the string which was passed in while creating object for the class).
In line 12, we set Prop1 property of obj. The point to be noted here is that set method gets called here (defined in line 18) and the string “Inside constructor” is passed as argument str. In line 20, Prop2 property of PropertySetMethod is set as str. This returns just a warning and not an error.
classdef PropertySetMethod
Prop1 = "Default String"
Prop2 = "My string"
function obj = PropertySetMethod(str)
if nargin > 0
fprintf("Before setting prop1, str = %s\n",str);
obj.Prop1 = "Inside constructor";
fprintf("After setting prop1, str = %s\n",str);
function obj = set.Prop1(obj,str)
obj.Prop1 = str;
obj.Prop2 =str;
fprintf('set.Prop1 method called. Prop1 = %s and this is str = %s\n', obj.Prop1,str);

  댓글 수: 0

로그인 to comment.

Translated by