Changing property attributes in a value class

11 views (last 30 days)
Is there a way to change the attributes of a class without using dynamicprops? I would like to be able to hide and reveal properties based on how objects are being used. The properties would all be defined in the class definition, but I can't find a way to change the attributes after the object is created.
  2 Comments
Cedric
Cedric on 12 May 2013
Edited: Cedric on 12 May 2013
What do you mean by "hide and reveal", is it changing access type to/from private from/to public?
Why not using setters and getters whose behavior is specific to an object usage, instead of dealing with specific sets of properties?
Daniel Dolan
Daniel Dolan on 13 May 2013
Yes, I'm looking for a "hide and reveal" behavior for properties and also methods (forgot the mention this before). I'm trying to unify several related classes into a master class where certain features can be activated and deactivated based on a setting in a particular object.

Sign in to comment.

Accepted Answer

Cedric
Cedric on 13 May 2013
Edited: Cedric on 13 May 2013
I don't think that this "hide and reveal" approach is sound/wise. You can implement whatever logic in your methods so they work differently depending on the context, but what do you mean by "hiding methods/properties"? Could you not just avoid using them when not relevant? Very few end users really use class/object introspection mechanisms actually, and in my opinion it would be a mistake to try hiding anything to those who do. Actually, as a user, I much prefer having a clean object/class that triggers an error() when I am using one of its methods inappropriately, than a class that tricks introspection mechanisms.
I don't think that you can dynamically make private properties/methods public and vice versa. If you really want to manage hiding properties/methods, the only trick that I can think of is to overload METHODS, FIELDNAMES, and PROPERTIES. I don't think that it would be wise to overload METACLASS, because you would not be able to reproduce easily its output.
  2 Comments
Daniel Dolan
Daniel Dolan on 13 May 2013
That's more or less what I figured. I have a set of classes that are related, but some of my users are getting confused about their use. There is a master class (call it "ClassA") that gets used 75% of the time and two subclasses (call them "ClassB" and "ClassC") that are used the remaining 25% of the time. The subclasses have extra properties and methods that only apply to specific circumstances, so it would not make any sense to implement them in the master class.
I was trying to incorporate the three classes into one, allowing users to start with the default class (based on master) and then dynamically switch to a subclass (if it makes sense) later on. At present, users have to explicitly select a particular class at object creation. I thought there might a clever workaround, but it eludes me.
Cedric
Cedric on 13 May 2013
Edited: Cedric on 13 May 2013
You can always create a class A that, when instantiated, creates an object of class B or C depending the context and stores it as a property. Then you can either create getters and setters that will manage accesses to properties of B or C appropriately (not my favorite solution), or overload SUBSASGN, SUBSREF, SUBSINDEX, METHODS, PROPERTIES, FIELDNAMES, METACLASS, and a few others like NUMEL, LENGTH, SIZE, CLASS, END, DISP, etc. This could be a valid approach if implemented well, which would require work but wouldn't be out of reach.
The difference between this and what I qualified as not being sound/wise in my first comment is the following: if you have to overload METACLASS and generate its output from scratch, you can be almost certain that it is not going to work, because of the complexity of the output of METACLASS; if, however, you have instantiated some other class and saved it as a property, your overload just needs to output the built-in METACLASS applied to the property, e.g.
...
properties
subObj
end
...
methods
function self = A(type, varargin) % Constructor.
switch type
case ...
self.subObj = B(varargin{:}) ;
case ...
self.subObj = C(varargin{:}) ;
else
error('Huh?') ;
end
function varargout = metaclass(self, varargin) % Overload.
varargout = metaclass(self.subObj, varargin{:}) ;
end
function varargout = methods(self, varargin) ... end
function varargout = properties(self, varargin) ... end
function names = fieldnames(self, varargin) ... end
function self = subsasgn(self, S, value) ... end
function ind = subsindex(self) ... end
function varargout = subsref(self, S) ... end
function s = size(self, varargin) ... end
function n = numel(self, varargin) ... end
function l = length(self, varargin) ... end
function out = end(self, k, ~) ... end
function disp(self, varargin) ... end
function flag = iscolumn(self, varargin) ... end
function flag = isfloat(self, varargin) ... end
.. etc
end
I guess that the part that would require the more work would be SUBSASGN and SUBSREF (~ 1 day of work including full testing for me), that have to "transfer" indexing (including methods call) on self.subObj.
Building this would certainly be a nice training to OOP in MATLAB, but I would keep that as a side/experimental project for a while, and definitely build a lengthy and exhaustive test script.

Sign in to comment.

More Answers (0)

Categories

Find more on Class Introspection and Metadata in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!