Object properties that automatically update but aren't Depenent

11 visualizzazioni (ultimi 30 giorni)
I'm new to using object oriented programming, so I'm honestly just experimenting here, and maybe there's a better way to do this. For context I'm trying to create an object for an ideal gas.
classdef idealGas
properties
P
V
n
R = 8.314; %J/mol/K
T
end
end
Ideal gasses are defined by P*V = n*R*T, so I would like to be able to set any 3 (R is constant) and have the fourth calculated automatically. If only one of them were dependent, I could do
classdef idealGas
properties
P
V
n
R = 8.314;
end
properties (Dependent)
T
end
methods
function T = get.T(obj)
T = obj.P*obj.V/obj.n/obj.R;
end
end
end
gas1 = idealGas;
gas1.P = 100;
gas1.V = 2;
gas1.n = 5;
T = gas1.T;
I have two problems with this. First is that it only lets T be dependent; I would like to be able to specify any three and have it calculate the fourth. Second is that is would have to recalculate T every time I call it. This might not be a problem for this example since its a very simple operation, but for different objects it might not be. I would like it to be able to store T without recalculating every time I call it.
I tried having assigning other properties in a set method for P like follows, but it didn't like me accessing other properties in the set method for P.
function obj = set.P(obj,pressure)
if ~isempty(obj.P)
error('Pressure is already set, please change pressure via specific process')
end
obj.P = pressure;
obj.V = obj.n*obj.Rbar*obj.T/pressure;
obj.n = pressure*obj.V/obj.Rbar/obj.T;
obj.T = pressure*obj.V/obj.n/obj.Rbar;
end
Also even if that worked, I'd still have to do it for every property, which feels clunky.
Any ideas would be appreciated
  1 Commento
Les Beckham
Les Beckham il 20 Gen 2021
Modificato: Les Beckham il 20 Gen 2021
This is a fascinating question. I too am not very comfortable with using OOP in Matlab. But I'm trying to learn.
I experimented a bit with this and did not come up with any good solution. I suspect that you could create different objects where one and only one property was dependent on the others (idealGasPVT, idealGasnPT, idealGasnVT, etc.) but that really seems like an unsatisfying approach. I feel that this should be possible. I'm hoping that someone smarter than me will provide a real answer.
Here is my (not working) code that I used to experiment with this.
This code generates the same CodeAnalyzer errors/warnings you refer to, which refers to loading and saving of objects, not creating or updating them (which is less than helpful in this case).
% idealGas.m
% https://www.mathworks.com/matlabcentral/answers/721574-object-properties-that-automatically-update-but-aren-t-depenent?s_tid=srchtitle
classdef idealGas
properties
P % N/m^2
V % m^2
n % moles
T % Kelvin
end % end properties
properties(Constant)
R = 8.314; % J/mol/K
end % end Constant properties
methods
% Constructors
function ig = idealGas(P, V, n, T)
if (isempty(P))
ig.V = V;
ig.T = T;
ig.n = n;
ig.P = get(P);
elseif (isempty(V))
ig.P = P;
ig.n = n;
ig.T = T;
ig.V = get(V);
elseif (isempty(n))
ig.P = P;
ig.V = V;
ig.T = T;
ig.n = get(n);
elseif (isempty(T))
ig.P = P;
ig.V = V;
ig.n = n;
ig.n = get(T);
end
end
% Get methods
function P = get.P(obj)
P = obj.n * obj.R * obj.T / obj.V;
end
function V = get.V(obj)
V = obj.n * obj.R * obj.T / obj.P;
end
function T = get.T(obj)
T = obj.P * obj.V / obj.n / obj.R;
end
function n = get.n(obj)
n = obj.P * obj.V / obj.R / obj.T;
end
% Set methods
function obj = set.P(obj, pressure)
obj.P = pressure;
obj.V = obj.n * obj.R * obj.T / obj.P;
obj.n = obj.P * obj.V / obj.R / obj.T;
obj.T = obj.P * obj.V / obj.n / obj.R;
end % end set.P
function obj = set.V(obj, volume)
obj.V = volume;
obj.P = obj.n * obj.R * obj.T / obj.V;
obj.n = obj.P * obj.V / obj.R / obj.T;
obj.T = obj.P * obj.V / obj.n / obj.R;
end % end set.V
function obj = set.T(obj, temp)
obj.T = temp;
obj.V = obj.n * obj.R * obj.T / obj.P;
obj.n = obj.P * obj.V / obj.R / obj.T;
obj.T = obj.P * obj.V / obj.n / obj.R;
end % end set.V
end % end methods
end % end classdef

Accedi per commentare.

Risposta accettata

Steven Lord
Steven Lord il 20 Gen 2021
function obj = set.P(obj,pressure)
if ~isempty(obj.P)
error('Pressure is already set, please change pressure via specific process')
end
obj.P = pressure;
obj.V = obj.n*obj.Rbar*obj.T/pressure;
obj.n = pressure*obj.V/obj.Rbar/obj.T;
obj.T = pressure*obj.V/obj.n/obj.Rbar;
end
So obj.P will have the new pressure value. obj.V will be calculated using the old n, Rbar, and T and the new P. Then obj.n will be calculated using the new pressure and V and the old Rbar and T. Do you then need to go back and recalculate obj.V using the new pressure and n and the old Rbar and T?
Giving a new value for any of the parameters will have a ripple effect on the others. I probably wouldn't try to use property set methods but I might use property get methods. If you're concerned about recomputing one of the parameters using a lengthy calculation consider using a memoize object.
  1 Commento
Laird Mendelson
Laird Mendelson il 20 Gen 2021
Yep! Yeah, I realized that was the problem with my method. Memoized objects seem perfect for what I'm trying to do. Thanks for the help!

Accedi per commentare.

Più risposte (0)

Community Treasure Hunt

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

Start Hunting!

Translated by