MATLAB CLASSES getter and setters

2019-02-18 08:31发布

问题:

I come from a Java background. I am having issues with classes in Matlab particularly getters and setters. getting a message saying conflict between handle and value class I'm a little lost with what to do so any help for lack of a better word will be helpful.

classdef Person
properties(Access = private)
    name;
    age; 
end


methods
    % class constructor
    function obj = Person(age,name)         
             obj.age = age;
             obj.name = name;
    end

    %getters
    function name = get.name(obj)          
    end

    function age = get.age(obj)
    end

    %setters
    function value = set.name(obj,name)
    end

    function value = set.age(obj,age)
    end

end

end

回答1:

Implementation

Since your class is currently a subclass of the default Value class, your setters need to return the modified object:

function obj = set.name(obj,name)
end
function obj = set.age(obj,age)
end

From the documention: "If you pass [a value class] to a function, the function must return the modified object." And in particular: "In value classes, methods ... that modify the object must return a modified object to copy over the existing object variable".


Handle classes (classdef Person < handle) do not need to return the modified object (like returning void):

function [] = set.name(obj,name)
end
function [] = set.age(obj,age)
end

Value vs. Handle

Going a bit deeper, the difference between a Value class and a Handle class lies mostly in assignment:

  • Assigning a Value class instance to a variable creates a copy of that class.
  • Assigning a Handle class instance to a variable create a reference (alias) to that instance.

The Mathworks has a good rundown on this topic. To paraphrase their illustration, the behavior of a Value class is

% p  is an instance of Polynomial
p = Polynomial(); 
% p2 is also an instance of Polynomial with p's state at assignment
p2 = p;

and of a Handle class is

% db is an instance of Database
db = Database();
% db2 is a reference to the db instance
db2 = db;


回答2:

Quick'n Dirty from the Java perspective: - "handle" classes are what your mind is set to. proper object instances with pointers to them. use them. - "value" classes are always returning a full clone of whatever object (which has been modified by what you just did, e.g. setting a name).

the reason they have both in Matlab is that in Matlab you would expect the "value" behaviour natively. Imagine you have a matrix A = [1 2; 3 4], then assign that via B = A. if you now set B(1) = -1 you'd hope that A(1) is still 1, right? this is because matlab keeps track of "copies" and truly creates them as you modify different variables initially set to the same matrix. in OOP you'd have A(1)=-1 now as everythings an object reference.

furthermore, "native" matlab routines dont have a "this/self/me" variable that contains the instance reference to access from within functions. instead, the convention is that the class instance will be prepended to the function's argument list. so for a function call myclass.mymethod(arg1,arg1), the declaration must be

function mymethod(this, arg1, arg2)
  % Note that the name you choose for "this" is arbitrary!
end

mind you, this is the java-perspective (and also my favourite one), the above function call is equivalent to mymethod(myclass,arg1,arg1). this is more native to matlab-style, but somehow makes it harder to see you're calling an objects method.

now, regarding setters/getters: for handle classes, everything feels java-ish now:

classdef MyClass < handle

properties
   MyProp;
end

methods
   function set.MyProp(this, value)  %Note: setMyProp is also valid!
       ... % do checks etc, trigger calls, 
       this.MyProp = value; 
   end

   function value = get.MyProp(this)
       ... % notify, update, triggers etc
       value = this.MyProp; 
   end 
end

Of course it goes without saying that you dont need to define a getter if you just want to return the value, i.e. myclassinstance.MyProp will work without any just as well.

Finally, getters/setters for value classes are something that [never encountered me/i never needed] in my 7 years of matlab oop, so my advise would be to go with handle classes and enjoy happy matlab coding :-) otherwise, the above explanation & official matlab docs is doing the job for value class getter/setters.