MATLAB handle class violates polymorphism on handle equivalence

19 ビュー (過去 30 日間)
JP Barnard
JP Barnard 2011 年 3 月 30 日
編集済み: per isakson 2016 年 10 月 21 日
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 件のコメント
Walter Roberson
Walter Roberson 2011 年 3 月 31 日
Do you find evidence in the documentation that claims that Matlab supports polymorphism of objects?
JP Barnard
JP Barnard 2011 年 4 月 11 日
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.

サインインしてコメントする。

採用された回答

Clark Williams
Clark Williams 2011 年 9 月 29 日
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 件のコメント
JP Barnard
JP Barnard 2011 年 9 月 30 日
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.

サインインしてコメントする。

その他の回答 (3 件)

Patrick Kalita
Patrick Kalita 2011 年 4 月 8 日
I believe what you are looking for has been introduced in R2011a with the Heterogeneous mixin class.
  3 件のコメント
JP Barnard
JP Barnard 2011 年 4 月 11 日
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.
Patrick Kalita
Patrick Kalita 2011 年 4 月 11 日
@Andrew, that's a good question; I'm actually not sure what the answer is.

サインインしてコメントする。


Andrew Newell
Andrew Newell 2011 年 3 月 30 日
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 件のコメント
Walter Roberson
Walter Roberson 2011 年 3 月 31 日
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.
Andrew Newell
Andrew Newell 2011 年 3 月 31 日
@Walter, where did you find that information?

サインインしてコメントする。


JP Barnard
JP Barnard 2011 年 4 月 11 日
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.

カテゴリ

Help Center および File ExchangeGraphics Object Programming についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by