I've just start OOP and am writing number of class constructors. Constructor input arguments often coorespond directly to class properties for which I want to override the default values. Depending on if/which defaults I want overridden, I may provide some, all, or none of these constructor input arguments. Some may be empty in order to access later arguments.
Trying to implement this has seemed either unnecessarily laborious or opaque.
What I'd like to do is something like:
classdef MyClass properties (SetAccess = private) prop1 = 1; prop2 = 2; end methods %Constructor
function obj = MyClass(obj.prop1, obj.prop2) ... end endend
This or something similar would allow immediately setting any varargins to the correct properties. It'd do this if an argument is provided (preferbly provided and not empty/missing) and would keep the default if not. This syntax also clearly lists the correct order of arguments for in-context help.
For example, a call like obj = MyClass(3,4) would set obj.prop1 = 3, obj.prop2 = 4.
Instead, it seems this needs to be belabored with something like (but often for more properties):
methods %Constructor
function obj = MyClass(prop1, prop2) if nargin > 0 obj.prop1 = prop1; end if nargin > 1 obj.prop2 = prop2; end ... end end
This seems to violate all kinds of Clean Code / Don't Repeat Yourself rules in addition to being frustrating. It's not even really a switch case, and as I understand it, all this needs to be written directly in-line in the classdef block. (Because the Constructor has to be defined inline and I can't pass the inputs to another function until I know they exist.)
I did write a general constructor_override function that solves this if I use a varargin reciever and provide a redundant list of property names. Unfortunately this seems like it's again is asking for clean code troubles. (Also, I'm still trying to figure out inheritence to allow it on SetAccess ~= public properties). In addition to the perils of a separate property names list, this results in the in-context help for the class call just saying "varargin", which is similarly problematic.
methods %Constructor function obj = MyClass(varargin) ... obj = constructor_override(obj, argin_names, varargin{:}) ... end end
I can't imagine this is a rare problem, unless I'm fundamentally poorly designing my classes (which is possible). Either way though, there must be a better way? Thank you
Best Answer