Why does MATLAB attempt to instantiate abstract properties?

Viewed 268

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

  1. Removing the size validation in TestClass eliminates the error. Evidently, MATLAB has no problem initializing a empty array of objects without a valid zero-argument constructor. Note: this only works when TestClassB is not abstract.
  2. If TestClassB is abstract and TestClassC initializes aprop in the property block with a concrete subclass of TestClassB, there is no error (assuming that the concrete subclass has a valid zero-argument constructor). Note: this is not true if aprop is instead initialized in TestClassC's constructor.

Motivating example

Car UML diagram

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.

1 Answers

It seems that two questions should be answered:

1 - "Evidently, MATLAB is trying to instantiate the abstract property aprop in TestClass. So why does MATLAB attempt to instantiate abstract properties?"

According to the documentation (emphasis is by me):

You can define property validation for abstract properties. The validation applies to all subclasses that implement the property.

MATLAB is trying to instantiate the property aprop in TestClassC that is a concrete subclass of TestClass. But it uses the same validation rules that is used in TestClass. The aprop property of TestClassC isn't abstract.

2 - "If TestClassB ... is defined to be abstract, you end up falling into the same trap..."

Referring to the documentation:

abstract class — A class that cannot be instantiated, but that defines class components used by subclasses.

TestClassC uses the same validation rules that is used in TestClass. It tries to instantiate its aprop member that is of class TestClassB but TestClassB is abstract and cannot be instantiated.

Related