14

例として、 という抽象クラスと という 2 つのサブクラスを作成し、両方Shapeがという (抽象) メソッドを実装しているとします。多数のandオブジェクトを作成し、それらを配列に格納し、配列を反復処理して各配列オブジェクトを呼び出すことができるようにしたいと考えています。CircleRectangleDrawCircleRectangleDraw

私は次のようなことを試しました:

形状.m:

classdef (Abstract) Shape < handle

    methods (Abstract)
        Draw(obj);
    end

end

Circle.m:

classdef Circle < Shape

    methods
        function obj = Draw(obj)
            disp('This is a circle');
        end
    end

end

長方形.m:

classdef Rectangle < Shape

    methods
        function obj = Draw(obj)
            disp('This is a rectangle');
        end
    end

end

test.m:

shapes = Shape.empty();

myrect = Rectangle();
mycirc = Circle();

shapes(end + 1) = myrect;
shapes(end + 1) = mycirc;

for i = 1:size(shapes,1)
    shapes(i).Draw();
end

test.m を実行しようとすると、次のエラー メッセージが表示されます。

Error using Shape.empty
Abstract classes cannot be instantiated.
Class 'Shape' defines abstract methods
and/or properties.

Error in test (line 1)
shapes = Shape.empty();
4

2 に答える 2

15

エラーから明らかなように、抽象クラスをインスタンス化することはできません(詳細については、セバスチャンの回答を参照してください)。ただし、matlab.mixin.Heterogeneousさまざまなクラスの配列を作成できるように派生できる特別なスーパークラスが呼び出されます。

まず、matlab.mixin.HeterogeneousShape.mから派生します。

classdef (Abstract) Shape < handle & matlab.mixin.Heterogeneous

次に、テスト スクリプトで、またはshapesのいずれCircleかから初期化しRectangleます。

shapes = Circle.empty();

ループを実行すると、配列のクラスが変更されます。

>> shapes

shapes = 

  1x2 heterogeneous Shape (Rectangle, Circle) array with no properties.

>> shapes(1)

ans = 

  Rectangle with no properties.

>> shapes(2)

ans = 

  Circle with no properties.

必要なのはこれだけですが、異種混合配列をさらに制御するために、 の getDefaultScalarElement メソッドをオーバーライドしmatlab.mixin.Heterogeneousてデフォルト オブジェクトを指定できます。これは、抽象基本クラスに対してオーバーライドする必要があります。

ルート クラスが抽象であるか、異種階層内のクラスの適切な既定のオブジェクトでない場合は、このメソッドをオーバーライドします。getDefaultScalarElement は、異種混合階層の別のメンバーのインスタンスを返す必要があります。

Circleから派生したオブジェクトの配列用のデフォルト オブジェクトが必要だとしますShape

methods (Static, Sealed, Access = protected)
    function default_object = getDefaultScalarElement
        default_object = Circle;
    end
end

から派生したオブジェクトの配列で欠落している要素がオブジェクトShapeで埋められるようになりましたCircle

>> clear r
>> r(2) = Rectangle
r = 
  1x2 heterogeneous Shape (Circle, Rectangle) array with no properties.
>> r(1)
ans = 
  Circle with no properties.
>> r(2)
ans = 
  Rectangle with no properties.
于 2013-11-11T08:23:15.823 に答える
3

ドキュメントから:

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

参照: Mathworks-Docs

これは、私の知る限り、他のプログラミング言語の抽象クラスの定義でもあります (間違っている場合は誰かが訂正してください)。

したがって、さまざまな種類の要素を保持する配列を構築するには、非抽象化するか、実際のすべての実装が継承する別の非抽象クラスを実装するShape必要があると思います。Shape

編集:完全を期すために:

私はあなたが達成しようとしていることを試しましたが、一見すると、共通のスーパークラスを持つ混合要素を持つオブジェクト配列は存在しません:

>> objects(1) = Foo();
>> objects(2) = FooBar();
The following error occurred converting from FooBar to Foo:
Error using Foo
Too many input arguments.

>> FooBar

ans = 

  FooBar handle with no properties.
  Methods, Events, Superclasses


Superclasses for class FooBar:

    Foo
    handle

編集 2: この問題については、chappjc のソリューションを参照してください ;)

于 2013-11-11T08:14:30.590 に答える