Octave:创建一个 class 变量然后在 class 中访问它(在构造函数中)

Octave: create a class variable then access it within class (in constructor)

也许这是一个微不足道的问题,但我想知道如何访问 class 构造函数中的常量 属性 或八度音程中的 class 函数。举个例子:

classdef Example % < FatherClass
    
    % read-only protected properties
    properties (Constant=true, Access=protected)
        all_levels = {"A","B","C","D"};
    endproperties
    
    % protected properties
    properties(Access=protected)
        level = 'D';
        output = '.';
    endproperties

    methods(Access=public)
        function obj = Example (level,outputfilepath)

            if any(strcmp(all_levels,level))
                obj.level = level;
            else
                error ("possible levels are: A B C D");
            endif

            obj.output = outputfilepath

        endfunction

    endmethods
end

运行 这个 class 例子我收到错误:

error: 'all_levels' undefined near line 12, column 12
error: called from
    Example at line 12 column 13

所以,我试过类似的方法

if any(strcmp(obj.all_levels,level))
     obj.level = level;

同样的结果,同样定义了一个getter:

methods (Static = true)
  function lvs = gel_levels()
     lvs = all_levels
  endfunction
endmethods

...

methods(Access=public)
  function obj = Example (obj,level,outputfilepath)
    all_levels = get_levels()
    % disp(all_levels)
    if any(strcmp(all_levels,level))
       obj.level = level;
    else
       error ("possible levels are: A B C D");
    endif
       obj.output = outputfilepath
  endfunction
endmethods

抱歉,我对 Octave 还很陌生,我还没有找到任何相关的例子。我想要完成的是一个简单的 class 变量

这个问题有点令人困惑,因为不同的尝试似乎使用了不同的部分,但总的来说我认为你的问题是你没有将对象作为方法中的形式参数传递。

也不清楚您是在尝试修改对象“in-place”,还是在尝试生成一个新对象...但无论如何请记住,就地修改对象是不可能的(除非从 'handle' 对象继承)。因此,您应该做的典型事情是:将对象作为第一个输入传入,就像您应该对 class 方法定义所做的那样,修改它,return 它,然后当您在您的调用工作区中使用此方法,通过赋值捕获此对象(通常在与调用工作区中的被调用对象同名的变量中)。

这对我有用:

%% in Example.m
classdef Example

    % read-only protected properties
    properties( Constant=true, Access=protected )
        all_levels = {"A", "B", "C", "D"};
    endproperties

    % protected properties
    properties( Access = protected )
        level  = 'D';
        output = '.';
    endproperties

    methods( Access = public )
        function obj = Logging( obj, level, outputfilepath )
            valid_level_choice = any( strcmp( obj.all_levels, level ) );

            if valid_level_choice,   obj.level = level;
            else,                    error( "possible levels are: A B C D" );
            endif

            obj.output = outputfilepath;
        endfunction

        function get_level( obj )
            fprintf( "The level is %s\n;", obj.level );
        endfunction

    endmethods
endclassdef

%% In your console session
E = Example();
E.get_level()
%> The level is D
E = E.Logging( 'A', './' );
E.get_level()
%> The level is A

更新

根据修改后的问题/评论更新了代码。 这适用于八度 7.1.0

%% in Example.m
classdef Example % < FatherClass

    % read-only protected properties
    properties (Constant=true, Access=protected)
        all_levels = {"A","B","C","D"};
    endproperties

    % protected properties
    properties(Access=protected)
        level = 'D';
        output = '.';
    endproperties

    methods(Access=public)
        % Constructor
        function obj = Example (level,outputfilepath)
            valid_choice = any(strcmp(obj.all_levels,level));
            if valid_choice, obj.level = level;
            else, error ("possible levels are: A B C D");
            endif
            obj.output = outputfilepath;
        endfunction
        % Remaining Methods
        function get_level( obj ), fprintf( "The level is %s\n", obj.level ); endfunction
        function change_all_levels( obj, C ), obj.all_levels = C; endfunction
    endmethods
end
%% octave session
octave:1> E = Example('A', '.');
octave:2> E.get_level()
%> The level is A
octave:3> E.change_all_levels( {'this', 'should', 'not', 'work' } );
%> error: subsasgn: cannot assign constant property: all_levels
%> error: called from
%>    change_all_levels at line 25 column 66