0

我喜欢 matlabs App Designer 使用的 OO 编程风格(或者至少我使用它的方式)。现在我想知道是否可以在我的“普通”matlab 类中使用相同的样式。

我现在拥有的:

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 设计器中修改类(实例?)中的变量,同时还能够访问修改后的变量,而无需显式覆盖旧类实例。

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

所以我的问题是,我如何在“普通”matlab 中编程,就像在 App Designer 中一样?

编辑:应用程序设计器中的以下工作(我省略了 GUI 元素的方法/属性):

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
4

2 回答 2

3

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

你唯一需要做的就是:

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

现在,每次将此类的对象传递给函数时,您都不是通过值传递它,而是通过引用传递(正如您可能习惯于从 python 中传递的那样),并且修改它的属性也会在原始对象中修改它们。

于 2020-03-19T15:31:19.433 回答
2

您需要<从句柄类继承(在类的顶部)

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

有关“句柄”和“值”类之间的区别,请参阅文档:

值类构造函数返回一个对象,该对象与分配给它的变量相关联。如果您重新分配此变量,MATLAB® 会创建原始对象的独立副本。如果将此变量传递给函数以对其进行修改,则该函数必须将修改后的对象作为输出参数返回。有关值类行为的信息,请参阅避免不必要的数据副本。

句柄类构造函数返回一个句柄对象,该对象是对所创建对象的引用。您可以将句柄对象分配给多个变量或将其传递给函数,而不会导致 MATLAB 复制原始对象。修改作为输入参数传递的句柄对象的函数不需要返回该对象。

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

classdef AppBase < handle

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

于 2020-03-19T15:31:44.820 回答