【问题标题】:How do I create an array of abstract class objects in MATLAB?如何在 MATLAB 中创建一组抽象类对象?
【发布时间】:2013-11-22 21:42:20
【问题描述】:

例如,假设我创建了一个名为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

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();

【问题讨论】:

    标签: matlab oop polymorphism matlab-class


    【解决方案1】:

    从错误中可以清楚地看出,you cannot instantiate an abstract class(有关详细信息,请参阅塞巴斯蒂安的回答)。但是,有一个名为 matlab.mixin.Heterogeneous 的特殊超类,您可以从中派生以允许创建不同类的数组。

    首先,派生自 Shape.m 中的matlab.mixin.Heterogeneous

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

    然后在您的测试脚本中,从CircleRectangle 初始化shapes

    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.
    

    这应该是您所需要的,但要对异构数组进行额外控制,您可以覆盖matlab.mixin.Heterogeneousthe getDefaultScalarElement method 以指定默认对象。这应该被抽象基类覆盖:

    如果根类是抽象的或者不是异构层次结构中类的适当默认对象,则覆盖此方法。 getDefaultScalarElement 必须返回异构层次结构的另一个成员的实例。

    假设您希望从Shape 派生的对象数组的默认对象为Circle

    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.
    

    【讨论】:

      【解决方案2】:

      来自文档:

      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 对此问题的解决方案;)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-21
        • 1970-01-01
        • 1970-01-01
        • 2011-05-18
        相关资源
        最近更新 更多