MATLAB Answers

Why do I get an error if do not define a constructor in the inherited class?

81 views (last 30 days)
Evgeny Pr
Evgeny Pr on 24 Jan 2013
Commented: Jim Hokanson on 27 May 2020
Here's a simple example that does not work in the MATLAB language:
classdef Bar < handle
% Bar class
properties
Value
end
methods
function self = Bar(value)
self.Value = value;
end
end
end
classdef Foo < Bar
% Foo class
% No has constructor. We want to use the "Bar" constructor
end
>> f = Foo(10)
Error using Foo
Too many input arguments.
Too many input arguments.???
Ok...
>> f = Foo()
Error using Bar (line 10)
Not enough input arguments.
Error in Foo (line 1)
classdef Foo < Bar
What's going on? This is the ordinary inheritance. I would not want every time to write this:
classdef Foo < Bar
methods
function self = Foo(value)
self = self@Bar(value);
end
end
end

  3 Comments

Jim Hokanson
Jim Hokanson on 27 May 2020
This seems to be version specific. I'm hopping beween versions right now and 2016b throws the same error but 2019a doesn't ...

Sign in to comment.

Accepted Answer

Daniel Shub
Daniel Shub on 25 Jan 2013
Edited: Daniel Shub on 25 Jan 2013
Classes and subclasses do not need a constructor.
classdef mysimpleclass
end
is perfectly valid. If a subclass does not have a constructor it calls the superclass constructor with no arguments. In other words the default constructor looks something like
function obj = mysubclass()
obj = obj@myclass;
end
It sounds like you would like the default constructor to look like
function obj = mysubclass(varargin)
obj = obj@myclass(varargin{:});
end
such that it would pass the arguments up the chain. I think both are reasonable defaults. There is a slight difference between MATLAB and Python (and most other languages) which potentially swayed TMW to go with the former approach in which no arguments get passed to the superclass. Because everything is an array in MATLAB, and how TMW chose to implement the OO system, the constructor for every MATLAB class needs to support being called with no input arguments (this is well documented).
EDIT
I think the choice becomes clearer if expand from the no constructor case a little bit. Consider
classdef mysubclass < myclass
methods
function obj = mysubclass(varargin)
end
end
end
Calling the mysubclass constructor invisibly calls the myclass constructor with no arguments. I believe this is documented. As we are guaranteed that the myclass constructor can be called with no arguments, it makes a little more sense to pass it no arguments (which will not crash) than pass it all the arguments which might result in an error. Either way you will end up with having to explicitly call the superclass constructor sometimes (either to pass all arguments or to pass no/some arguments). Passing all arguments seems less robust than pass no arguments. Passing a subset just seems silly.

  5 Comments

Show 2 older comments
Evgeny Pr
Evgeny Pr on 25 Jan 2013
@Daniel
> Passing a subset just seems silly
I agree.
> ...the myclass constructor can be called with no arguments, it makes a lot more sense to pass it no arguments (which will not crash) than pass it all the arguments which might result in an error.
It is a disputed, that it is better... :)
Daniel Shub
Daniel Shub on 25 Jan 2013
@Evgeny, you are correct. I changed "a lot more sense" to "a little more sense". I don't think one is substantially better than another. Just as you don't want to write "self = self@Bar(value);" every time, TMW decided that they/we didn't want to write "self = self@Bar;" every time. You asked "What's going on?" and I tried to explain what is going on and that it essentially was a design decision by the TMW.
Evgeny Pr
Evgeny Pr on 25 Jan 2013
@Daniel
Thanks for your reasonable answer. I will choose your answer as an accepted.
@Matt J
Thanks for the discussion!

Sign in to comment.

More Answers (1)

Matt J
Matt J on 24 Jan 2013
Edited: Matt J on 24 Jan 2013
Write the Bar constructor to handle the case when no input arguments are passed. Otherwise, it needs to get those arguments from somewhere, e.g.,
function self = Bar(varargin)
if nargin
value=varargin{1};
else
value=somedefault;
end
self.Value = value;
end

  17 Comments

Evgeny Pr
Evgeny Pr on 25 Jan 2013
Then you will need to write a constructor in a subclass. But it is even less often (in my experience) :)
Matt J
Matt J on 25 Jan 2013
Then you should correct what you said here
I want matlab transfers to the constructor of the superclass all parameters, unless the subclass constructor is not define.
You really meant to say "I want matlab to transfer to the constructor of the superclass all parameters, IF the subclass constructor is not defined."
Yes, I think I can see what you mean. Although, it somehow seems cleaner to me that for every function call
subclassConstructor(params)
there is a function signature to match. But that might just be the bias of my experience...

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!