在超类方法中修改子类的 immutable/protected 变量

Modifying an immutable/protected variable of a subclass in a superclass method

我正在尝试使用超类方法或外部实用函数修改子类的 immutable/protected 属性(我正在尝试在子类的构造函数中使用此函数,当然)。

示例(我想做的事情):

classdef Sup
  methods
    function self = setProperties(self, varargin)
      % This method sets the properties of the object
      % the input arguments come in the form 'propname1', val1, 'propname2', val2, ...
      ...
    end % setProperties
  end % methods
end % classdef Sup


classdef sub < Sup
  properties (SetAccess = immutable)
    prop1
    prop2
    prop3
  end % properties
  methods
    function self = sub(varargin)
      % constructor
      self = setProperties(self, varargin)
    end % sub
  end % methods
end % classdef sub


>> SomeObj = sub('prop1', 1, 'prop2', 10, 'prop3', 100);

此代码无效,我收到错误消息“您无法设置子的只读 属性 'prop1'。”

我同意将 sub 的属性设置为受保护,但我不希望它们 public。我也同意 setProperties 将是一个外部实用函数(未在超类中定义)的想法,但话又说回来,我无法在 sub.

的构造函数中使用 setProperties

感谢您对此的帮助。 谢谢,

阿维海伊

如果您愿意,可以将 subSetAccess 属性设置为 ?Sup - 换句话说,它们只能由 class 设置Sup.

这似乎可以满足您的直接要求 - 但是,我应该说这似乎是一种不寻常的实施模式。我想知道是否有更好的建议是检查为什么您发现需要这样做,并重新设计您的 class 关系。

编辑:

如果您需要的是在构造函数中方便地设置属性的通用方法,您可以尝试从内置 class hgsetget 继承您的 class。例如,

classdef sub < hgsetget
    properties (SetAccess = immutable)
    prop1
    prop2
    prop3
  end % properties
  methods
    function self = sub(varargin)
      set(self,varargin{:})
    end
  end
end

hgsetget 为您提供内置方法 set(和 get),可以与语法 set(obj, 'myprop', myval, 'myprop2', myval2) 和类似的语法(如 MATLAB Handle Graphics 对象,因此 hghgsetget).

这对你来说可能更方便。但是请注意,hgsetget 本身是 handle 的子 class,因此您必须接受 class 是 handle 对象。但是,如果您正在考虑 immutable 属性,那么您可能已经接受了。

编辑 2:

另一种适用于值对象的方法可能如下:

classdef sub
  properties (SetAccess = immutable)
    prop1
    prop2
    prop3
  end % properties
  methods
    function self = sub(varargin)
      % constructor
      props = varargin(1:2:end-1);
      vals = varargin(2:2:end);
      for i = 1:numel(props)
          self.(props{i}) = vals{i};
      end
    end
  end
end

或者,您可以在构造函数中使用 inputParser,为您提供更灵活的语法范围。