如何以八度为单位访问/读取类实例属性?

时间:2014-08-09 10:49:31

标签: class oop properties octave getter-setter

example我附加了类实例的参数中创建类似于那个类的类

function t = train (m, F_z, F_b, varargin)
  ...
  t.m =     m;      % total mass of train [kg]
  t.F_z =  F_z;     % ...
  ...
  t = class (t, "train");

获取字段名称

>> t1 = train(100, 150000, 200000);
...
>> fieldnames(t1)
ans =
{
  [1,1] = m
  [2,1] = F_z
  ...

但是如何访问这些?显然它不是

>> t1.m
error: invalid index for class
>> getfield(t1, 'm')
error: invalid index for class
error: called from
...

如果我在t = class (t, 'train'); function t = train (m... @train/train.m末尾省略struct行,这些事情似乎都很正常......但是后来它是class而不是一个{{1}}

2 个答案:

答案 0 :(得分:2)

您可以通过两种方式完成此操作。您可以定义一个方法来检索它(简单),或者设置subsref(下标引用)(硬)。

要定义方法,只需使用以下内容创建@train/m.m

function r = m ()
  r = t.m;
endfunction

要设置下标,请使用以下内容创建@train/subsref.m

function r = subsref (val, idx)
  if (strcmp (idx.type, ".") && strcmp (idx.subs, "m"))
    r = val.m;
  endif
endfunction

这样您就可以只访问 字段m。要访问您班级中的任何属性,您只需执行以下操作:

function r = subsref (val, idx)
  r = subsref (struct (val), idx);
endfunction

要允许访问属性的子集,您可以:

function r = subsref (val, idx)
  if (strcmp (idx.type, ".") && any (strcmp (idx.subs, {"m", "f2", "F_z"})))
    r = val.(idx.subs{1});
  endif
endfunction

但是subsref控制所有索引,而不仅仅是在作为结构访问它时。你可以允许人们为对象编制索引(也许你有一个旅行车类,索引火车返回它们)。该函数在开始时看起来有点奇怪(就像subsasgn(下标赋值))但可能非常有用。你可以这样做:

function r = subsref (val, idx)
  if (strcmp (idx.type, ".") && strcmp (idx.subs, "m"))
    r = val.m;
  elseif (strcmp (idx.type, "()"))
    r = val.wagons(idx.subs{:});
  endif
endfunction

答案 1 :(得分:2)

一种快速而又肮脏的方式是在八度音阶中打破OOP哲学。无需定义subsrefgetter方法。要访问这些字段,只需将对象转换为struct作为

>> t1 = train(100, 150000, 200000);
>> t1_easy = struct(t1);
>> t1_easy.m
>> t1_easy.F_z