14

例如,假设我创建了一个名为的抽象类Shape和两个名为的子类CircleRectangle它们都实现了一个名为Draw. 我希望能够创建多个CircleRectangle对象,将它们存储在一个数组中,并Draw通过遍历数组来调用每个数组对象。

我尝试过类似以下的方法:

形状.m:

classdef (Abstract) Shape < handle

    methods (Abstract)
        Draw(obj);
    end

end

圆.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

测试.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

这就是,afaik,其他编程语言中抽象类的定义(如果我错了,有人纠正我)。

因此,要构造一个包含各种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 回答