Reputation: 11
New to Matlab but forced to use it for a new work project... I'm coming from a C++ background, but maybe I should not try to emulate coding paradigms from C++ with Matlab. I'm trying to figure out how to have a abstract class property that gets initialized when the constructor is called with a concrete member. For instance:
%AbstractClass.m
classdef (Abstract) AbstractClass < handle
end
%ConcreteClass.m
classdef ConcreteClass < AbstractClass
end
%myclass.m
classdef myclass < handle
properties
% X {AbstractClass} % would like to have this be like C++ nullptr
%X {AbstractClass} % can't initialize...
%X % Works, but not safe
X {mustBeA(X, 'AbstractClass')} % Suggested, error below
end
methods
% constructor
function obj = myclass( concreteInstanceOfAbstractClass )
obj.X = concreteInstanceOfAbstractClass
end
end
end
But when I try to run this
Y = ConcreteClass()
mustBeA(AbstractClass, Y) % no error, fine
mustBeA(ConcreteClass, Y) % no error, fine
A = myclass(Y) % throws error below
I get the following error
>> A = myclass(Y)
Error using implicit default value of property 'X' of class 'myclass'. Value must be one of the following types: 'AbstractClass'.
Is there a way to initialize the class in the constructor using the concrete instance of Abstract class? I have done some searching, but I'm new enough to Matlab that I'm probably not looking in the right places. This would be a very common thing to do in C++.
Upvotes: 1
Views: 360
Reputation: 25140
Try
properties
X {mustBeA(X, 'AbstractClass')}
end
which is a property validator rather than a class constraint.
Further to comments below, I realise the problem is that MATLAB insists on having a default value in the classdef
. Unfortunately, this makes things difficult. One approach is to supply a valid concrete class as the default value. This works:
properties
X AbstractClass = ConcreteClass
end
but requires that the using class knows the name of ConcreteClass
. Another approach (especially if the property needs to be set only at construction time) is this:
classdef Uses
properties (SetAccess = immutable)
% No constraints here
Property
end
methods
function obj = Uses(val)
arguments
% Enforce constraints here - scalar instance
% of something inheriting from AbstractClass
val (1,1) AbstractClass
end
obj.Property = val;
end
end
end
Upvotes: 1