Question

Take the following class

classdef MyClass
    properties (Access = public)
        MyProperty;
    end

    methods
        function this = MyClass()
            % initialize the class
            this.MyProperty = [];
            this.LoadProperty(2,2);
        end

        function p = GetProperty(this)
            p = this.MyProperty;
        end

        function this = LoadProperty(this, m, n)
            % loads the property
            this.MyProperty = zeros(m, n);
        end
    end
end

And then you call:

obj = MyClass();
obj.GetProperty()

It will return [] -- which is the first value assigned to MyProperty in the constructor method.

The LoadProperty method is acting as a setter, but it does not set anything. How can I create a setter for MyProperty? I am coming from C# background and there it is very straightforward. -> SOLVED (see below)

I suspect that it is an issue with references and objects, as MATLAB always send the object itself as the first parameter to every method of a class, instead of sending only a reference as C# do.

Thank you in advance!


EDIT:

If I change the line this.LoadProperty(2,2); to this = this.LoadProperty(2,2);, it works.

Now, is there a way to create a void-return method in MATLAB, which only sets a class property, as it would be normally expected in C#, C++, Java, etc?

Was it helpful?

Solution 2

You can access it directly since you have declared it as public:

classObj = MyClass; 
classObj.MyProperty = 20;   
classObj.MyProperty % ans = 20

But it seems you want to encapsulate it. There are several ways you can do that. Suppose you have it with private access, as follows.

classdef MyClass
    properties (Access = private)
        MyProperty;
    end

    methods
        function this = MyClass()
            % initialize the class
            this.MyProperty = [];
            this.LoadProperty(2,2);
        end

        function p = GetProperty(this)
            p = this.MyProperty;
        end

        function this = LoadProperty(this, m, n)
            % loads the property
            this.MyProperty = zeros(m, n);
        end
    end 
end

Then you can add a set method to it, as follows (I commonly use lower case for functions and variables, and upper case to classes. You can change it to upper case if you want):

function this = setProperty(this,value)
   this.MyProperty = value;
end

Since this is not a handle class, you will need to use this function as follows:

myClass = myClass.setProperty(30); % You can also set it to [30 30 30; 20 20 20] if you want, there are no restrictions if you don't explicitly write into your function.

Otherwise you can use a handle class, by doing:

classdef MyClass < handle

in this case you can change it directly by doing:

myClass.setProperty(40);

But this would also mean that any reference you make to this class will not create a new object, but will be another handle from this object. That is, if you do:

myClass2 = myClass;
% and uses myClass2.setProperty:
myClass2.setProperty(40)
myClass.GetProperty % ans = 40!

So, if you want to avoid this kind of behavior (that is, you want a copy of your class when you pass it to a function or to another variable, a.k.a call by value) but want to specify how your get and set methods should behave, Matlab gives you two builtin methods that you can overload when you are assigning a property. That is:

function out = get.MyProperty(this)
function set.MyProperty(this,value)

By overwriting those methods you are overwriting what happens when the user calls

myClass.MyProperty          % calls out = get.MyPropertyGet(this)
myClass.MyProperty = value; % calls set.MyProperty(this,value)

But you can also work with handle classes and create a copy function your class:

function thisCopy = copy(this)
   nObj = numel(this);
   thisCopy(nObj) = MyClass;
   meta = metaclass(MyClass);
   nProp = numel(meta,'PropertyList');
   for k = 1:nObj
     thisCopy(k) = MyClass; % Force object constructor call
     for curPropIdx=1:nProp
       curProp = meta.PropertyList(curPropIdx);
       if curProp.Dependent
         continue;
      end
      propName = curProp.Name;
      thisCopy(k).(propName) = this(k).(propName);
    end
  end
end

This should be specified (just like your get. set. methods) inside your classdef as a public method. If you have this method declared and want your class2 to be a copy of class, then you do like this:

myClass = MyClass;
myClass.setProperty(30);
myClass2 = copy(myClass);
myClass2.setProperty(40); %
myClass.GetProperty % ans = 30

It is a bit more complicated that it should be for your MyClass because it copies every (non handle) property from your class objects, and work when you have a class object array. For more references see @Amro's answer and the matlab oop documentation.

This is also the explanation why this = this.LoadProperty works and this.LoadProperty(2,2) does not.

OTHER TIPS

Change the class definition (first line) as:

classdef MyClass < handle

This defines the class as having reference semantics by inheriting from the handle class. The documentation explains the difference:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top