| MATLAB® | ![]() |
| On this page… |
|---|
An abstract class serves as a basis (i.e., a superclass) for a group of related subclasses. It forms the abstractions that are common to all subclasses by specifying the common properties and methods that all subclasses must implement. However, the abstract class cannot itself be instantiated. Only the subclasses can be instantiated. These subclasses are sometimes referred to as concrete classes.
Abstract classes are useful for describing functionality that is common to a group of classes, but requires unique implementations within each class. This approach is often called an interface because the abstract class defines the interface of each subclass without specifying the actual implementation.
Define an abstract class by setting the Abstract attribute on one or more methods of a class to true. You do not use a function...end block to define an abstract method, use only the method signature.
For example, the group abstract class defines two methods that take two input arguments and return a result:
classdef group % Both methods must be implemented so that % the operations are communtative methods (Abstract) rsult = add(numeric,polynom) rsult = times(numeric,polynom) end end
The subclasses must implement methods with the same names. The names and number of arguments can be different. However, the abstract class typically conveys details about the expected implementation via its comments and argument naming.
For properties that have Abstract attributes set to true:
Concrete subclasses must redefine abstract properties without the Abstract attribute set to true and must use the same values for SetAccess and GetAccess attributes as the base class.
Abstract properties cannot define set or get access methods (see Controlling Property Access) and cannot specify initial values. The subclass must define the property and then can create set or get access methods and specify initial values.
For methods that have Abstract attributes set to true:
Abstract methods have no implementation in the abstract class. The method has a normal function line (without the function or end key words) that can include input and output argument lists.
Subclasses are not required to support the same number of input and output arguments and do not need to use the same argument names. However, subclasses generally use the same signature when implementing their version of the method.
The properties and methods defined by a class form the interface that determines how users interact with objects of the class. When you are creating a group of related classes, it makes sense to define a common interface to all these classes, even though the actual implementations of this interface might differ from one class to another. Abstract properties and methods provide a mechanism to create interfaces for groups of classes.
For example, consider a set of classes designed to represent a variety of graphs (e.g., line plots, bar graphs, pie charts, and so on). Suppose all classes need to implement a Data property to contain the data used to generate the graph. However, the form of the data might differ considerably from one type of graph to another. Consequently, the way each class implements the Data property needs to be different.
The same differences apply to methods. All classes might have a draw method that creates the graph, but the implementation of this method changes with the type of graph.
The basic idea of an interface class is to specify the properties and methods that each subclass must implement without defining the actual implementation. This enables you to enforce a consistent interface to a group of related objects. As more classes are added in the future, the interface is maintained.
This example creates an interface for classes used to display specialized graphs. The interface is an abstract class that defines properties and methods that the subclasses need to implement, but does not specify how to implement these components. This enforces the use of a consistent interface while at the same time provides the necessary flexibility to implement the internal workings of each specialized graph subclass differently.
In this example, the interface, derived subclasses, and a utility function are contained in a package directory:
+graphics/graph.m % abstract interface class +graphics/linegraph.m % concrete subclass +graphics/addButtons.m % static method of graph class
The graph class specifies the following properties to be defined by subclasses:
Primitive — Handle of the Handle Graphics object used to implement the specialized graph. The user has no need to access these objects directly so this is property has protected SetAccess and GetAccess.
AxesHandle — Handle of the axes used for the graph. The specialized graph objects might set axes object properties and also limit this properties SetAccess and GetAccess to protected.
Data — All specialized graph objects need to store data, but the type of data varies so each subclass defines the way the data is stored. Subclass users can change the data so this property has public access rights.
The graph class names three abstract methods that subclasses need to implement. The graph class also suggests in comments that each subclass constructor needs to accept the data to be plotted and property name/property value pairs for all class properties.
subclass_constructor — Accept data and P/V pairs and return an object.
draw — Used to create a drawing primitive and render a graph of the data according to the type of graph implemented by the subclass.
zoom — Implementation of a zoom method by changing the axes CameraViewAngle property. The interface suggests the use of the camzoom function for consistency among subclasses. This method is used as a callback for the zoom buttons created by the addButtons static method.
updateGraph — Method called by the set.Data method to update the plotted data whenever the Data property is changed.
The package of classes that derive from the graph abstract class implement the following behaviors:
Creating an instance of a specialized graph object (subclass object) without rendering the plot
Specifying any or none of the object's properties when you create a specialized graph object
Changing any object property automatically updates the currently displayed plot
Allowing each specialized graph object to implement whatever additional properties it needs to give users control over those characteristics.
The graph class is an abstract class that defines the methods and properties used by the derived classes. Comments in the abstract class suggest the intended implementation:
classdef graph < handle % Abstract class for creating data graphs % Subclass constructor should accept % the data that is to be plotted and % property name/property value pairs properties (SetAccess = protected, GetAccess = protected) Primitive % HG primitive handle AxesHandle % Axes handle end properties % Public access Data end methods (Abstract) draw(obj) % Use a line, surface, % or patch HG primitive zoom(obj,factor) % Change the CameraViewAngle % for 2D and 3D views % use camzoom for consistency updateGraph(obj) % Called by the set.Data method % to update the drawing primitive % whenever the Data property is changed end methods function set.Data(obj,newdata) obj.Data = newdata; updateGraph(obj) end end methods (Static) addButtons(obj) end end
The graph class implements the property set method (set.Data) to monitor changes to the Data property. An alternative is to define the Data property as Abstract and enable the subclasses to determine whether to implement a set access method for this property. However, by defining the set access method that calls an abstract method (updateGraph, which must be implemented by each subclass), the graph interface more effectively imposes a specific design on the whole package of classes, without limiting flexibility.
The addButtons method simply adds push buttons for the zoom methods that each subclass must implement. Using a static method instead of an ordinary function enables the addButtons method to access the protected class data (the axes handle). Notice how the particular object's zoom method is defined as the buttons' callback.
function addButtons(gobj) hfig = get(gobj.AxesHandle,'Parent'); uicontrol(hfig,'Style','pushbutton','String','Zoom Out',... 'Callback',@(src,evnt)zoom(gobj,.5)); uicontrol(hfig,'Style','pushbutton','String','Zoom In',... 'Callback',@(src,evnt)zoom(gobj,2),... 'Position',[100 20 60 20]); end
Note Display the fully commented code for the linegraph class by clicking this link: linegraph class. |
This example defines only a single subclass used to represent a simple line graph. It derives from graph, but provides implementations for the abstract methods draw, zoom, updateGraph, and its own constructor. The base class (graph) and subclass are all contained in a package (graphics), which must be used to reference the class name:
classdef linegraph < graphics.graphThe linegraph class implements the interface defined in the graph class and adds two additional properties—LineColor and LineType. This class defines initial values for each property in case a linegraph object is created without specifying these properties (which might happen when reloading an object from a MAT-file). Specifying property values in the constructor is optional. Data is required to produce a plot, but not to create a linegraph object):
properties LineColor = [0 0 0]; LineType = '-'; end
The constructor accepts a struct with x and y coordinate data, as well as property name/property value pairs:
function gobj = linegraph(data,varargin) if nargin > 0 gobj.Data = data; if nargin > 2 for k=1:2:length(varargin) gobj.(varargin{k}) = varargin{k+1}; end end end end
The linegraph draw method uses property values to create a line object. The line handle is stored as protected class data. The linegraph class does not create the line primitive and display its plot until the draw method is called. To support the use of no input arguments for the constructor, draw checks the Data property to determine if it is empty before proceeding:
function gobj = draw(gobj) if isempty(gobj.Data) error('The linegraph object contains no data') end h = line(gobj.Data.x,gobj.Data.y,... 'Color',gobj.LineColor,... 'LineStyle',gobj.LineType); gobj.Primitive = h; gobj.AxesHandle = get(h,'Parent'); end
The linegraph zoom method follows the directions in the graph class and uses the camzoom function, which provides a convenient interface to zooming and operates correctly with the push buttons created by the addButtons method.
Property set methods provide a convenient way to execute code automatically when the value of a property is changed or assigned for the first time in a constructor (see Property Set Methods). The linegraph class uses set methods to update the line primitive data (which causes a redraw of the plot) whenever a property value changes. The use of property set methods provides a way to update the data plot quickly without requiring a call to the draw method, which updates the plot by resetting all values to match the current property values.
Three properties use set methods LineColor, LineType, and Data. LineColor and LineType are properties added by the linegraph class and are specific to the line primitive used by this class. Other subclasses might define different properties unique to their specialization (e.g., FaceColor).
The Data property set method is implemented in the graph class. However, the graph class requires each subclass to define a method called updateGraph, which handles the update of plot data for the specific drawing primitive used.
The linegraph class defines the simple API specified by the graph base class and implements its specialized type of graph:
d.x = 1:10; d.y = rand(10,1); lg = graphics.linegraph(d,'LineColor','b','LineType',':'); lg.draw; graphics.graph.addButtons(lg);
Clicking the Zoom In button shows the zoom method providing the callback for the button.

Changing properties updates the graph:
d.y = rand(10,1); % new set of random data for y lg.Data = d; lg.LineColor = [.9 .1 .6]; % LineColor can be char or double
Now click Zoom Out and see the new results:

![]() | Subclassing MATLAB Built-In Classes | Properties — Storing Class Data | ![]() |
| © 1984-2008- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |