残念ながら、MATLABの配列のすべての要素は同じタイプである必要があります。異なるクラスを連結すると、MATLABはそれらすべてを同じクラスに変換しようとします。
クラスの1つを他のクラスよりも劣っているまたは優れていると定義した場合(InferiorClasses属性またはINFERIORTO / SUPERIORTO関数を使用)、より優れたクラスのメソッドが呼び出されます。クラス間の関係を指定していない場合、2つのオブジェクトの優先順位は等しくなり、MATLABは左端のオブジェクトメソッドを呼び出します。arr = [b c];
これが、クラスBの配列をarr = [c b];
作成し、クラスCの配列を作成する理由である可能性があります。
オプション1:セルアレイ
foo
オブジェクトのクラスBに定義されたメソッドを実行し、オブジェクトのクラスCに定義されb
たメソッドも実行する場合は、セル配列と関数CELLFUNを使用する必要があります。が値を返さない場合は、次のようにすることができます。foo
c
foo
arr = {b,c};
cellfun(@foo,arr); % Invoke foo on each element of the cell array
オプション2:仮帆装のポリモーフィックな振る舞いを楽しむ
楽しみのために、私は技術的には機能するが、いくつかの制限がある潜在的な解決策を思いついた。アイデアを説明するために、質問にリストしたものと同様のサンプルクラスをいくつかまとめました。これが抽象的なスーパークラスclassA
です:
classdef classA < hgsetget
properties
stuff
end
properties (Access = protected)
originalClass
end
methods
function foo(this)
disp('I am type A!');
if ~strcmp(class(this),this.originalClass)
this = feval(this.originalClass,this);
end
this.fooWorker;
end
end
methods (Abstract, Access = protected)
fooWorker(this);
end
end
そして、これがサブクラスの例ですclassB
(どこでも置き換えられたものclassC
とまったく同じであり、その逆も同様です)。B
C
classdef classB < classA
methods
function this = classB(obj)
switch class(obj)
case 'classB' % An object of classB was passed in
this = obj;
case 'classC' % Convert input from classC to classB
this.stuff = obj.stuff;
this.originalClass = obj.originalClass;
otherwise % Create a new object
this.stuff = obj;
this.originalClass = 'classB';
end
end
end
methods (Access = protected)
function fooWorker(this)
disp('...and type B!');
end
end
end
classB
およびのコンストラクターはclassC
、2つのクラスを相互に変換できるように設計されています。プロパティoriginalClass
は作成時に初期化され、オブジェクトの元のクラスが何であったかを示します。オブジェクトがあるクラスから別のクラスに変換されても、このプロパティは変更されません。
メソッド内で、foo
渡されたオブジェクトの現在のクラスが元のクラスと照合されます。それらが異なる場合、fooWorker
メソッドを呼び出す前に、オブジェクトは最初に元のクラスに変換されます。テストは次のとおりです。
>> b = classB('hello'); % Create an instance of classB
>> c = classC([1 2 3]); % Create an instance of classC
>> b.foo % Invoke foo on b
I am type A!
...and type B!
>> c.foo % Invoke foo on c
I am type A!
...and type C!
>> arr = [b c] % Concatenate b and c, converting both to classB
arr =
1x2 classB handle
Properties:
stuff
Methods, Events, Superclasses
>> arr(1).foo % Invoke foo on element 1 (formerly b)
I am type A!
...and type B!
>> arr(2).foo % Invoke foo on element 2 (formerly c)
I am type A!
...and type C!
(少し醜いことを除いて)1つの重要な制限はclassB
、classC
それぞれが他にはないプロパティを持っている場合です。このような場合、他のクラスに変換してから元に戻すと、それらのプロパティが失われる可能性があります(つまり、デフォルト値にリセットされます)。ただし、一方のクラスがもう一方のクラスのサブクラスであり、すべて同じプロパティを持ち、それからいくつかの場合、解決策があります。サブクラスをスーパークラスよりも優れているように設定して(上記の説明を参照)、2つのクラスのオブジェクトを連結すると、常にスーパークラスオブジェクトがサブクラスに変換されます。(上記のような)「ポリモーフィック」メソッド内で変換して戻すfoo
と、オブジェクトデータが失われることはありません。
これがどれほど実行可能な解決策であるかはわかりませんが、少なくともいくつかの興味深いアイデアが得られるかもしれません。;)