There is unexpected (to me) behavior when combining class property validation with abstract properties in MATLAB. Here is a short example involving three classes:
classdef TestClass
properties (Abstract)
aprop (1,1) TestClassB
end
end
classdef TestClassB
methods
function obj = TestClassB(a)
disp(a);
end
end
end
classdef TestClassC < TestClass
properties
aprop
end
end
Then, when attempting to instantiate a TestClassC object, I get the following error:
>> TestClassC()
Error defining property 'aprop' of class 'TestClass'. Unable to construct default
object of class TestClassB.
Evidently, MATLAB is trying to instantiate the abstract property aprop in TestClass and then fails due to the lack of a valid zero-argument constructor in aprop's class definition TestClassB. I realize that the zero-argument constructor issue is in theory fixable (although only if you have access to modify TestClassB), but the fact that MATLAB is instantiating an abstract property at all seems very strange. The first line of the Wikipedia article on abstract types literally states:
...an abstract type is a type in a nominative type system that cannot be instantiated directly...
Perhaps this is the only way that MATLAB, as a weakly typed language, can implement property validation, but this is an unfortunate result.
On a side note, if TestClassB has a valid zero-argument constructor but is defined to be abstract, you end up falling into the same trap but with a slightly different error:
>> TestClassC()
Error defining property 'aprop' of class 'TestClass'. Class TestClassB is abstract.
Specify a default value for property aprop.
Is there a good reason for this behavior?
Edit:
Additional test-class observations
- Removing the size validation in
TestClasseliminates the error. Evidently, MATLAB has no problem initializing a empty array of objects without a valid zero-argument constructor. Note: this only works whenTestClassBis not abstract. - If
TestClassBis abstract andTestClassCinitializesapropin the property block with a concrete subclass ofTestClassB, there is no error (assuming that the concrete subclass has a valid zero-argument constructor). Note: this is not true ifapropis instead initialized inTestClassC's constructor.
Motivating example
The above UML diagram is a typical example of combining inheritance with composition. GenericCar and GenericEngine are abstract classes. GenericCar contains a GenericEngine, but Racecar specifies its engine as a concrete V8 (which "isa" GenericEngine). Unfortunately, this can't be constructed using property validation in MATLAB since MATLAB will not allow you to re-define the class of an abstract property even if it is a subclass of the original definition.
Suppose you accept that you can't define engine in Racecar as a V8. Even so, if you don't supply an initial value for engine in the property block of Racecar, MATLAB will throw an error when creating a Racecar object since it will try to initialize engine using the abstract type GenericEngine. This is true even if the constructor of Racecar initializes engine as a V8 object. This highlights the odd connection between property validation and object instantiation.
