As an example, suppose I have created an abstract class called Shape
and two subclasses called Circle
and Rectangle
that both implement an (abstract) method called Draw
. I would like to be able to create a number of Circle
and Rectangle
objects, store them in an array and call Draw
on each array object by iterating through the array.
I have tried something like the following:
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
When I try to run test.m, I get the following error message:
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();
- An Abstract class is one whose instance CANNOT be created. - Creating an Array which holds the Object Reference Variable of that Abstract class are just the references not the object itself.
Build Arrays in the ConstructorTo preallocate the object array, assign the last element of the array first. MATLAB® fills the first to penultimate array elements with the ObjectArray object. After preallocating the array, assign each object Value property to the corresponding value in the input array F .
A heterogeneous array is an array of objects that differ in their specific class, but all objects derive from or are instances of a common superclass. The common superclass forms the root of the hierarchy of classes that you can combine into heterogeneous arrays.
The abstract class defines the interface of each subclass without specifying the actual implementation. An abstract class serves as a basis (that is, a superclass) for a group of related subclasses. An abstract class can define abstract properties and methods that subclasses implement.
As is clear from the error, you cannot instantiate an abstract class (see sebastian's answer for details). However, there is a special superclass called matlab.mixin.Heterogeneous
from which you can derive to allow creation of an array of different classes.
First, derive from matlab.mixin.Heterogeneous
in Shape.m:
classdef (Abstract) Shape < handle & matlab.mixin.Heterogeneous
Then in your test script, initialize shapes
from either Circle
or Rectangle
:
shapes = Circle.empty();
When you run the loop, the array will change class:
>> 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.
That should be all you need, but for additional control over a heterogeneous array, you can override the getDefaultScalarElement method of matlab.mixin.Heterogeneous
to specify the default object. This should be overridden for abstract base classes:
Override this method if the Root Class is abstract or is not an appropriate default object for the classes in the heterogeneous hierarchy. getDefaultScalarElement must return an instance of another member of the heterogeneous hierarchy.
Say you want the default object to be Circle
for an array of objects deriving from Shape
:
methods (Static, Sealed, Access = protected)
function default_object = getDefaultScalarElement
default_object = Circle;
end
end
Now missing elements in an array of objects derived from Shape
will be filled with Circle
objects:
>> 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.
From the docs:
abstract class — A class that cannot be instantiated, but that defines class components used by subclasses.
See: Mathworks-Docs
Which is, afaik, the definition of abstract classes in other programming languages as well (someone correct me if I'm wrong).
So to construct an array that holds various kinds of Shape
elements, I'd guess you'll either have to make Shape
non-abstract or implement another non-abstract class, that all your real implementations inherit from.
EDIT: For completeness:
I tried what you're trying achieve and at first sight, object-arrays with mixed elements that have a common superclass don't exist:
>> 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
EDIT 2: See chappjc's solution for this issue ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With