(2018a) Implicit Call to Inherited Constructor is not available when used in a package

1 view (last 30 days)
Hi All,
The goal is to try the new feature of Matlab 2018 using a package. In each of the examples there is a super class and a subclass. The subclass has no constructor but the superclass expects a input argument. In the case without a package this works fine as advertised in the release notes. In the case with package there is an error.
  5 Comments
alex_7
alex_7 on 10 Jul 2018
There is a limited number of class types, that means that I am not trying to create a class based on arbitrary string. The drawback of if-else statements is that if a new class type is available then another if statement has to be implemented. Anyway it seems that there is no solution to the problem and have to create constructors for the subclasses. Thank you very much for your time.
Adam
Adam on 10 Jul 2018
Edited: Adam on 10 Jul 2018
What is wrong with the str2func approach if you really must do it this way?
Having to add an extra if-else clause may be seen as a drawback, but can also just be seen as part of extending a piece of tight code in an explicit way that forces you to ensure that the new case is satisfied. A very generic answer that can just create any type of class from any type of string may seem much nicer, but is also far more open to bugs and misuse, in the same way that just making every function and property of a class public makes it appear 'simpler' to use, but ultimately creates a mess.

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 10 Jul 2018
I agree with Adam there are a lot of inconveniences that come with packages, so I've given up on them entirely.
I also completely agree with Adam, you should create a class factory. You can either implement that as a free function or as a static method of an abstract superclass of all your classes, or as a static method of a factory class.
The implementation of the creation code itself can also be done several ways as well, using if/else statements as Adam suggested or even with eval. That's one use of eval that would be perfectly valid. If all your classes derive from an abstract base you could even check that your string is indeed a valid class using meta.class. eval has the advantage that you indeed don't need to change anything when a new class gets added to the list.
And if the package issue gets fixed, you can switch to the package method suggested on StackOverflow if eval is disturbing.

More Answers (1)

Sean de Wolski
Sean de Wolski on 10 Jul 2018
Edited: Sean de Wolski on 10 Jul 2018
I had to do this for an application I worked on where I wanted to have an unknown number of models in a package and to be able to scrape it and construct all classes that inherit from the same abstract base class as Guillaume describes.
This is also how the unit test framework creates test suites fromPackage or fromFolder (that's where I got the idea from).
methods (Access = protected)
% Figure out model trainers to use
function setModelTrainers(obj, modeltrainers)
if isempty(modeltrainers)
% Grab all classes in model trainers package
mt = meta.package.fromName('LoadForecaster.Prediction.ModelTrainers');
classes = mt.ClassList;
% Determine which ones are of the correct type
for ii = numel(classes):-1:1
switch obj.ModelType
case 'Regression'
idx(ii) = ismember(?LoadForecaster.Prediction.RegressionTrainer, classes(ii).SuperclassList);
% Add more cases to add classification, etc.
end
end
% Set
obj.ModelTrainers = classes(idx);
else
% Use passed in ones
obj.ModelTrainers = modeltrainers;
end
% Loop over model trainers building a function to the call the
% constructor.
for ii = numel(obj.ModelTrainers):-1:1
obj.ModelTrainerConstructors{ii} = str2func(obj.ModelTrainers(ii).Name);
end
end
end

Categories

Find more on Programming in Help Center and File Exchange

Products


Release

R2018a

Community Treasure Hunt

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

Start Hunting!