Here is my suggestion: create a method in the superclass called add_dyn_prop . This method should be called in subclasses instead of the usual dependent property .
The idea is that the superclass inherits from dynamicprops and uses addprop to add a new property and set its access methods manually based on its name.
classdef klass < dynamicprops methods (Access = protected) function add_dyn_prop(obj, prop, init_val, isReadOnly) % input arguments narginchk(2,4); if nargin < 3, init_val = []; end if nargin < 4, isReadOnly = true; end % create dynamic property p = addprop(obj, prop); % set initial value if present obj.(prop) = init_val; % define property accessor methods % NOTE: this has to be a simple function_handle (@fun), not % an anonymous function (@()..) to avoid infinite recursion p.GetMethod = @get_method; p.SetMethod = @set_method; % nested getter/setter functions with closure function set_method(obj, val) if isReadOnly ME = MException('MATLAB:class:SetProhibited', sprintf(... 'You cannot set the read-only property ''%s'' of %s', ... prop, class(obj))); throwAsCaller(ME); end obj.(prop) = val; end function val = get_method(obj) val = obj.(prop); end end end end
now in the subclass, instead of defining the dependent property in the usual way, we use this new inherited function in the constructor to define the dynamic property:
classdef subklass < klass %properties (Dependent, SetAccess = private) % name %end %methods % function val = get.name(obj) % val = 'Amro'; % end %end methods function obj = subklass() % call superclass constructor obj = obj@klass (); % define new properties add_dyn_prop(obj, 'name', 'Amro'); add_dyn_prop(obj, 'age', [], false) end end end
Output:
>> o = subklass o = subklass with properties: age: [] name: 'Amro' >> o.age = 10 o = subklass with properties: age: 10 name: 'Amro' >> o.name = 'xxx' You cannot set the read-only property 'name' of subklass.
Of course, now you can configure the getter method based on the name of the property that you originally planned.
EDIT:
Based on the comments, you may find a slight change to the same method as discussed above.
The idea is to require the subclass to create a property (defined as abstract in the superclass) containing the names of the required dynamic properties to be created. The superclass constructor will then create the specified dynamic properties by setting their access methods to universal functions (which could customize their behavior based on the name of the property as you wish). I am reusing the same add_dyn_prop function that I mentioned earlier.
In the subclass, we just need to implement the inherited abstract property dynamic_props , initialized with a list of names (or {} if you don't want to create a dynamic property). For example, we write:
classdef subklass < klass properties (Access = protected) dynamic_props = {'name', 'age'} end methods function obj = subklass() obj = obj@klass (); end end end
The superclass is similar to what it was before, only now its obligation to call add_dyn_prop in its constructor for each of the property names:
classdef klass < dynamicprops % ConstructOnLoad properties (Abstract, Access = protected) dynamic_props end methods function obj = klass() assert(iscellstr(obj.dynamic_props), ... '"dynamic_props" must be a cell array of strings.'); for i=1:numel(obj.dynamic_props) obj.add_dyn_prop(obj.dynamic_props{i}, [], false); end end end methods (Access = private) function add_dyn_prop(obj, prop, init_val, isReadOnly) % input arguments narginchk(2,4); if nargin < 3, init_val = []; end if nargin < 4, isReadOnly = true; end % create dynamic property p = addprop(obj, prop); %p.Transient = true; % set initial value if present obj.(prop) = init_val; % define property accessor methods p.GetMethod = @get_method; p.SetMethod = @set_method; % nested getter/setter functions with closure function set_method(obj,val) if isReadOnly ME = MException('MATLAB:class:SetProhibited', sprintf(... 'You cannot set the read-only property ''%s'' of %s', ... prop, class(obj))); throwAsCaller(ME); end obj.(prop) = val; end function val = get_method(obj) val = obj.(prop); end end end end
Note. I have not used the ConstructOnLoad class attribute or Transient , since I'm still not sure how they will affect the loading of an object from a saved MAT file regarding dynamic properties.
>> o = subklass o = subklass with properties: age: [] name: [] >> o.name = 'Amro'; o.age = 99 o = subklass with properties: age: 99 name: 'Amro'