MATLAB handle class violates polymorphism on handle equivalence

I am shocked to discover that MATLAB seems to violate polymorphism when it comes to equivalence of handles in handle classes.
I presume that the handle to a handle class object is synonymous to a pointer of a specific class.
E.g.
Let
classdef MyBase < handle ... end
classdef MyDerived < MyBase ... end
1. array = repmat(MyBase,1,n);
2. array(1) = MyBase; % No error
3. array(2) = MyDerived; % Error!
The assignment in line 3 should not error, as the array is of the parent of MyDerived, in accordance with the above rule of equivalence of pointers under polymorphism.
Of course, one explanation is that handles are not synonymous to pointers. And the workaround is to deploy the cell array. Not nice.
What is the official explanation to the above anomaly?

3 Comments

More to the above:
obj = MyDerived;
isa(obj,'MyDerived')
ans =
1
isa(obj,'MyBase')
ans =
1
% which is in accordance with inheritance
isa(array,'MyBase')
ans =
1
And yet MATLAB denies the assignment in 3., above.
Do you find evidence in the documentation that claims that Matlab supports polymorphism of objects?
I am afraid not - refer to "Limitations to Object Substitution" in the user guide of R2010a - adding to my surprise at the lack of such support.
Apparently, R2011a (released after my question posted here) has introduced support for heterogeneous class arrays via a rather complicated design pattern, which obscures in my view the simplicity of classical polymorphic class substitution.

Sign in to comment.

 Accepted Answer

Just thought I'd chime in for the sake of others trying to get MATLAB to work as expected with an array of base class "pointers" to objects of derived classes. The matlab.mixin.Heterogeneous requires minimal changes and allows your code to work as expected. Here is a sample of what was giving me errors before:
classdef MyBase < handle { ... };
classdef DerivedA < MyBase { ... };
classdef DerivedB < MyBase { ... };
%%Create an array of MyBase objects
featureExtractors = MyBase.empty();
featureExtractors( end+1 ) = DerivedA();
featureExtractors( end+1 ) = DerivedB();
In order to get this to work, all I had to do was change the base class of MyBase from handle to matlab.mixin.Heterogeneous.
classdef MyBase < matlab.mixin.Heterogeneous { ... };

1 Comment

Thanks.
Since we have installed R2011a, I have taken a closer look at matlab.mixin.Heterogeneous. The caveats with respect to design patterns are apparently limited to vectorised methods, where, for one, these methods must be sealed in the applicable superclass. In another caveat, the identity of the applicable superclass changes, depending upon where each derived class falls in the inheritance hierarchy. So, because MATLAB supports vectorisation, there is no free meal with reaping the benefits of Heterogeneous - the programmer must carefully design the method allocation and intended polymorphic behaviour (a bit more carefully, perhaps, than in e.g. C++).
On the other hand, when accessing methods on individual objects in a heterogeneous (small h) array, e.g. obj(k).myMethod(), the above caveats do not apply and the expected polymorphic behaviour is upheld. In this case, the method is not subject to the Sealed requirement.

Sign in to comment.

More Answers (3)

I believe what you are looking for has been introduced in R2011a with the Heterogeneous mixin class.

3 Comments

@Patrick, do you know if there would be any performance penalty for using a heterogeneous class?
Thank you for this remark. Please note that R2011a has appeared after my posting on this issue.
I have checked the user guide on the topic and found the solution rather convoluted, obscuring the simplicity of classical polymorphic class substitution. The complexity increases substantially when dealing with derived handle classes, which is my original use case under discussion here, as one is forced to use multiple inheritance and keep track of what specific class of vectorised (array) methods apply in addition to scalar object methods.
On the other hand, I suppose the formal solution is to a large extent forced by the design decision of how class identity is internally represented in arrays of MATLAB objects. Also, there is no free meal in software development and therefore there must be some price to pay for vectorisation support in a polymorphic context. It seems unavoidable that some of this cost must lay at the door of the application programmer.
@Andrew, that's a good question; I'm actually not sure what the answer is.

Sign in to comment.

This is not an official explanation, but I can tell you this much: First, MATLAB does not have pointers. If you want handle polymorphism, you could try making a feature request. Another workaround for the above problem is to create a method to convert MyDerived to MyBase.

3 Comments

See also this previous discussion a few months ago, in which some users said explicitly that polymorphism is not supported but discussed workarounds in the context of a particular task:
In MATLAB, the type (class) of data (including objects) is not stored with the data. The type (class) is stored in a header block. MATLAB arrays have one header block for the entire array, so all elements of the array must be the exact same class unless you use a cell array. This system preserves class hierarchies but does not offer the kind of polymorphism that you would like.
@Walter, where did you find that information?

Sign in to comment.

Thank you to all who have posted comments to my original question. All of these inputs were of value.
As regards a solution, given that I am restricted by my user requirements to R2010a, I have resorted to the cell array as container in this particular case.
For future applications, where and when I am allowed to venture to R2011a, the rather complex solution implied by the new matlab.mixin.Heterogeneous feature will be considered.

Products

Community Treasure Hunt

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

Start Hunting!