以与 App Designer 相同的 OOP 风格编程

Program in same OOP style as App Designer

我喜欢 matlabs App Designer 使用的 OO 编程风格(或者至少是我使用它的方式)。现在我想知道我是否可以在我的 "normal" matlab class.

中使用相同的样式

我现在拥有的:

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

外部调用方式:

myClassInst = myClass;
myClassInst.Main()

我想去掉 classdef 中的所有 "obj = ",这在 App Designer 中是可能的。所以看起来像这样的东西:

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

App Designer 中的等效项似乎有效。因此,您似乎可以在 App 设计工具中修改 class(实例?)中的变量,同时还能够访问修改后的变量而无需显式覆盖旧的 class 实例。

我注意到 App Designer 将所有方法的属性都设置为 (Access = private),但我不确定这与它有什么关系。当然,如果我将所有内容都设置为私有,那么我就无法再从外部访问 Main() 方法了。

所以我的问题是,如何在 "normal" matlab 中编程,就像在 App Designer 中一样?

编辑: 以下在 App Designer 中有效(我省略了 GUI 元素的 methods/properties):

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

你绝对可以!您所要做的就是继承句柄 class,而不是 matlab 的默认值 class。您还可以像在其他语言中一样定义私有和 public 方法。

您唯一需要做的是:

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

现在每次将此 class 的对象传递给函数时,您不是按值传递它,而是按引用传递(您可能习惯于来自 python)并修改它的属性也会在原始对象中修改它们。

您需要从句柄 class

继承(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

请参阅 documentation 以了解“句柄”和“值”之间的区别 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.

此外,如果你edit matlab.apps.AppBase,你的应用程序设计器代码继承的class,你可以看到第一行是

classdef AppBase < handle

所以你实际上是在做同样的事情,没有 AppBase 中间人。