作为一个例子,假设我创建了一个名为Shape
的抽象类和两个名为Circle
和Rectangle
的子类,它们都实现了一个名为Draw
的(抽象)方法。我希望能够创建一些Circle
和Rectangle
个对象,将它们存储在一个数组中,并通过遍历数组在每个数组对象上调用Draw
。
我尝试过以下内容:
Shape.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
Rectangle.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();
答案 0 :(得分:14)
从错误中可以清楚地看出you cannot instantiate an abstract class(详见塞巴斯蒂安的回答)。但是,有一个名为matlab.mixin.Heterogeneous
的特殊超类,您可以从中派生它以允许创建不同类的数组。
首先,从Shape.m中的matlab.mixin.Heterogeneous
派生:
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.
这应该是您所需要的,但是为了对异构数组进行额外控制,您可以覆盖matlab.mixin.Heterogeneous
的{{3}}来指定默认对象。这应该被抽象为抽象基类:
如果Root Class是抽象的,则覆盖此方法,或者不是异构层次结构中的类的适当默认对象。 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.
答案 1 :(得分: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针对此问题的解决方案;)