MATLAB: Best Way to Set Private Properties in Class Constructor

classconstructordefault valuefunction callMATLABoopprivatepropertiesvarargin

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
end
end
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

There's nothing wrong with the first version of the code you posted (the one with the nargin tests). Also, there is no reason you can't invoke other functions in the constructor. However, you might like to try inputParser