Deruijter
Deruijter

Reputation: 2159

Program in same OOP style as App Designer

I like the OO programming style that matlabs App Designer uses (or at least the way I'm using it). Now I'm wondering if I can use the same style in my "normal" matlab class.

What I have now:

classdef myClass

    properties
        myVar;
    end

    methods
        function Main(obj)
            obj.myVar = "a";
            obj = DoSomething(obj);
            disp(obj.myVar) % outputs "c"
        end

        function obj = DoSomething(obj)
            if(obj.myVar == "a")
                obj.myVar="c";
            else
                obj.myVar = "b";
            end
        end
    end
end

Which can be called externally using:

myClassInst = myClass;
myClassInst.Main()

I would like to get rid of all the "obj = " in the classdef, as is possible in App Designer. So something that would look like this:

classdef myClass

    properties
        myVar;
    end

    methods
        function Main(obj)
            obj.myVar = "a";
            DoSomething(obj); % Just call the function without "obj = "
            disp(obj.myVar) % outputs "a" because I didn't overwrite obj
        end

        function DoSomething(obj)
            if(obj.myVar == "a")
                obj.myVar="c";
            else
                obj.myVar = "b";
            end
        end
    end
end

The equivalent of this seems to work in App Designer. So it appears you can modify variables in a class (instance?) in App Designer, while also being able to access the modified variable without explicitly overwriting your old class instance.

I noticed App Designer has all methods an properties set to (Access = private), though I'm not sure that has anything to do with it. Of course if I set everything to private, then I can't access the Main() method from outside anymore.

So my question is, how can I program in "normal" matlab, the same way as is possible in App Designer?

EDIT: The following works in App Designer (I left out the methods/properties for the GUI elements):

classdef tmp < matlab.apps.AppBase

    properties (Access = private)
        myVar; % Description
    end

    methods (Access = private)

        function doSomething(app)
            if app.myVar == "a"
                app.myVar = "c";
            else
                app.myVar = "b";
            end
        end
    end


    % Callbacks that handle component events
    methods (Access = private)

        % Code that executes after component creation
        function startupFcn(app)
            app.myVar = "a";
            doSomething(app);
            disp(app.myVar); % outputs "c"
        end
    end
end

Upvotes: 0

Views: 619

Answers (2)

Wolfie
Wolfie

Reputation: 30101

You need to inherit (< at the top of the class) from a handle class

classdef myClass < handle
    properties
        var
    end
    methods
        function obj = myClass( varargin )
            % Constructor function, called automatically when object is created
        end
        function someFunction( obj )
            obj.randomizeVar(); % Equivalent to randomizeVar( obj );
        end
        function randomizeVar( obj )
            obj.var = rand();
        end
    end
end

See the documentation for the difference between a "handle" and "value" class:

A value class constructor returns an object that is associated with the variable to which it is assigned. If you reassign this variable, MATLAB® creates an independent copy of the original object. If you pass this variable to a function to modify it, the function must return the modified object as an output argument. For information on value-class behavior, see Avoid Unnecessary Copies of Data.

A handle class constructor returns a handle object that is a reference to the object created. You can assign the handle object to multiple variables or pass it to functions without causing MATLAB to make a copy of the original object. A function that modifies a handle object passed as an input argument does not need to return the object.

Moreover, if you edit matlab.apps.AppBase, the class which you app designer code inherits, you can see that the first line is

classdef AppBase < handle

So you are literally doing the same thing, without the AppBase middle-man.

Upvotes: 2

Papooch
Papooch

Reputation: 1645

You definitely can! All you have to do is inherit from the handle class, as opposed to a value class which is the default for matlab. You can also define private and public methods as in other languages.

The only thing you have to do is:

classdef myclass < handle % this is how you inherit from base class
   properties
      public_property
   end

   properties (Access=private)
      private_property
   end

   methods
      function obj = myclass() % class constructor
         ...
      end
      function public_function()
         ...
      end
   end
   methods (Access=private)
      function private_function()
         ...
      end
   end
end

Now every time you pass an object of this class to a function, you are not passing it by value, you are passing by reference (as you might be used to from python) and modifying it's properties modifies them also in the original object.

Upvotes: 3

Related Questions