Validate property is a subclass of an abstract class
34 views (last 30 days)
Show older comments
I've just upgraded from 2018b to 2020a and some of my code has stopped working. With release 2018b the following code did not throw an error. The idea is that myProperty must always be a subclass of myAbstractClass.
classdef myClass
properties (Abstract)
myProperty(1,1) myAbstractClass
end
end
When I attempt to use myClass in release 2020a I get the following complaint: "Error defining property 'myProperty' of class 'myClass'. Class myAbstractClass is abstract. Specify a default value for property myProperty."
Having read the documentation carefully (https://uk.mathworks.com/help/matlab/matlab_oop/property-size-and-class-validation.html#bvklfs7-1) I can see that Matlab is attempting to assign a default value to myProperty which is an empty instance of myAbstractClass. At this point the code fails because it is not possible to instantiate an abstract class. Presumably the default value was assigned differently in 2018b or the checks were less rigerous. Anyway, I've now got a codebase which doesn't work and needs fixing.
Obviously I could write my own property validation function to get the behaviour I require, or I could do validation in the setter. I've used the same trick in other places in the code, so ideally I don't want to spend ages writing custom property validation functions or modifying setters. Is there an elegant way to deal with this? Something like a mustBeClass validaiton function?
0 Comments
Answers (1)
Tim Johns
on 2 Sep 2020
Hi Tim,
I can see that Matlab is attempting to assign a default value to myProperty which is an empty instance of myAbstractClass. At this point the code fails because it is not possible to instantiate an abstract class.
Correct. So what you need to do is specify a default property value that is a concrete class:
classdef MyClass
properties (Abstract)
myProperty(1,1) MyAbstractClass = MyConcreteClass()
end
end
Where for example:
classdef (Abstract) MyAbstractClass
methods (Abstract)
foo(obj)
end
end
classdef MyConcreteClass < MyAbstractClass
methods
function foo(obj)
% Implementation
end
end
end
Tim
2 Comments
Thomas Michiels
on 25 Aug 2021
i have the exact same issue using the MustBeA validator.
the annoying part is that i don't want to set a default value as this will get passed in the constructor. As far as i've noticed, this scenario is not decently supported due to the 0argument constructor requirement. But also the fact that almost none of the validators accept empty defaults is a huge issue for the use of abstract classes as a requirement.
the only decent solution for using abstract classes when you don't want to define a concrete class default is implementing your own `MustBaAOrEmpty(obj, classtr)`
Tim Johns
on 25 Aug 2021
Hi Thomas,
MATLAB needs to be able to initialise property values. If you define constraints on that value such as size, type, or validation functions, the initial value must also meet those constraints - you can't have a "null". A second restriction is that you cannot instantiate abstract classes.
Together, these restrictions mean that if you are imposing an abstract type restriction on a property, you need to provide a concrete instance as an initial value. (I think you know this but wanted to clarify.)
The way I normally handle this is by implementing a "NoOp" subclass for default values that implement the required interface. It can also be useful for testing when you don't actually care about that property. The code would be the same as my original answer, but foo would actually do nothing rather than having some implementation. I don't find doing this to be onerous.
I hope that helps.
See Also
Categories
Find more on Software Development Tools in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!