008 Object-Oriented Programming
008 Object-Oriented Programming
Object-Oriented Programming
R2012a
How to Contact MathWorks
www.mathworks.com Web
comp.soft-sys.matlab Newsgroup
www.mathworks.com/contact_TS.html Technical Support
508-647-7000 (Phone)
508-647-7001 (Fax)
Trademarks
MATLAB and Simulink are registered trademarks of The MathWorks, Inc. See
www.mathworks.com/trademarks for a list of additional trademarks. Other product or brand
names may be trademarks or registered trademarks of their respective holders.
Patents
MathWorks products are protected by one or more U.S. patents. Please see
www.mathworks.com/patents for more information.
Revision History
March 2008 Online only New for MATLAB 7.6 (Release 2008a)
October 2008 Online only Revised for MATLAB 7.7 (Release 2008b)
March 2009 Online only Revised for MATLAB 7.8 (Release 2009a)
September 2009 Online only Revised for MATLAB 7.9 (Release 2009b)
March 2010 Online only Revised for MATLAB 7.10 (Release 2010a)
September 2010 Online only Revised for Version 7.11 (Release 2010b)
April 2011 Online only Revised for Version 7.12 (Release 2011a)
September 2011 Online only Revised for Version 7.13 (Release 2011b)
March 2012 Online only Revised for Version 7.14 (Release 2012a)
Contents
v
Using the BankAccount Class . . . . . . . . . . . . . . . . . . . . . . . 2-16
vi Contents
Grouping Classes with Package Folders . . . . . . . . . . . . . . . 3-3
More Information on Class Folders . . . . . . . . . . . . . . . . . . . 3-4
vii
Calling Superclass Methods on Subclass Objects . . . . . 3-26
Calling a Superclass Constructor . . . . . . . . . . . . . . . . . . . . . 3-26
Calling Superclass Methods . . . . . . . . . . . . . . . . . . . . . . . . . 3-27
viii Contents
Defining and Organizing Classes
4
User-Defined Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-2
Defining Classes in MATLAB . . . . . . . . . . . . . . . . . . . . . . . 4-2
ix
Value or Handle Class — Which to Use
5
Comparing Handle and Value Classes . . . . . . . . . . . . . . . 5-2
Basic Difference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-2
Why Select Handle or Value . . . . . . . . . . . . . . . . . . . . . . . . . 5-2
Behavior of MATLAB Built-In Classes . . . . . . . . . . . . . . . . 5-3
Behavior of User-Defined Classes . . . . . . . . . . . . . . . . . . . . 5-4
x Contents
Controlling the Number of Instances . . . . . . . . . . . . . . . . 5-31
Limiting Instances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-31
xi
What Are Dynamic Properties . . . . . . . . . . . . . . . . . . . . . . . 6-26
Defining Dynamic Properties . . . . . . . . . . . . . . . . . . . . . . . . 6-27
Responding to Dynamic-Property Events . . . . . . . . . . . . . . 6-29
Defining Property Access Methods for Dynamic
Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-31
Dynamic Properties and ConstructOnLoad . . . . . . . . . . . . . 6-32
xii Contents
Overloading Functions for Your Class . . . . . . . . . . . . . . . 7-27
Overloading MATLAB Functions . . . . . . . . . . . . . . . . . . . . . 7-27
Rules for Naming to Avoid Conflicts . . . . . . . . . . . . . . . . . . 7-28
Object Arrays
8
Information About Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 8-2
Basic Knowledge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-2
xiii
Events — Sending and Responding to Messages
9
Learning to Use Events and Listeners . . . . . . . . . . . . . . . 9-2
What You Can Do With Events and Listeners . . . . . . . . . . 9-2
What You Need to Know to Use Events . . . . . . . . . . . . . . . 9-2
Customizing Event Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9-3
Observe Property Changes . . . . . . . . . . . . . . . . . . . . . . . . . . 9-6
xiv Contents
Summary of fcnview Class . . . . . . . . . . . . . . . . . . . . . . . . . . 9-37
Methods Inherited from Handle Class . . . . . . . . . . . . . . . . . 9-39
Using the fcneval and fcnview Classes . . . . . . . . . . . . . . . . 9-39
Implementing the UpdateGraph Event and Listener . . . . . 9-42
Implementing the PostSet Property Event and Listener . . 9-47
Enabling and Disabling the Listeners . . . . . . . . . . . . . . . . . 9-50
xv
Controlling Access to Class Members . . . . . . . . . . . . . . . . 10-24
Basic Knowledge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-24
Applications for Access Control Lists . . . . . . . . . . . . . . . . . . 10-25
Specify Access to Class Members . . . . . . . . . . . . . . . . . . . . . 10-26
Properties with Access Lists . . . . . . . . . . . . . . . . . . . . . . . . . 10-29
Methods with Access Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 10-29
Abstract Methods with Access Lists . . . . . . . . . . . . . . . . . . 10-33
xvi Contents
Class saveobj and loadobj Methods . . . . . . . . . . . . . . . . . . . 11-6
Processing Objects During Load . . . . . . . . . . . . . . . . . . . . . . 11-7
Save and Load Applications . . . . . . . . . . . . . . . . . . . . . . . . . 11-7
Enumerations
12
Defining Named Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-2
Kinds of Predefined Names . . . . . . . . . . . . . . . . . . . . . . . . . 12-2
Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-4
Basic Knowledge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-4
Using Enumeration Classes . . . . . . . . . . . . . . . . . . . . . . . . . 12-5
Defining Methods in Enumeration Classes . . . . . . . . . . . . . 12-9
Defining Properties in Enumeration Classes . . . . . . . . . . . 12-9
Array Expansion Operations . . . . . . . . . . . . . . . . . . . . . . . . 12-11
Constructor Calling Sequence . . . . . . . . . . . . . . . . . . . . . . . 12-11
Restrictions Applied to Enumeration Classes . . . . . . . . . . . 12-13
xvii
Techniques for Defining Enumerations . . . . . . . . . . . . . . . . 12-13
Constant Properties
13
Properties with Constant Values . . . . . . . . . . . . . . . . . . . . 13-2
Defining Named Constants . . . . . . . . . . . . . . . . . . . . . . . . . 13-2
Setting Constant Property Default . . . . . . . . . . . . . . . . . . . 13-4
xviii Contents
Information from Class Metadata
14
Use Class Metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-2
What Is Class Metadata? . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-2
xix
Converting Objects to Another Class . . . . . . . . . . . . . . . . 15-11
Why Implement a Converter . . . . . . . . . . . . . . . . . . . . . . . . 15-11
xx Contents
Designing Related Classes
17
Example — A Simple Class Hierarchy . . . . . . . . . . . . . . . 17-2
Shared and Specialized Properties . . . . . . . . . . . . . . . . . . . . 17-2
Designing a Class for Financial Assets . . . . . . . . . . . . . . . . 17-3
Displaying the Class Files . . . . . . . . . . . . . . . . . . . . . . . . . . 17-4
Summary of the DocAsset Class . . . . . . . . . . . . . . . . . . . . . . 17-4
The DocAsset Constructor Method . . . . . . . . . . . . . . . . . . . . 17-5
The DocAsset Display Method . . . . . . . . . . . . . . . . . . . . . . . 17-6
Designing a Class for Stock Assets . . . . . . . . . . . . . . . . . . . 17-7
Displaying the Class Files . . . . . . . . . . . . . . . . . . . . . . . . . . 17-7
Summary of the DocStock Class . . . . . . . . . . . . . . . . . . . . . 17-7
Designing a Class for Bond Assets . . . . . . . . . . . . . . . . . . . . 17-10
Displaying the Class Files . . . . . . . . . . . . . . . . . . . . . . . . . . 17-10
Summary of the DocBond Class . . . . . . . . . . . . . . . . . . . . . . 17-11
Designing a Class for Savings Assets . . . . . . . . . . . . . . . . . 17-15
Displaying the Class Files . . . . . . . . . . . . . . . . . . . . . . . . . . 17-15
Summary of the DocSavings Class . . . . . . . . . . . . . . . . . . . . 17-15
Index
xxi
xxii Contents
1
Using Object-Oriented
Design in MATLAB
Play demo
1-2
Begin Using Object-Oriented Programming
1-3
1 Using Object-Oriented Design in MATLAB®
The MATLAB language enables you to create programs using both procedural
and object-oriented techniques and to use objects and ordinary functions in
your programs.
1-4
Why Use Object-Oriented Design
After performing this analysis, you define classes that describe the objects
your application uses.
If the code executed in the try block generates an error, program control
passes to the code in the catch block. This behavior enables your program
to provide special error handling that is more appropriate to your particular
application. However, you must have enough information about the error to
take the appropriate action.
try
surf
catch ME
disp(ME.message)
end
Not enough input arguments.
1-5
1 Using Object-Oriented Design in MATLAB®
function requires input arguments). However, this is not all the information
available in the MException object.
You can list the public properties of an object with the properties function:
properties(ME)
Properties for class MException:
identifier
message
cause
stack
class(ME.message)
ans =
char
shows that the value of the message property is an array of class char (a text
string). The stack property contains a MATLAB struct:
ME.stack
ans =
file: [1x90 char]
name: 'surf'
line: 50
You can simply treat the property reference, ME.stack as a structure and
reference its fields:
ME.stack.file
ans =
D:\myMATLAB\matlab\toolbox\matlab\graph3d\surf.m
The file field of the struct contained in the stack property is a character
array:
1-6
Why Use Object-Oriented Design
class(ME.stack.file)
ans =
char
strcmp(ME.stack.name,'surf')
ans =
1
Object properties can contain any class of value and can even determine their
value dynamically. This provides more flexibility than a structure and is
easier to investigate than a cell array, which lacks fieldnames and requires
indexing into various cells using array dimensions.
To see what methods exist for MException objects, use the methods function:
methods(ME)
Methods for class MException:
Static methods:
1-7
1 Using Object-Oriented Design in MATLAB®
last
You can use these methods like any other MATLAB statement when there is
an MException object in the workspace. For example:
ME.getReport
ans =
Error using ==> surf
Not enough input arguments.
Objects often have methods that overload (redefined for the particular class of
the object) MATLAB functions (e.g., isequal, fieldnames, etc.). This enables
you to use objects just like other values. For example, MException objects
have an isequal method. This method enables you to compare these objects
in the same way you would compare variables containing doubles. If ME and
ME2 are MException objects, you can compare them with this statement:
isequal(ME,ME2)
However, what really happens in this case is MATLAB calls the MException
isequal method because you have passed MException objects to isequal.
Similarly, the eq method enables you to use the == operator with MException
objects:
ME == ME2
Of course, objects should support only those methods that make sense. For
example, it would probably not make sense to multiply MException objects so
the MException class does not implement methods to do so.
1-8
Why Use Object-Oriented Design
As functions become too large, you might break them into smaller functions
and pass data from one to the other. However, as the number of functions
becomes large, designing and managing the data passed to functions becomes
difficult and error prone. At this point, you should consider moving your
MATLAB programming tasks to object-oriented designs.
Identify Differences. You must also consider how each institution differs. A
mortgage company might provide only home mortgage loans. Therefore, the
loan operation might need be specialized for mortgage companies to provide
fixRateLoan and varRateLoan methods to accommodate two loan types.
You might also define a loan object, which would represent a particular loan.
It might need Amount, Rate, and Lender properties. When the loan is sold
to another institution, the Lender property could be changed, but all other
information is neatly packaged within the loan object.
1-9
1 Using Object-Oriented Design in MATLAB®
Hiding the internal state from general access leads to more robust code. If a
loan object’s Lender property can be changed only by the object’s newLender
method, then inadvertent access is less likely than if the loan data were
stored in a cell array where an indexing assignment statement could damage
the data.
Objects provide a number of useful features not available from structures and
cell arrays. For example, objects provide the ability to:
1-10
Why Use Object-Oriented Design
Reducing Redundancy
As the complexity of your program increases, the benefits of an object-oriented
design become more apparent. For example, suppose you need to implement
the following procedure as part of your application:
1 Check inputs
Step 1
function checkInputs()
% actual implementation
end
Step 2
function results = computeOnFirstArg()
% specify syntax only
end
Step 3
function transformResults()
1-11
1 Using Object-Oriented Design in MATLAB®
% actual implementation
end
Step 4
function out = checkOutputs()
% actual implementation
end
The code in the base class is not copied or modified, it is inherited by the
various classes you derive from the base class. This reduces the amount
of code to be tested, and isolates your program from changes to the basic
procedure.
For example, suppose you are creating an object to return information about
errors that occur during the execution of specific blocks of code. There might
be functions that return special types of information that you want to include
in an error report only when the error is generated by these functions.
The interface class, from which all error objects are derived, could specify that
all error objects must support a getReport method, but not specify how to
implement that method. The class of error object created for the functions
returning special information could implement its version of the getReport
method to handle the different data.
The requirement defined by the interface class is that all error objects be able
to display an error report. All programs that use this feature can rely on it
being implement in a consistent way.
1-12
Why Use Object-Oriented Design
All of the classes derived from the interface class can create a method called
getReport without any name conflicts because it is the class of the object that
determines which getReport is called.
Reducing Complexity
Objects reduce complexity by reducing what you need to know to use a
component or part of a system. This happens in a couple of ways:
n1 n2 n3
Properties Properties Properties
Data Data Data
Next Next Next
Prev Prev Prev
n2.Prev n2 n2.Next
To add a new node to the list, the following steps must occur. First disconnect
the nodes:
1-13
1 Using Object-Oriented Design in MATLAB®
n1 n2 n3
Properties Properties Properties
Next Next Next
Prev Prev Prev
5 Link new.Prev to n1
n1 n2 n3 n4
Properties Properties Properties Properties
Next Next Next Next
Prev Prev Prev Prev
The act of inserting a new node in an existing doubly linked list requires a
number of steps. Any application code using a data structure like this can
perform these operations. However, defining the linked list nodes as objects
enables all the operations like adding, deleting, and rearranging nodes to be
encapsulated in methods. The code that implements these operations can
be well tested, implemented in an optimal way, always up to date with the
current version of the class, and can even automatically update old-versions
of the objects when they are loaded from MAT-files.
1-14
Why Use Object-Oriented Design
The objects enforce the rules for how the nodes interact by implementing
methods to carry out these operations. A single addNode method would
perform all the steps listed above. This removes the responsibility for
enforcing constraints from the applications that use the objects. It also means
the application is less likely to generate errors in its own implementation of
the process.
This approach can reduce the complexity of your application code, provide
greater consistency across applications, and reduce testing and maintenance
requirements.
Fostering Modularity
As you decompose a system into objects (car –> engine –> fuel system –>
oxygen sensor), you form modules around natural boundaries. These objects
provide interfaces by which they interact with other modules (which might be
other objects or functions). Often the data and operations behind the interface
are hidden from other modules to segregate implementation from interface.
• Public — Any code can access this particular property or call this method.
• Protected — Only the object’s own methods and those of the object’s whose
class has been derived from this object’s class can access this property
or call this method.
• Private — Only the object’s own methods can access this property or call
this method.
1-15
1 Using Object-Oriented Design in MATLAB®
dialog windows, and then deriving the specific dialog classes from this base
class, you can:
Learning More
See “Classes in the MATLAB Language” on page 2-2 to learn more about
writing object-oriented MATLAB programs.
1-16
Class Diagram Notation
1-17
1 Using Object-Oriented Design in MATLAB®
BankAccount
Object Properties
AccountNumber
AccountBalance
Employee
Class Properties
Name
Address
Asset
is_a
Stock
FileReader FileID
(aggregation)
has_a
Car Tire
(composition)
1-18
2
Classes
In the MATLAB language, every value is assigned to a class. For example,
creating a variable with an assignment statement constructs a variable of
the appropriate class:
>> a = 7;
>> b = 'some string';
>> whos
Name Size Bytes Class
a 1x1 8 double
b 1x11 22 char
Basic commands like whos display the class of each value in the workspace.
This information helps MATLAB users recognize that some values are
characters and display as text while other values might be double, single,
or other types of numbers. Some variables can contain different classes
of values like cells.
User-Defined Classes
You can create your own MATLAB classes. For example, you could define a
class to represent polynomials. This class could define the operations typically
associated with MATLAB classes, like addition, subtraction, indexing,
displaying in the command window, and so on. However, these operations
would need to perform the equivalent of polynomial addition, polynomial
subtraction, and so on. For example, when you add two polynomial objects:
p1 + p2
2-2
Classes in the MATLAB® Language
the plus operation would know how to add polynomial objects because the
polynomial class defines this operation.
When you define a class, you overload special MATLAB functions (plus.m for
the addition operator) that are called by the MATLAB runtime when those
operations are applied to an object of your class.
2-3
2 MATLAB® Classes Overview
Classes
A class is a definition that specifies certain characteristics that all instances
of the class share. These characteristics are determined by the properties,
methods, and events that define the class and the values of attributes that
modify the behavior of each of these class components. Class definitions
describe how objects of the class are created and destroyed, what data the
objects contain, and how you can manipulate this data.
Class Hierarchies
It sometimes makes sense to define a new class in terms of existing classes.
This enables you to reuse the designs and techniques in a new class that
represents a similar entity. You accomplish this reuse by creating a subclass.
A subclass defines objects that are a subset of those defined by the superclass.
A subclass is more specific than its superclass and might add new properties,
methods, and events to those inherited from the superclass.
Mathematical sets can help illustrate the relationships among classes. In the
following diagram, the set of Positive Integers is a subset of the set of Integers
and a subset of Positive numbers. All three sets are subsets of Real numbers,
which is a subset of All Numbers.
2-4
Classes in the MATLAB® Language
All
Numbers
Integers
Positive
Integers
Positives
Reals
If the “is a” relationship holds, then it is likely you can define a new a class
from a class or classes that represent some more general case.
Reusing Solutions
Classes are usually organized into taxonomies to foster code reuse. For
example, if you define a class to implement an interface to the serial port of a
computer, it would probably be very similar to a class designed to implement
an interface to the parallel port. To reuse code, you could define a superclass
that contains everything that is common to the two types of ports, and then
2-5
2 MATLAB® Classes Overview
derive subclasses from the superclass in which you implement only what is
unique to each specific port. Then the subclasses would inherit all of the
common functionality from the superclass.
Objects
A class is like a template for the creation of a specific instance of the class.
This instance or object contains actual data for a particular entity that is
represented by the class. For example, an instance of a bank account class
is an object that represents a specific bank account, with an actual account
number and an actual balance. This object has built into it the ability to
perform operations defined by the class, such as making deposits to and
withdrawals from the account balance.
Objects are not just passive data containers. Objects actively manage the
data contained by allowing only certain operations to be performed, by hiding
data that does not need to be public, and by preventing external clients from
misusing data by performing operations for which the object was not designed.
Objects even control what happens when they are destroyed.
Encapsulating Information
An important aspect of objects is that you can write software that accesses
the information stored in the object via its properties and methods without
knowing anything about how that information is stored, or even whether it
is stored or calculated when queried. The object isolates code that accesses
the object from the internal implementation of methods and properties. You
can define classes that hide both data and operations from any methods that
are not part of the class. You can then implement whatever interface is most
appropriate for the intended use.
2-6
Classes in the MATLAB® Language
2-7
2 MATLAB® Classes Overview
2-8
Detailed Information and Examples
(Continued)
2-9
2 MATLAB® Classes Overview
(Continued)
2-10
Develop Classes — Typical Workflow
Formulating a Class
This example discusses the design and implementation of a simple class. To
design a class that represents a bank account, first determine the elements of
data and the operations that form your abstraction of a bank account. For
example, a bank account has:
• An account number
• An account balance
• A current status (open, closed, etc.)
• Deposit money
• Withdraw money
You might also want the bank account to send a notice if the balance is too
low and an attempt is made to withdraw money. When this event occurs, the
bank account can broadcast a notice to other entities that are designed to
listen for these notices, such as an account manager program. The account
manager program can take action in response to the event.
2-11
2 MATLAB® Classes Overview
The first two properties contain information that only the class can change, so
the SetAccess attribute is set to private (only class methods can set these
values).
2-12
Develop Classes — Typical Workflow
To define an event, specify a name within an events block. Trigger the event
by a call to the notify handle class method. Because InsufficientsFunds
is not a predefined event, you can name it with any string and trigger it
with any action.
BankAccount class
AccountManager class
You can open both class files in your editor by clicking this link:
Open in editor
2-13
2 MATLAB® Classes Overview
Class Definition
2-14
Develop Classes — Typical Workflow
end
end % withdraw
end % methods
end % classdef
Class Definition
classdef AccountManager
methods (Static)
function assignStatus(BA)
if BA.AccountBalance < 0
if BA.AccountBalance < -200
BA.AccountStatus = 'closed';
else
BA.AccountStatus = 'overdrawn';
end
end
end
function addAccount(BA)
% Call the handle addlistener method
% Object BA is a handle class
addlistener(BA, 'InsufficientFunds', ...
@(src, evnt)AccountManager.assignStatus(src));
end
end
end
2-15
2 MATLAB® Classes Overview
BA = BankAccount(1234567,500);
BA.AccountNumber
ans =
1234567
BA.AccountBalance
ans =
500
BA.AccountStatus
ans =
open
BA.withdraw(600)
BA.AccountBalance
ans =
-100
BA.AccountStatus
ans =
overdrawn
BA.withdraw(200)
BA.AccountBalance
ans =
-300
BA.AccountStatus
ans =
closed
Now the AccountStatus has been set to closed by the listener and further
attempts to make withdrawals are blocked:
2-16
Develop Classes — Typical Workflow
BA.withdraw(100)
Account 1234567 has been closed
BA.deposit(700)
BA.AccountStatus
ans =
open
BA.withdraw(100)
BA.AccountBalance
ans =
300
2-17
2 MATLAB® Classes Overview
Flexible Workflow
The MATLAB language does not require you to define classes for all the code
you write. You can use objects along with ordinary functions. This section
illustrates the use of an object that implements the basic task of writing text
to a file. Then this object is used in a function to write a text file template
for a class definition.
• Hiding private data — The caller does not need to manage the file identifier.
• Ensuring only one file identifier is in use at any time — Copies of handle
objects reference the same file identifier as the original.
• Providing automatic file closing when the object is deleted — the object’s
delete method takes care of cleanup without needing to be called explicitly.
2-18
Use Custom Objects in Functions
This class is derived from the handle class so that a Filewriter object is
a handle object. All copies of handle objects reference the same internal
data so there will be only one file identifier in use, even if you make copies
of the object. Also, handle classes define a delete method which is called
automatically when a handle object is destroyed. This example overrides
the delete method to close the file before the file identifier is lost and the
file is left open.
methods
% Construct an object and
% save the file ID
function obj = Filewriter(filename)
obj.FileID = fopen(filename,'a');
end
function writeToFile(obj,text_str)
fprintf(obj.FileID,'%s\n',text_str);
end
% Delete methods are always called before a object
% of the class is destroyed
function delete(obj)
fclose(obj.FileID);
end
end % methods
end % class
>> fw = Filewriter('mynewclass.m');
2-19
2 MATLAB® Classes Overview
This example creates only one simple class template, but another version
might accept a cell array of attribute name/value pairs, method names, and
so on.
function writeClassFile(classname,superclass)
% Use a Filewriter object to write text to a file
fw = Filewriter([classname '.m']);
if nargin > 1
fw.writeToFile(['classdef ' classname ' < ' superclass])
else
fw.writeToFile(['classdef ' classname])
end
fw.writeToFile(' properties ')
fw.writeToFile(' ')
fw.writeToFile(' end % properties')
fw.writeToFile(' ')
fw.writeToFile(' methods ')
fw.writeToFile([' function obj = ' classname '()'])
fw.writeToFile(' ')
fw.writeToFile(' end')
fw.writeToFile(' end % methods')
fw.writeToFile('end % classdef')
delete(fw) % Delete object, which closes file
end
To create a class file template, call writeClassFile with the name of the new
class and its superclass. Use the type command to display the contents of
the file:
2-20
Use Custom Objects in Functions
>> writeClassFile('myNewClass','handle')
>> type myNewClass
end % properties
methods
function obj = myNewClass()
end
end % methods
end % classdef
2-21
2 MATLAB® Classes Overview
Open class definition file in the MATLAB editor. — Use this link if you want
to save and modify your version of the class.
2-22
Example — Representing Structured Data
Data Description
Material Character string identifying the type of
material tested
SampleNumber Number of a particular test sample
Stress Vector of doubles representing the stress
applied to the sample during the test.
Strain Vector of doubles representing the strain at
the corresponding values of the applied stress.
Modulus Double defining an elastic modulus of the
material under test, which is calculated from
the stress and strain data
Note that this example begins with a simple implementation of the class
and builds on this implementation to illustrate how features enhance the
usefulness of the class.
2-23
2 MATLAB® Classes Overview
classdef TensileData
properties
Material = '';
SampleNumber = 0;
Stress
Strain
Modulus = 0;
end
end
td = TensileData;
td.Material = 'Carbon Steel';
td.SampleNumber = 001;
td.Stress = [2e4 4e4 6e4 8e4];
td.Strain = [.12 .20 .31 .40];
td.Modulus = mean(td.Stress./td.Strain);
>>td.Modulis = ...
would simply add a new field to a structure array, but returns an error
when td is an instance of the TensileData class.
• A class is easy to reuse. Once you have defined the class, you can easily
extend it with subclasses that add new properties.
2-24
Example — Representing Structured Data
• A class is easy to identify. A class has a name so that you can identify
objects with the whos and class functions and the Workspace browser. The
class name makes it easy to refer to records with a meaningful name.
• A class can validate individual field values when assigned, including class
or value.
• A class can restrict access to fields, for example, allowing a particular field
to be read, but not changed.
The next section describes how to add type checking and how to restrict
property access in the TensileData class.
classdef TensileData
properties
Material = 'carbon steel';
SampleNumber = 0;
Stress
Strain
Modulus
end % properties
methods
function obj = set.Material(obj,material)
if ~(strcmpi(material,'aluminum') ||...
strcmpi(material,'stainless steel') ||...
strcmpi(material,'carbon steel'))
error('Material must be aluminum, stainless steel, or carbon steel')
end
2-25
2 MATLAB® Classes Overview
obj.Material = material;
end % set.Material
end% methods
end% classdef
When an attempt is made to set the Material property, the MATLAB runtime
passes the object and the specified value to the property’s set.Material
function (the obj and the material input arguments). In this case, if the
value does not match the acceptable values, the function returns an error.
Otherwise, the specified value is used to set the property. Only the set
method can directly access the property in the object (without calling the
property set method).
For example:
td = TensileData;
td.Material = 'composite';
Error using TensileData.TensileData>TensileData.set.Material
Material must be aluminum, stainless steel, or carbon steel
function td = TensileData(material,samplenum,stress,strain)
if nargin > 0 % Support calling with 0 arguments
td.Material = material;
td.SampleNumber = samplenum;
td.Stress = stress;
td.Strain = strain;
end
end % TensileData
2-26
Example — Representing Structured Data
Using the constructor, you can create a TensileData object fully populated
with data using the following statement:
Calculating Modulus
Note that the constructor function does not have an input argument for the
value of the Modulus property. This is because the value of the Modulus:
Therefore, it is better to calculate the value of the Modulus property only when
its value is requested. You can do this with a property get access method,
which is described in the next section.
Also, because the get.Modulus method calculates and returns the value of
the Modulus property, you should set the property’s SetAccess attribute
to private.
2-27
2 MATLAB® Classes Overview
methods
function modulus = get.Modulus(obj)
ind = find(obj.Strain > 0); % Find nonzero strain
modulus = mean(obj.Stress(ind)./obj.Strain(ind));
end % Modulus get method
end % methods
This function simply calculates the average ratio of stress to strain data after
eliminating zeros in the denominator data.
The MATLAB runtime calls the get.Modulus method when the property is
queried. For example,
methods
function obj = set.Modulus(obj,~)
fprintf('%s%d\n','Modulus is: ',obj.Modulus)
error('You cannot set Modulus explicitly');
end % Modulus get function
2-28
Example — Representing Structured Data
Strain property data since these properties contain raw data that is not
easily viewed in the command window. The plot method (described in the
next section) provides a better way to display stress and strain data.
The disp method uses fprintf to display formatted text in the command
window:
methods
function disp(td)
fprintf(1,'Material: %s\nSample Number: %g\nModulus: %1.5g\n',...
td.Material,td.SampleNumber,td.Modulus);
end % disp
end % methods
The TensileData plot method creates a linear graph of the stress versus
strain data and adds a title and axis labels to produce a standardized graph
for the tensile data records:
function plot(td,varargin)
plot(td.Strain,td.Stress,varargin{:})
title(['Stress/Strain plot for Sample',...
num2str(td.SampleNumber)])
ylabel('Stress (psi)')
xlabel('Strain %')
end % plot
The variable list of arguments that follow are passed directly to the built-in
plot function from within the method. This enables the TensileData plot
method to behave like the built-in plot function, which allows you to pass
line specifier arguments or property name/value pairs along with the data.
2-29
2 MATLAB® Classes Overview
2-30
Example — Implementing Linked Lists
Open class definition file in the MATLAB editor. — Use this link if you want
to save and modify your version of the class.
To use the class, create a folder named @dlnode and save dlnode.m to
this folder. The parent folder of @dlnode must be on the MATLAB path.
Alternatively, save dlnode.m to a path folder.
Encapsulation
This example shows how classes encapsulate the internal structure used to
implement the class design (a doubly linked lists). Encapsulation conceals the
internal workings of the class from other code and provides a stable interface
to programs that use this class. It also prevents client code from misusing the
class because only class methods can access certain class data.
2-31
2 MATLAB® Classes Overview
Class methods define the operations that you can perform on nodes of this
class. These methods hide the potentially confusing process of inserting and
removing nodes, while at the same time providing an interface that performs
operations simply:
See “Defining the dlnode Class” on page 2-35 for the implementation details.
• Data array
• Link to the next node
• Link to the previous node
Class Properties
The dlnode class implements each node as a handle object with three
properties:
2-32
Example — Implementing Linked Lists
This diagram shows a three-node list n1, n2, and n3. It also shows how the
nodes reference the next and previous nodes.
n1 n2 n3
Properties Properties Properties
Data Data Data
Next Next Next
Prev Prev Prev
n2.Prev n2 n2.Next
Class Methods
The dlnode class implements the following methods:
• dlnode — Constructs a node and assigns the value passed as input to the
Data property
• insertAfter — Inserts this node after the specified node
• insertBefore — Inserts this node before the specified node
• disconnect — Removes this node from the list
• disp — Overloads default disp function so that the Data property displays
on the command line for scalar objects and the dimension of the array
displays for object arrays
• delete — Removes this node from the list before it is destroyed
2-33
2 MATLAB® Classes Overview
n1=dlnode(1);
n2=dlnode(2);
n3=dlnode(3);
You build these nodes into a doubly linked list using the class methods:
n2.insertAfter(n1)
n3.insertAfter(n2)
Now the three nodes are linked. The dlnode disp method returns the data for
the node referred to:
n1.Next % Points to n2
ans =
Doubly-linked list node with data:
2
n2.Next.Prev % Points back to n2
ans =
Doubly-linked list node with data:
2
n1.Next.Next % Points to n3
ans =
Doubly-linked list node with data:
3
n3.Prev.Prev % Points to n1
ans =
Doubly-linked list node with data:
1
n1.Next == n2
n2.Prev == n1
2-34
Example — Implementing Linked Lists
x = n2;
x == n1.Next
x.Prev == n1
But each instance of a node is unique so there is only one node in the list
that can satisfy the conditions of being equal to n1.Next and having a Prev
property that contains a handle to n1. Therefore, x must point to the same
node as n2.
This means there has to be a way for multiple variables to refer to the same
object. The MATLAB handle class provides a means for both x and n2 to refer
to the same node. All instances of the handle class are handles that exhibit
the copy behavior described previously.
Notice that the handle class defines the eq method (use methods('handle')
to list the handle class methods), which enables the use of the == operator
with all handle objects.
See “Comparing Handle and Value Classes” on page 5-2 for more information
on kinds of MATLAB classes.
See “The Handle Superclass” on page 5-11 for more information about the
handle class.
n1 = dlnode(1);
n2 = dlnode(2);
n3 = dlnode(3);
n2.insertAfter(n1)
n3.insertAfter(n2)
2-35
2 MATLAB® Classes Overview
Class Properties
The dlnode class is itself a handle class because it is derived from the handle
class. Note that only class methods can set the Next and Prev properties
(SetAccess = private). Using private set access prevents client code from
performing any incorrect operation with these properties. The dlnode class
defines methods that perform all the operations that are allowed on these
nodes. Here are the property definition blocks:
When you add the node to a list, the class methods that perform the insertion
set the Next and Prev properties. See “Inserting Nodes” on page 2-38.
Disconnecting Nodes
The disconnect method removes a node from a list and repairs the list by
reconnecting the appropriate nodes. The insertBefore and insertAfter
methods always call disconnect on the node to insert before attempting to
connect it to a linked list. This ensures the node is in a known state before
assigning it to the Next or Prev property:
function disconnect(node)
if ~isscalar(node)
2-36
Example — Implementing Linked Lists
For example, suppose you remove n2 from the three-node list discussed above
(n1 n2 n3):
n2.disconnect;
disconnect removes n2 from the list and repairs the list with the following
steps:
n1 = n2.Prev;
n3 = n2.Next;
if n1 exists, then
n1.Next = n3;
if n3 exists, then
n3.Prev = n1
Now the list is rejoined because n1 connects to n3 and n3 connects to n1. The
final step is to ensure that n2.Next and n2.Prev are both empty (i.e., n2
is not connected):
2-37
2 MATLAB® Classes Overview
Inserting Nodes
There are two methods for inserting nodes into the list—insertAfter and
insertBefore. These methods perform similar operations, so this section
describes only insertAfter in detail.
methods
function insertAfter(newNode,nodeBefore)
disconnect(newNode);
newNode.Next = nodeBefore.Next;
newNode.Prev = nodeBefore;
if ~isempty(nodeBefore.Next)
nodeBefore.Next.Prev = newNode;
end
nodeBefore.Next = newNode;
end
For example, suppose you want to insert a new node, nnew, after an existing
node, n1, in a list containing n1 n2.
nnew = dlnode(rand(3));
Next, call insertAfter to insert nnew into the list after n1:
nnew.insertAfter(n1)
The insertAfter method performs the following steps to insert nnew in the
list between n1 and n2:
2-38
Example — Implementing Linked Lists
n1.Next.Prev = nnew;
% n1.Next is now set to nnew
n1.Next = nnew;
function disp(node)
% DISP Display a link node
if (isscalar(node))
disp('Doubly-linked list node with data:')
disp(node.Data)
else
% If node is an object array, display dimensions
dims = size(node);
ndims = length(dims);
% Counting down in for loop avoids need to preallocate dimcell
for k = ndims-1:-1:1
dimcell{k} = [num2str(dims(k)) 'x'];
end
dimstr = [dimcell{:} num2str(dims(ndims))];
disp([dimstr ' array of doubly-linked list nodes']);
end
end
2-39
2 MATLAB® Classes Overview
The dlnode class defines a delete method because each dlnode object is a
node in a doubly linked list. If a node object is going to be destroyed, the
delete method must disconnect the node and repair the list before allowing
MATLAB to destroy the node.
The disconnect method already performs the necessary steps, so the delete
method can simply call disconnect:
function delete(node)
disconnect(node);
end
Rather than copying the code used to implement the dlnode class, and then
expanding upon it, you can derive a new class from dlnode (i.e., subclass
dlnode) to create a class that has all the features of dlnode and more. And
because dlnode is a handle class, this new class is a handle class too.
To use the class, create a folder named @NamedNode and save NamedNode.m to
this folder. The parent folder of @NamedNode.m must be on the MATLAB path.
Alternatively, save NamedNode.m to a path folder.
The following class definition shows how to derive the NamedNode class from
the dlnode class:
2-40
Example — Implementing Linked Lists
The NamedNode class adds a Name property to store the node name and extends
the disp method defined in the dlnode class.
The constructor calls the class constructor for the dlnode class, and then
assigns a value to the Name property. The NamedNode class defines default
values for the properties for cases when MATLAB calls the constructor with
no arguments.
Now use the insert methods inherited from dlnode to build the list:
n(2).insertAfter(n(1))
2-41
2 MATLAB® Classes Overview
n(3).insertAfter(n(2))
A single node displays its name and data when you query its properties:
>> n(1).Next
ans =
Node Name: Second Node
Doubly-linked list node with data:
200
>> n(1).Next.Next
ans =
Node Name: Third Node
Doubly-linked list node with data:
300
>> n(3).Prev.Prev
ans =
Node Name: First Node
Doubly-linked list node with data:
100
If you display an array of nodes, the NamedNode disp method displays only
the dimensions of the array:
>> n
n =
1x3 array of doubly-linked list nodes
2-42
Example — Class for Graphing Functions
The class block is the code that starts with the classdef key word and
terminates with the end key word. The following example illustrated a simple
class definition that uses:
• Handle class
• Property set and get functions
• Use of a delete method for the handle object
• Static method syntax
Open class definition file in the MATLAB editor. — Use this link if you want
to save and modify your own version of the class.
2-43
2 MATLAB® Classes Overview
methods
function obj = topo(fnc,limits)
% Constructor assigns property values
obj.FofXY = fnc;
obj.Lm = limits;
end % topo
function set.Lm(obj,lim)
% Lm property set function
if ~(lim(1) < lim(2))
error('Limits must be monotonically increasing')
else
obj.Lm = lim;
end
end % set.Lm
function surflight(obj)
% Graph function as surface
obj.FigHandle = figure;
surfc(obj.Data.X,obj.Data.Y,obj.Data.Matrix,...
'FaceColor',[.8 .8 0],'EdgeColor',[0 .2 0],...
'FaceLighting','phong');
2-44
Example — Class for Graphing Functions
function delete(obj)
% Delete the figure
h = obj.FigHandle;
if ishandle(h)
delete(h);
else
return
end
end % delete
end % methods
2-45
2 MATLAB® Classes Overview
The class surflight method uses the object to create a graph of the function.
The actual data required to create the graph is not stored. When the
surflight method accesses the Data property, the property’s get function
performs the evaluation and returns the data in the Data property structure
fields. This data is then plotted. The advantage of not storing the data is
the reduced size of the object.
Now suppose you change the FofXY property so that it contains a function
handle that points to another function:
2-46
Example — Class for Graphing Functions
Because a is a copy of the handle object tobj, changes to the data referenced
by tobj also change the data referenced by a.
2-47
2 MATLAB® Classes Overview
2-48
3
Class Definition—Syntax
Reference
pathfolder
ClassNameA.m Contains classdef and methods for ClassNameA
ClassNameB.m Contains classdef and methods for ClassNameB
ClassNameC.m Contains classdef and methods for ClassNameC
...
ordinaryFunction.m A function on the path
See “Methods in Separate Files” on page 7-8 for more information on using
multiple files to define classes.
3-2
Saving Class Files
pathfolder
@ClassNameA
ClassNameA.m Contains classdef
classMethod.m Class method in separate file
ClassNameB.m Contains entire class definition
A path folder can contain classes defined in both @-folders and single files
without an @-folder.
3-3
3 Class Definition—Syntax Reference
pathfolder
+packagefld1
@ClassNameA
ClassNameA.m Contains classdef
classMethod.m Class method in separate file
ClassNameB.m Contains entire class definition
+packagefld2 Defines a new name space
packageFunction.m
ClassNameA.m
ClassNameB.m
See “Methods In Separate Files” on page 3-16 for the syntax used to define
methods external to the classdef file.
3-4
Class Components
Class Components
In this section...
“Class Building Blocks – Defining Class Members” on page 3-5
“More In Depth Information” on page 3-6
• classdef block contains the class definition within a file that starts with the
classdef keyword and terminates with the end keyword. See “Classdef
Block” on page 3-8 for more syntax information.
• properties block (one for each unique set of attribute specifications) contains
property definitions, including optional initial values. The properties block
starts with the properties keyword and terminates with the end keyword.
See “Specifying Properties” on page 3-10 for more syntax information.
classdef ClassName
properties (PropertyAttributes)
...
end
...
end
• methods block (one for each unique set of attribute specifications) contains
function definitions for the class methods. The methods block starts with
the methods keyword and terminates with the end keyword. See “The
Methods Block” on page 3-15 for more syntax information.
classdef ClassName
methods (MethodAttributes)
...
3-5
3 Class Definition—Syntax Reference
end
...
end
• events block (one for each unique set of attribute specifications) contains
the names of events that this class declares. The events block starts with
the events keyword and terminates with the end keyword. See “Specifying
Events” on page 3-21 for more syntax information.
classdef ClassName
events (EventAttributes)
...
end
...
end
3-6
Class Components
“Events and Listeners — Syntax and Techniques” on page 9-18 for information
on the use of events.
3-7
3 Class Definition—Syntax Reference
Classdef Block
In this section...
“Specifying Attributes and Superclasses” on page 3-8
“Assigning Class Attributes” on page 3-8
“Specifying Superclasses” on page 3-9
• Class attributes
• Superclasses
The classdef block contains the properties, methods, and events subblocks.
classdef class_name
...
end
See “Class Attributes” on page 4-6 for a list of attributes and a discussion of
the behaviors they control.
3-8
Classdef Block
Specifying Superclasses
To define a class in terms of one or more other classes by specifying the
superclasses on the classdef line:
See “Creating Subclasses — Syntax and Techniques” on page 10-7 for more
information.
3-9
3 Class Definition—Syntax Reference
Specifying Properties
In this section...
“What You Can Define” on page 3-10
“How to Initialize Property Values” on page 3-10
“Defining Default Values” on page 3-11
“Assigning Property Values from Within the Constructor” on page 3-11
“Initializing Properties to Unique Values” on page 3-12
“Property Attributes” on page 3-12
“Property Access Methods” on page 3-13
“Referencing Object Properties Using Variables” on page 3-13
Note Always use case sensitive property names in your MATLAB code.
3-10
Specifying Properties
classdef class_name
properties
PropertyName % No default value assigned
PropertyName = 'some text';
PropertyName = sin(pi/12); % Expression returns default value
end
end
Evaluation of property default values occurs only when the value is first
needed, and only once when MATLAB first initializes the class. MATLAB
does not reevaluate the expression each time you create a class instance.
MATLAB sets property values not specified in the class definition to empty
([]).
classdef MyClass
properties
PropertyOne
end
methods
function obj = MyClass(intval)
obj.PropertyOne = intval;
end
end
end
3-11
3 Class Definition—Syntax Reference
When you assign an object property from the class constructor, MATLAB
evaluates the assignment statement for each instance created. Assign
property values in the constructor if you want each object to contain a unique
instance of a handle object.
Property Attributes
All properties have attributes that modify certain aspects of the property’s
behavior. Specified attributes apply to all properties in a particular properties
block. For example:
classdef class_name
properties
PropertyName % No default value assigned
PropertyName = sin(pi/12); % Expression returns default value
end
properties (SetAccess = private, GetAccess = private)
Stress
Strain
end
end
In this case, only methods in the same class definition can modify and
query the Stress and Strain properties. This restriction exists because the
class defines these properties in a properties block with SetAccess and
GetAccess attributes set to private.
3-12
Specifying Properties
methods
function value = get.PropertyName(object)
...
end
MATLAB does not call the property set access method when assigning the
default value specified in the property’s definition block.
If a handle class defines the property, the set access method does not need to
return the modified object.
object.(PropertyNameVar)
PropName = 'KeyType';
3-13
3 Class Definition—Syntax Reference
function o = getPropValue(obj,PropName)
...
o = obj.(PropName); % Returns value of KeyType property
...
end
3-14
Specifying Methods and Functions
classdef ClassName
methods
function obj = ClassName(arg1,arg2,...)
obj.Prop1 = arg1;
...
end
function normal_method(obj,arg1,...)
...
end
end
methods (Static = true)
function static_method(arg1,...)
...
end
end
end
3-15
3 Class Definition—Syntax Reference
See “Determining Which Method Is Invoked” on page 7-9 for more information.
Note Always use case sensitive method names in your MATLAB code.
For example, the folder @MyClass must contain the file MyClass.m (which
contains the classdef block) and can contain other methods and function
defined in files having a .m extension. For example, the folder @MyClass
might contain a number of files:
@MyClass/MyClass.m
@MyClass/subsref.m
@MyClass/subsasgn.m
@MyClass/horzcat.m
@MyClass/vertcat.m
@MyClass/myFunc.m
3-16
Specifying Methods and Functions
• Class constructor
• Delete method
• All functions that use dots in their names, including:
- Converter methods that convert to classes contained in packages, which
must use the package name as part of the class name.
- Property set and get access methods (“Property Access Methods” on page
6-14)
classdef ClassName
% In a methods block, set the method attributes
% and add the function signature
methods (Access = private)
output = myFunc(obj,arg1,arg2)
end
end
3-17
3 Class Definition—Syntax Reference
Include the method signature in the file with the classdef block only if you
want to specify attributes for that method. Otherwise, you can implement the
method as a function in a separate file in the @-folder.
classdef ClassName
...
methods (Static)
output = staticFunc1(arg1,arg2)
staticFunc2
end
You would then define the functions in separate files using the same function
signature. For example:
For an Example
The example, “Example — Using Events to Update Graphs” on page 9-34
uses multiple files for class definition.
3-18
Specifying Methods and Functions
Subfunctions in classdef files are useful for utility functions that you use
only within that file. These functions can take or return arguments that
are instances of the class but, it is not necessary, as in the case of ordinary
methods. For example, the following code defines myUtilityFcn outside the
classdef block:
classdef MyClass
properties
PropName
end
methods
function obj = MyClass(arg1)
obj.PropName = arg1;
end
end % methods
end % classdef
function myUtilityFcn
...
end
You also can create package functions, which require you to use the package
name when calling these functions. See “Create a Namespace with Packages”
on page 4-21 for more information on packages
3-19
3 Class Definition—Syntax Reference
You can also overload MATLAB arithmetic, logical, relational, and indexing
operators by defining class methods with the appropriate names. See
“Implementing Operators for Your Class” on page 15-35 for a list of the
functions to overload.
See the handle class for a list of operations defined for that class, which are
inherited by all classes deriving from handle.
3-20
Events and Listeners
Specifying Events
To define an event, you declare a name for the event in the events block.
Then one of the class methods triggers the event using the notify method,
which is method inherited from the handle class. Only classes derived from
the handle class can define events.
3-21
3 Class Definition—Syntax Reference
addlistener(event_obj,'StateChange',@myCallback)
3-22
Specifying Attributes
Specifying Attributes
In this section...
“Attribute Syntax” on page 3-23
“Attribute Descriptions” on page 3-23
“Specifying Attribute Values” on page 3-24
“Simpler Syntax for true/false Attributes” on page 3-24
Attribute Syntax
For a quick reference to all attributes, see Attribute Tables.
Attribute Descriptions
For lists of supported attributes, see:
3-23
3 Class Definition—Syntax Reference
When specifying class attributes, place the attribute list directly after the
classdef keyword:
methods (Static)
...
end
3-24
Specifying Attributes
methods (~Static)
...
end
All attributes that take a logical value (that is, true or false) have a default
value of false. Therefore, specify an attribute only if you want to set it to
true.
3-25
3 Class Definition—Syntax Reference
3-26
Calling Superclass Methods on Subclass Objects
obj = obj@MySuperClass(SuperClassArguments);
3-27
3 Class Definition—Syntax Reference
superMethod@MySuperClass(obj)
Superclass name
3-28
Representative Class Code
properties (Dependent)
JobTitle
end
properties (Transient)
OfficeNumber
end
events
BackgroundAlert
end
methods
function Eobj = Employee(name)
% Method help here
Eobj.Name = name;
Eobj.EmpNumber = employee.getEmpNumber;
end
3-29
3 Class Definition—Syntax Reference
if result == false
notify(obj,'BackgroundAlert');
end
end
function set.OfficeNumber(obj,setvalue)
if isInUse(setvalue)
error('Not available')
else
obj.OfficeNumber = setvalue;
end
end
end
methods (Static)
function num = getEmpNumber
num = queryDB('LastEmpNumber') + 1;
end
end
end
3-30
Understanding MATLAB® Code Analyzer Warnings
properties
EmployeeName
end
methods
function someMethod(obj,n)
EmployeeName = n;
end
end
While the previous function is legal MATLAB code, it results in Code Analyzer
warnings for two reasons:
3-31
3 Class Definition—Syntax Reference
obj.EmployeeName = n;
function EN = someMethod(obj)
EN = EmployeeName;
end
The Code Analyzer returns only one warning, suggesting that you might
actually want to refer to the EmployeeName property.
EN = obj.EmployeeName;
The Code Analyzer does not warn when a variable name is the same as a
property name when the variable is:
In these particular cases, the Code Analyzer does not warn you that you are
using a variable name that is also a property name. Therefore, a coding error
like the following:
3-32
Understanding MATLAB® Code Analyzer Warnings
3-33
3 Class Definition—Syntax Reference
Function Description
class Return class of object.
enumeration Display class enumeration members and names.
events List event names defined by the class.
methods List methods implemented by the class.
methodsview List methods in separate window.
properties List class property names.
Function Description
isa Determine whether an argument is an object of specific
class.
isequal Determine if two objects are equal, which means
both objects are of the same class and size and their
corresponding property values are equal.
isobject Determine whether input is a MATLAB object
3-34
Functions Used with Objects
h1 == h2
h1 = BasicHandle('Handle Object');
h2 = h1;
switch h1
case h2
disp('h2 is selected')
otherwise
disp('h2 not selected')
3-35
3 Class Definition—Syntax Reference
end
h2 is selected
Behave Like a Built-in Type. Some MATLAB functions also use the built-in
== operator in their implementation. Therefore, your implementation of eq
should be replaceable with the built-in eq to enable objects of your class work
like built-in types in MATLAB code.
3-36
Functions Used with Objects
both objects. In addition, eq works with arrays the same way as the built-in
eq. For the following expression:
obj1 == obj2
classdef SwitchOnVer
properties
Version
end
methods
function obj = SwitchOnVer(ver)
if nargin > 0
obj.Version = ver;
end
end
function bol = eq(obj1,obj2)
if ~strcmp(class(obj1),class(obj2))
error('Objects are not of the same class')
end
s1 = numel(obj1);
s2 = numel(obj2);
if s1 == s2
bol = false(size(obj1));
for k=1:s1
if obj1(k).Version == obj2(k).Version
bol(k) = true;
else
3-37
3 Class Definition—Syntax Reference
bol(k) = false;
end
end
elseif s1 == 1
bol = scalarExpEq(obj2,obj1);
elseif s2 == 1
bol = scalarExpEq(obj1,obj2);
else
error('Dimension missmatch')
end
function ret = scalarExpEq(ns,s)
% ns is nonscalar array
% s is scalar array
ret = false(size(ns));
n = numel(ns);
for kk=1:n
if ns(kk).Version == s.Version
ret(kk) = true;
else
ret(kk) = false;
end
end
end
end
end
end
...
if isscalar(objIn)
switch(objIn)
case ov1
3-38
Functions Used with Objects
3-39
3 Class Definition—Syntax Reference
+PackFld1/+PackFld2/@myclass/myclass.m
To open myclass.m in the MATLAB editor, you could reference the file using
dot-separated package names:
edit PackFld1.PackFld2.myclass
edit +PackFld1/+PackFld2/@myclass/myclass
edit +PackFld1/+PackFld2/myclass
edit PackFld1.PackFld2.packFunction
edit +PackFld1/+PackFld2/packFunction
To refer to a function defined in its own file inside of a class @-folder, use:
edit +PackFld1/+PackFld2/@myclass/myMethod
See “Modifying and Reloading Classes” on page 3-41 for information about
clearing class.
3-40
Modifying and Reloading Classes
Clear Classes
When you issue the clear classes command, MATLAB clears:
3-41
3 Class Definition—Syntax Reference
MATLAB issues a warning stating that it cannot apply your changes because
it cannot clear the class. Clear the instance of MyClass before calling clear
classes. For example, you can use the close all command to remove the
object or reset the UserData property to another value:
Here are some suggestions for finding and clearing class instances:
3-42
Modifying and Reloading Classes
3-43
3 Class Definition—Syntax Reference
3-44
Compatibility with Previous Versions
Private Methods
You do not need to define private folders in class folders in Version 7.6. You
can set the method’s Access attribute to private instead.
function s = Stock(description,num_shares,share_price)
s.NumShares = num_shares;
s.SharePrice = share_price;
% Construct Asset object
a = Asset(description,'stock',share_price*num_shares);
% Use the class function to define the stock object
s = class(s,'Stock',a);
Write the same Stock class constructor as shown here. Define the inheritance
on the classdef line and define the constructor within a methods block.
function s = Stock(description,num_shares,share_price)
% Call superclass constructor to pass arguments
3-45
3 Class Definition—Syntax Reference
s = s@Asset(description,'stock',share_price*num_shares);
s.NumShares = num_shares;
s.SharePrice = share_price;
end % End of function
The following sections reimplement examples using the latest syntax. The
original MATLAB Classes and Objects documentation implemented these
same examples and provide a comparison of old and new syntax.
3-46
Compatibility with Previous Versions
Obsolete Documentation
Documentation for MATLAB Classes and Objects before Version 7.6 is
available here.
3-47
3 Class Definition—Syntax Reference
Public Properties
Unlike fields in C++ or the Java language, you can use MATLAB properties to
define a public interface separate from the implementation of data storage.
You can provide public access to properties because you can define set and
get access methods that execute automatically when assigning or querying
property values. For example, the following statement:
myobj.Material = 'plastic';
assigns the string plastic to the Material property of myobj. Before making
the actual assignment, myobj executes a method called set.Material
(assuming the class of myobj defines this method), which can perform any
necessary operations. See “Property Access Methods” on page 6-14 for more
information on property access methods.
You can also control access to properties by setting attributes, which enable
public, protected , or private access. See “Property Attributes” on page 6-8
for a full list of property attributes.
No Implicit Parameters
In some languages, one object parameter to a method is always implicit. In
MATLAB, objects are explicit parameters to the methods that act on them.
3-48
Comparing MATLAB® with Other OO Languages
Dispatching
In MATLAB classes, method dispatching is not based on method signature,
as it is in C++ and Java code. When the argument list contains objects of
equal precedence, MATLAB software uses the left-most object to select the
method to call. However, if the class of that argument is superior to the
other arguments, MATLAB can dispatch to a method of an argument in any
position within an argument list.
Other Differences
In MATLAB classes, there is no equivalent to C++ templates or Java generics.
However, MATLAB is weakly typed and it is possible to write functions and
classes that work with different types of data.
Modifying Objects
MATLAB classes can define public properties, which you can modify by
explicitly assigning values to those properties on a given instance of the
class. However, only classes derived from the handle class exhibit reference
behavior. Modifying a property value on an instance of a value classes (classes
not derived from handle), changes the value only within the context in which
the modification is made.
3-49
3 Class Definition—Syntax Reference
See “Comparing Handle and Value Classes” on page 5-2 for more information
on the behavior and use of both kinds of classes.
Passing Value Objects. When you pass a value object to a function, the
function creates a local copy of the argument variable. The function can
modify only the copy. If you want to modify the original object, return the
modified object and assign it to the original variable name. For example,
consider the value class, SimpleClass :
classdef SimpleClass
properties
Color
end
methods
function obj = SimpleClass(c)
if nargin > 0
obj.Color = c;
end
end
end
3-50
Comparing MATLAB® with Other OO Languages
end
obj = SimpleClass('red');
Pass the object to the function g, which assigns blue to the Color property:
function y = g(x)
x.Color = 'blue';
y = x;
end
y = g(obj);
The function g modifies its copy of the input object and returns that copy, but
does not change the original object.
y.Color
ans =
blue
obj.Color
ans =
red
If the function g did not return a value, the modification of the object Color
property would have occurred only on the copy of obj within the function
workspace. This copy would have gone out of scope when the function
execution ended.
obj = g(obj);
3-51
3 Class Definition—Syntax Reference
For example, suppose you modify the SimpleClass class definition to make a
class derived from the handle class:
obj = SimpleHandleClass('red');
Pass the object to the function g, which assigns blue to the Color property:
y = g(obj);
The function g sets the Color property of the object referred to by both the
returned handle and the original handle:
y.Color
ans =
blue
obj.Color
3-52
Comparing MATLAB® with Other OO Languages
ans =
blue
y.Color = 'yellow';
obj.Color
ans =
yellow
The function g modified the object referred to by the input argument (obj)
and returned a handle to that object in y.
Handles do not behave like references in C++. If you pass an object handle to
a function and that function assigns a different object to that handle variable,
the variable in the caller is not affected. For example, suppose you define a
function g2:
function y = g2(x)
x = SimpleHandleClass('green');
y = x;
end
obj = SimpleHandleClass('red');
y = g2(obj);
y.Color
ans =
green
obj.Color
ans =
3-53
3 Class Definition—Syntax Reference
red
The function overwrites the handle passed in as an argument, but does not
overwrite the object referred to by the handle. The original handle obj still
references the original object.
3-54
Comparing MATLAB® with Other OO Languages
3-55
3 Class Definition—Syntax Reference
3-56
4
User-Defined Classes
MATLAB classes are defined in code blocks, with sub-blocks delineating the
definitions of various class members. See “classdef Syntax” on page 4-4 for
details on the classdef block.
Kinds of Classes
There are two kinds of MATLAB classes—handle and value classes.
• Handle classes create objects that reference the data contained. Copies
refer to the same data.
• Value classes make copies of the data whenever the object is copied or
passed to a function. MATLAB numeric types are value classes.
4-2
User-Defined Classes
See “Comparing Handle and Value Classes” on page 5-2 for a more complete
discussion.
Constructing Objects
For information on class constructors, see “Class Constructor Methods” on
page 7-16
4-3
4 Defining and Organizing Classes
Class Definition
In this section...
“classdef Syntax” on page 4-4
“Examples of Class Definitions” on page 4-4
classdef Syntax
Class definitions are blocks of code that are delineated by the classdef
keyword at the beginning and the end keyword at the end. Files can contain
only one class definition.
The following diagram shows the syntax of a classdef block. Only comments
and blank lines can precede the classdef key word.
...
end
classdef block
4-4
Class Definition
4-5
4 Defining and Organizing Classes
Class Attributes
In this section...
“Table of Class Attributes” on page 4-6
“Specifying Attributes” on page 4-7
4-6
Class Attributes
(Continued)
Specifying Attributes
Attributes are specified for class members in the classdef, properties,
methods, and events definition blocks. The particular attribute setting
applies to all members defined within that particular block. This means that,
for example, you might use multiple properties definition blocks so you can
apply different attribute setting to different properties.
4-7
4 Defining and Organizing Classes
Attribute Syntax
Specify class attribute values in parentheses, separating each attribute
name/attribute value pair with a comma. The attribute list always follows the
classdef or class member key word, as shown below:
4-8
Expressions in Class Definitions
Basic Knowledge
The material presented in this section builds on an understanding of the
following information:
• “Evaluating Expressions”
• “Specifying Properties” on page 3-10
• “Specifying Attributes” on page 3-23
4-9
4 Defining and Organizing Classes
MATLAB does not call property set methods when assigning the result of
default value expressions to properties. (See “Property Access Methods” on
page 6-14 for information about these special methods.)
It is possible to use a MATLAB expression on the right side of the equals sign
(=) as long as it evaluates to logical true or false. However, this expression
cannot use any definitions in its own file, including any constant properties,
static methods, and local functions.
classdef MyClass
properties (Constant = true)
Deg2Rad = pi/180;
end
properties
PropA = sin(Deg2Rad*MyClass.getAngle[1 0],[0 1]);
end
...
methods (Static = true)
r = getAngle(vx,vy)
4-10
Expressions in Class Definitions
...
end
end
end
The following example shows how value and handle object behave when
assigned to properties as default values. Suppose you have the following
classes. ContClass defines the object that is created as a default property
value, and ClassExp has a property that contains a ContClass object:
classdef ContClass
4-11
4 Defining and Organizing Classes
properties
TimeProp = datestr(now); % Assign current date and time
end
end
classdef ClassExp
properties
ObjProp = ContClass;
end
end
MATLAB creates an instance of the ContClass class when the ClassExp class
is first used. MATLAB initializes both classes at this time. All instances of
ClassExp include a copy of this same instance of ContClass.
a = ClassExp;
a.ObjProp.TimeProp
ans =
08-Oct-2003 17:16:08
The TimeProp property of the ContClass object contains the date and time
when MATLAB initialized the class. Creating additional instances of the
ClassExp class shows that the date string has not changed:
b = ClassExp;
b.ObjProp.TimeProp
ans =
08-Oct-2003 17:16:08
Because this example uses a value class for the contained object, each
instance of the ClassExp has its own copy of the object. For example, suppose
you change the value of the TimeProp property on the object contained by
ClassExp objectb:
b.ObjProp.TimeProp = datestr(now)
ans =
4-12
Expressions in Class Definitions
08-Oct-2003 17:22:49
a.ObjProp.TimeProp
ans =
08-Oct-2003 17:16:08
Creating two instances of the ClassExp class shows that MATLAB created
an object when it initialized the ContClass and used a copy of the object
handle for each instance of the ClassExp class. This means there is one
ContClass object and the ObjProp property of each ClassExp object contains
a copy of its handle.
Create an instance of the ClassExp class and note the time of creation:
a = ClassExp;
a.ObjProp.TimeProp
ans =
08-Oct-2003 17:46:01
Create a second instance of the ClassExp class. The ObjProp contains the
handle of the same object:
b = ClassExp;
b.ObjProp.TimeProp
4-13
4 Defining and Organizing Classes
ans =
08-Oct-2003 17:46:01
b.ObjProp.TimeProp = datestr(now);
b.ObjProp.TimeProp
ans =
08-Oct-2003 17:47:34
Because the ObjProp property of object b contains a handle to the same object
as the ObjProp property of object a, the value of the TimeProp property has
changed on this object as well:
a.ObjProp.TimeProp
ans =
08-Oct-2003 17:47:34
See “Comparing Handle and Value Classes” on page 5-2 for more information
on handle and value classes.
4-14
Organizing Classes in Folders
• @-folders — Folder name begins with “@” and is not on the MATLAB path,
but its parent folder is on the path. Use this type of folder when you want to
use multiple files for one class definition. You can define only one class per
folder and the name of the class must match the name of the folder, without
the “@” symbol (@MyClass/MyClass.m, @MyClass/MyMethod.m, and so on).
• path folders — Folder name does not use an @ character and is itself on
the MATLAB path. Use this type of folder when you want multiple classes
in one folder. Define each class in one file only (MyClass1.m, MyClass2.m,
and so on)
See the path function for information about the MATLAB path.
@-Folders
An @-folder is contained by a path folder, but is not itself on the MATLAB
path. Place the class definition file inside the @-folder, which can also contain
method files. The class definition file must have the same name as the
@-folder (without the @-sign) and the class definition (beginning with the
classdef key word) must appear in the file before any other code (white space
and comments do not constitute code). The name of the class must match the
name of the file that contains the class definition.
4-15
4 Defining and Organizing Classes
You must use an @-folder if you want to use more than one file for your class
definition. Methods defined in separate files match the file name to the
function name. All files have a .m extension.
Path Folders
You can locate class definition files in folders that are on the MATLAB
path. These classes are visible on the path like any ordinary function. Class
definitions placed in path folders behave like any ordinary function with
respect to precedence—the first occurrence of a name on the MATLAB path
takes precedence over all subsequent occurrences.
The name of the file must match the name of the class, as specified with
the classdef key word. Using a path folder eliminates the need to create a
separate @-folder for each class. However, the entire class definition must be
contained within a single file. All files have a .m extension.
If you want a subclass to have access to the private functions of the superclass,
define the private functions as protected methods of the superclass (that is, in
a methods block with the Access attribute defined a protected).
4-16
Organizing Classes in Folders
precedence and it takes precedence over all class definition files occurring
later on the path.
For example, consider a path with the following folders, containing the files
indicated:
The MATLAB language applies the logic in the following list to determine
which version of foo to call:
4-17
4 Defining and Organizing Classes
Note that for backward compatibility, classes defined in @-folders always take
precedence over functions and scripts having the same name, even those
that come before them on the path.
4-18
Class Precedence
Class Precedence
InferiorClasses Attribute
You can specify the relative precedence of user-defined classes using the class
InferiorClasses attribute. Assign a cell array of class names (represented
as meta.class objects) to this attribute to specify classes that are inferior to
the class you are defining. For example, the following classdef declares that
myClass is dominant over class1 and class2.
The ? operator combined with a class name creates a meta.class object. This
syntax enables you to create a meta.class object without requiring you to
construct an actual instance of the class.
Dominant Class
MATLAB uses class dominance when evaluating expressions involving objects
of more than one class. The dominant class determines:
• The methods of which class MATLAB calls when more than one class
defines methods with the same names.
• The class of arrays that are formed by combining objects of different classes,
assuming MATLAB can convert the inferior objects to the dominant class.
4-19
4 Defining and Organizing Classes
More Information
See “Determining Which Method Is Invoked” on page 7-9 for more on how the
MATLAB classes dispatch when evaluating expressions containing objects.
See “Class Precedence and MATLAB Path” on page 4-16 for information on
how the location of a class definition on the MATLAB path determines its
precedence.
See “Use Class Metadata” on page 14-2 for information on meta-class objects.
No Attribute Inheritance
Subclasses do not inherit a superclass InferiorClasses attribute. Only
instances of the classes specified in the subclass InferiorClasses attribute
are inferior to subclass objects.
4-20
Create a Namespace with Packages
Package Folders
Packages are special folders that can contain class folders, function and
class definition files, and other packages. Packages define the scope of the
contents of the package folder (that is, a namespace within which names must
be unique). This means function and class names need to be unique only
within the package. Using a package provides a means to organize classes
and functions and to select names for these components that other packages
can reuse.
Note Packages are not supported for classes created prior to MATLAB
Version 7.6 (i.e., classes that do not use classdef).
+mypack
+mypack/pkfcn.m % a package function
+mypack/@myClass % class folder in a package
The top-level package folder’s parent folder must be on the MATLAB path.
help event
Contents of event:
4-21
4 Defining and Organizing Classes
what event
z = mypack.pkfcn(x,y);
Note that definitions do not use the package prefix. For example, the function
definition line of the pkfcn.m function would include only the function name:
function z = pkfcn(x,y)
Similarly, a package class would be defined with only the class name:
classdef myClass
obj = mypack.myClass(arg1,arg2,...);
Calling class methods does not require the package name because you have
an instance of the class:
obj.myMethod(arg) or
myMethod(obj,arg)
mypack.myClass.stMethod(arg)
4-22
Create a Namespace with Packages
obj = mypack.myClass;
+mypack
+mypack/myfcn.m
+mypack/@myfirstclass
+mypack/@myfirstclass/myfcn.m
+mypack/@myfirstclass/otherfcn.m
+mypack/@myfirstclass/myfirstclass.m
+mypack/@mysecondclass
+mypack/@mysecondclass/mysecondclass.m
+mypack/+mysubpack
+mypack/+mysubpack/myfcn.m
mypack.myfcn(arg)
obj1 = mypack.myfirstclass;
obj2 = mypack.mysecondclass(arg);
mypack.mysubpack.myfcn(arg1,arg2);
4-23
4 Defining and Organizing Classes
obj = mypack.myfirstclass;
myfcn(obj,arg);
obj = mypack.myfirstclass;
obj.MyProp = some_value;
Package members remain scoped to the package even if the package folder is
the current folder. You must, therefore, always refer to the package members
using the package name.
Package folders do not shadow other package folders that are positioned later
on the path, unlike classes, which do shadow other classes.
fldr1/+foo
fldr2/@foo/foo.m
A call to which foo returns the path to the executable class constructor:
A function and a package can have the same name. However, a package name
by itself is not an identifier so if a redundant name occurs alone, it identifies
the function. Executing a package name alone returns an error.
4-24
Create a Namespace with Packages
In cases where a path folder contains both package and class folders with
the same name, the class static method takes precedence over the package
method:
4-25
4 Defining and Organizing Classes
Importing Classes
In this section...
“Related Information” on page 4-26
“Syntax for Importing Classes” on page 4-26
Related Information
See “Create a Namespace with Packages” on page 4-21 for information about
packages.
function myFunc
import pkg.cls1
obj = cls1(arg,...); % call cls1 constructor
obj.Prop = cls1.StaticMethod(arg,...); % call cls1 static method
end
Note that you do not need to reference the package name (pkg) once you have
imported the class (cls1). You can also import all classes in a package using
the syntax pkg.*, where * indicates all classes in the package. For example,
function myFunc
import pkg.*
obj1 = cls1(arg,...); % call pkg.cls1 constructor
obj2 = cls2(arg,...); % call pkg.cls2 constructor
a = pkgFunction(); % call package function named pkgFunction
end
4-26
Importing Classes
function myFunc
import pkg.pkfcn
pkfcn(arg,...); % call imported package function
end
import pkg.*
myobj = pkg.myclass;
timedata(myobj)
A call to timedata finds the package function, not the class method because
MATLAB applies the import and finds pkg.timedata first. Do not use a
package in cases where you have name conflicts and plan to import the
package.
clear import
4-27
4 Defining and Organizing Classes
4-28
5
Basic Difference
A value class constructor returns an instance that is associated with the
variable to which it is assigned. If you reassign this variable, MATLAB
creates a copy of the original object. If you pass this variable to a function, the
function must return the modified object.
Note All handle classes must subclass the abstract handle class.
“Modifying Objects” on page 3-49 compares handle and value object behavior
when used as arguments to functions.
Use a handle class when you want to create a reference to the data contained
in an object of the class, and do not want copies of the object to make copies of
the object data. For example, use a handle class to implement an object that
5-2
Comparing Handle and Value Classes
Use value classes to represent entities that do not need to be unique, like
numeric values. For example, use a value class to implement a polynomial
data type. You can copy a polynomial object and then modify its coefficients to
make a different polynomial without affecting the original polynomial.
“Which Kind of Class to Use” on page 5-9 describes how to select the kind
of class to use for your application.
a = int32(7);
b = a;
a = a^4;
b
7
5-3
5 Value or Handle Class — Which to Use
x = 1:10; y = sin(x);
h1 = line(x,y);
h2 = h1;
MATLAB returns an
If you delete one handle, all copies are now invalid because you have deleted
the single object to which all copies point.
Value Classes
MATLAB associates objects of value classes with the variables to which
you assign them. When you copy a value object, MATLAB also copies the
data contained by the object. The new object is independent of changes to
the original object. Instances behave like standard MATLAB numeric and
struct classes. Each property behaves essentially like a MATLAB array See
“Memory Allocation for Arrays” for more information.
5-4
Comparing Handle and Value Classes
p = polynomial([1 0 -2 -5]);
p2 = p;
p.Coefficients = [2 3 -1 -2 -3];
p2.Coefficients
ans =
1 0 -2 -5
classdef myValueClass
...
end
Handle Classes
Objects of handle classes use a handle to reference objects of the class. A
handle is a variable that identifies an instance of a class. When you copy a
handle object, MATLAB copies the handle, but not the data stored in the
object properties. The copy refers to the same data as the original handle. If
you change a property value on the original object, the copied object reflects
the same change.
All handle classes are subclasses of the abstract handle class. In addition to
providing handle copy semantics, deriving from the handle class enables
your class to:
5-5
5 Value or Handle Class — Which to Use
See “The Handle Superclass” on page 5-11 for more information on the handle
class and its methods.
5-6
Comparing Handle and Value Classes
For example, suppose you have defined a handle class that stores data about
company employees, such as the department in which they work:
The transfer method in the previous code changes the employee’s department
(the Department property of an employee object). In the following statements,
e2 is a copy of the handle object e. Notice that when you change the
Department property of object e, the property value also changes in object e2.
e = employee('Fred Smith','QE');
e2 = e; % Copy handle object
transfer(e,'Engineering')
e2.Department
ans =
Engineering
The variable e2 is an alias for e and refers to the same property data storage
as e.
5-7
5 Value or Handle Class — Which to Use
When you call transfer, assign the output argument to create the modified
object.
e = transfer(e,'Engineering');
In a value class, the transfer method does not affect the variable e2, which
is a different employee object. In this example, having two independent
copies of objects representing the same employee is not a good design. Hence,
implement the employee class as a handle class.
Deleting Handles
You can destroy handle objects before they become unreachable by explicitly
calling the delete function. Deleting the handle of a handle class object
makes all handles invalid. For example:
delete(e2)
e.Department
Invalid or deleted object.
Calling the delete function on a handle object invokes the destructor function
or functions for that object. See “Handle Class Destructor” on page 5-16 for
more information.
5-8
Which Kind of Class to Use
Handle classes enable you to create objects that more than one function or
object can share. Handle objects allow more complex interactions among
objects because they allow objects to reference each other.
• No two instances of a class can have the same state, making it impossible
to have exact copies. For example:
- A copy of a graphics object (such as a line) has a different position in
its parents list of children than the object from which it was copied.
Therefore, the two objects are not identical.
- Nodes in lists or trees having specific connectivity to other nodes—no
two nodes can have the same connectivity.
5-9
5 Value or Handle Class — Which to Use
• The class represents physical and unique objects like serial ports or
printers, in which the entity or state cannot exist in a MATLAB variable.
However, a handle to such entity can be a variable.
• The class defines events and notifies listeners when an event occurs
(notify is a handle class method).
• The class creates listeners by calling the handle class addlistener method.
• The class subclasses the dynamicprops class (a subclass of handle) so that
instances can define dynamic properties.
• The class subclasses the hgsetget class (a subclass of handle) so that it
can implement a Handle Graphics™ style set/get interface.
• You want to create a singleton class or a class in which you track the
number of instances from within the constructor. MATLAB software never
creates a unique handle without calling the class constructor. A copy of a
handle object is not unique because both original and copy reference the
same data.
A value class is suitable because you can copy a polynomial object and have
two objects that are identical representations of the same polynomial. See
“Subclassing MATLAB Built-In Classes” on page 10-43 for more information
on value classes.
5-10
The Handle Superclass
Handle Subclasses
There are two subclasses of the handle class that provide additional features
when you derive your class from these subclasses:
• hgsetget — Provides set and get methods that enable you to implement a
Handle Graphics™ style interface. See “Implementing a Set/Get Interface
for Properties” on page 5-23 for information on subclassing hgsetget.
• dynamicprops — Provides the ability to define instance properties. See
“Dynamic Properties — Adding Properties to an Instance” on page 6-26 for
information on subclassing dynamicprops.
Deriving from subclasses of the handle class means that your class is a
handle class. It inherits all the handle class methods, plus the special
features provided by these subclasses.
5-11
5 Value or Handle Class — Which to Use
You can list the methods of a class by passing the class name to the methods
function:
>> methods('handle')
addlistener findobj gt lt
delete findprop isvalid ne
eq ge le notify
Static Methods:
empty
Relational Methods
function TF = eq(H1,H2)
function TF = ne(H1,H2)
function TF = lt(H1,H2)
function TF = le(H1,H2)
function TF = gt(H1,H2)
function TF = ge(H1,H2)
The handle class overloads these functions with implementations that allow
for equality tests and sorting on handles. For each pair of input arrays,
these functions return a logical array of the same size. Each element is an
5-12
The Handle Superclass
B = isvalid(H)
B is a logical array in which each element is true if, and only if, the
corresponding element of H is a valid handle. B is always the same size as H.
h = button([50 20 50 20]);
5-13
5 Value or Handle Class — Which to Use
Determine the difference between the graphics object handle (stored in the
UiHandle property) and the handle class object, h. Use ishandle to test the
validity of Handle Graphics object handles:
% h is a handle object
>> isa(h,'handle')
ans =
1
If you close the figure, the ishandle function determines that the Handle
Graphics handle is not valid:
>> close
>> ishandle(h.UiHandle)
ans =
>> isa(h,'handle')
ans =
5-14
The Handle Superclass
>> isvalid(h)
ans =
>> isa(h,'button')
ans =
You do not need to free memory in handle classes. However, there can be
other operations that you want to perform when destroying an object. For
example, closing a file or shutting down an external program that the object
constructor started. You can define a delete method in your handle subclass
for these purposes.
5-15
5 Value or Handle Class — Which to Use
Basic Knowledge
Terms and Concepts
Class destructor – a method named delete that MATLAB calls implicitly
before destroying an object of the a handle class. User-defined code can also
call delete explicitly to destroy a handle object.
Nondestructor – a method named delete that does not meet the syntax
requirements of a valid destructor. Consequently, MATLAB does not call this
method implicitly when destroying an object.
• Must have one scalar input argument that is an object of the class.
5-16
Handle Class Destructor
• Throw errors
• Create new handles to the object being destroyed
If you define a delete method that can be called with more than one input
argument, or that returns any output arguments, then MATLAB does not
recognize that method as the class destructor, and does not call it when
destroying an object of the class.
method
function delete(obj)
% obj is always scalar
...
end
end
For example, suppose an object opens a file for writing and you want to close
the file in your delete method. This delete function calls fclose on a file
identifier that the object’s FileID property stores:
function delete(obj)
fclose(obj.FileID);
end
5-17
5 Value or Handle Class — Which to Use
“The Filewriter Class” on page 2-18 is an example of a class that uses this
delete method.
Object Lifecycle
MATLAB invokes the destructor delete method when the lifecycle of an
object ends. The lifecycle of an object ends when the object is:
5-18
Handle Class Destructor
Inside a Function
The lifecycle of an object referenced by a local variable or input argument
exists from the time the variable is assigned until the time it is reassigned,
cleared, or no longer referenced within that function or any handle array.
A variable goes out of scope when you explicitly clear it or when its function
ends. When a variable goes out of scope, if its value belongs to a handle class
that defines a delete method, MATLAB calls that method. MATLAB defines
no ordering among variables in a function. Do not assume that MATLAB
destroys one value before another value when the same function contains
multiple values.
2 The delete method of each superclass class, starting with the immediate
superclasses and working up the hierarchy to the most general superclasses
After calling each delete method, MATLAB destroys the property values
belonging exclusively to the class whose method was called. The destruction
of property values that contain other handle objects can cause MATLAB to
5-19
5 Value or Handle Class — Which to Use
call the delete methods for those objects, if there are no other references
to those objects.
• Destroys the objects if they are referenced only within the cycle
• Does not destroy the objects as long as there is an external reference to any
of the objects from a MATLAB variable outside the cycle
delete(obj)
However, when an object’s lifecycle ends, MATLAB calls the object’s delete
method when destroying the object regardless of method’s Access attribute
setting. See “Object Lifecycle” on page 5-18 for information on when MATLAB
destroys objects and “Sequence During Handle Object Destruction” on page
5-19 for information on how MATLAB calls object delete methods.
5-20
Handle Class Destructor
When you explicitly call an object’s delete method, MATLAB checks the
delete method Access attribute in the class defining the object, but not in
the superclasses of the object. Therefore, a superclass with a private delete
method does not prevent the destruction of subclass objects.
Declaring a private delete method makes most sense for Sealed classes
because subclasses can define their own delete methods with public Access.
See “Syntax of Class Destructor Method” on page 5-16 for information on how
to implement a delete method that is a valid destructor.
5-21
5 Value or Handle Class — Which to Use
function HM = findobj(H,<conditions>)
function mp = findprop(h,'PropertyName')
The findprop method returns the meta.property object associated with the
PropertyName property defined by the class of h. The property can also be a
dynamic property created by the addprop method of the dynamicprops class.
ba = BankAccount(007,50,'open');
mp = findprop(ba,'AccountStatus'); % get meta.property object
mp.Dependent
ans =
0
5-22
Implementing a Set/Get Interface for Properties
Note The set and get methods referred to in this section are different from
property set access and property get access methods. See “Property Access
Methods” on page 6-14 for information on property access methods.
Subclass hgsetget
Classes inherit set and get methods from hgsetget:
Because hgsetget derives from the handle class, MyClass is also a handle
class.
v = get(h,'PropertyName');
5-23
5 Value or Handle Class — Which to Use
If you specify an array of handles with a single property name, get returns
the current property value for each object in H as a cell array of values, (CV):
CV = get(H,'PropertyName');
prop = {'PropertyName1','PropertyName2'};
CV = get(H,prop);
If you specify a handle array, but no property names, get returns a struct
array in which each structure in the array corresponds to an object in H. Each
field in the structure corresponds to a property defined by the class of H. The
value of each field is the value of the corresponding property. If you do not
assign an output variable, then H must be scalar.
SV = get(H);
See “Using Handle Arrays with Get” on page 5-28 for an example.
set(H,'PropertyName',PropertyValue)
You can pass a cell array of property names and a cell array of property
values to set:
set(H,{'PropertyName1','PropertyName2'},...
{Property1Value,Property2Value})
5-24
Implementing a Set/Get Interface for Properties
If length(H) is greater than one, then the property value cell array can have
values for each property in each object. For example, if length(H) is 2 (two
object handles), then you can use an expression like this:
set(H,{'PropertyName1','PropertyName2'},...
{Property11Value,Property12Value;Property21Value,Property22Value})
set(H(1),'PropertyName1',Property11Value,'PropertyName2',Property12Value)
set(H(2),'PropertyName1',Property21Value,'PropertyName2',Property22Value)
If you specify a scalar handle, but no property names, set returns a struct
array with one field for each property in the class of H. Each field contains
an empty cell array.
SV = set(h);
5-25
5 Value or Handle Class — Which to Use
if ~(strcmpi(val,'-') ||...
strcmpi(val,'--') ||...
strcmpi(val,'..'))
error('Invalid line style ')
end
obj.Style = val;
end % set.Style
function obj = set.Marker(obj,val)
if ~isstrprop(m,'graphic')
error('Marker must be a visible character')
end
obj.Marker = val;
end % set.Marker
end % methods
end % classdef
h = LineType('--','*');
Query the value of any object property using the inherited get method:
get(h,'Marker')
ans =
Set the value of any property using the inherited set method:
set(h,'Marker','Q')
set(h,'Style','-.-')
Error using LineType>LineType.set.Style
Invalid line style
5-26
Implementing a Set/Get Interface for Properties
Using the set and get methods that are inherited from hgsetget invokes
any existing property access methods that would execute when assigning or
querying property values using dot notation:
h.Style = '-.-';
Error using LineType>LineType.set.Style
Invalid line style
See “Property Access Methods” on page 6-14 for more information on property
access methods.
Style: '--'
Marker: '*'
Units: 'points'
Create a struct containing the properties that have public SetAccess using
set with an object handle:
S =
Style: {}
Marker: {}
5-27
5 Value or Handle Class — Which to Use
The LineType class defines the Units property with SetAccess = protected.
Therefore, S = set(h) does not create a field for this property in the sturct
S. set cannot return possible values for the properties.
H = [LineType('..','z'),LineType('--','q')]
H =
Properties:
Style
Marker
Units
CV = get(H,'Style')
CV =
'..'
'--'
SV =
5-28
Implementing a Set/Get Interface for Properties
Units
Get the value of the Marker property from the second array element in the
SV struct array:
SV(2).Marker
ans =
H = [LineType('..','z'),LineType('--','q')];
set(H,{'Style','Marker'},{'..','o';'--','x'})
H(1)
ans =
LineType handle
Properties:
Style: '..'
Marker: 'o'
Units: 'points'
H(2)
ans =
LineType handle
Properties:
5-29
5 Value or Handle Class — Which to Use
Style: '--'
Marker: 'x'
Units: 'points'
• setdisp — Called by set when you call set with no output arguments and
a single input parameter containing the handle array.
• getdisp — Called by get when you call get with no output arguments and
a single input parameter containing the handle array.
5-30
Controlling the Number of Instances
Limiting Instances
You can limit the number of instances of a class that can exist at any one time.
For example, a singleton class can have only one instance and provides a way
to access this instance. You can create a singleton class using these elements:
The getInstance static method returns a handle to the object created, which
the class stores in a persistent variable. getInstance creates an instance
only the first time called in a session or when the object becomes invalid.
For example:
5-31
5 Value or Handle Class — Which to Use
sobj = SingleInstance.getInstance
sobj =
SingleInstance handle with no properties.
Methods, Events, Superclasses
delete(sobj)
isvalid(sobj)
ans =
0
sobj = SingleInstance.getInstance;
isvalid(sobj)
ans =
5-32
6
• Define a constant value that you cannot change outside the class definition.
See “Properties with Constant Values” on page 13-2
• Calculate its value based on the current value of other data. See “Property
Get Methods” on page 6-18
• Execute a function to determine if an attempt to assign a value meets a
certain criteria. See “Property Set Methods” on page 6-16
• Trigger an event notification when any attempt is made to get or set its
value. See “Property-Set and Query Events” on page 9-14
• Restrict access by other code to the property value. See the SetAccess and
GetAccess attributes “Property Attributes” on page 6-8
• Control whether its value is saved with the object in a MAT-file. See “The
Default Save and Load Process” on page 11-2
6-2
How to Use Properties
Types of Properties
There are two types of properties:
• Compute the value of a property from other values (for example, you can
compute area from Width and Height properties).
• Provide a value in different formats depending on other values. For
example, the size of a push button in values determined by the current
setting of its Units property.
• Provide a standard interface where a particular property is or is not used,
depending on other values. For example, different computer platforms can
have different components on a toolbar).
6-3
6 Properties — Storing Class Data
6-4
Defining Properties
Defining Properties
In this section...
“Property Definition Block” on page 6-5
“Accessing Property Values” on page 6-6
“Inheritance of Properties” on page 6-6
“Specifying Property Attributes” on page 6-7
Coefficients = [0 0 1];
end
properties block
6-5
6 Properties — Storing Class Data
You can initialize property values with MATLAB expressions. However, these
expressions cannot refer to the class that you are defining in any way, except
to call class static methods. MATLAB executes expressions that create initial
property values only when initializing the class, which occurs just before
first using the class. See “Defining Default Values” on page 3-11 for more
information about how MATLAB evaluates default value expressions.
When you access a property, MATLAB performs any operations that the
property requires. For example, executing a property set or get access method
and triggering property access events.
Inheritance of Properties
When you derive one class from another class, the derived (subclass) class
inherits all the properties of the superclass. In general, subclasses define
only properties that are unique to that particular class. Superclasses define
properties that more than one subclass use.
6-6
Defining Properties
For example, the following code shows the SetAccess attribute set to private
for the IndependentVar and Order properties, but not for the Coefficients
property:
properties
Coefficients = [0 0 1];
end
properties (SetAccess = private)
IndependentVar
Order = 0;
end
These properties (and any others placed in
this block) have private set access
6-7
6 Properties — Storing Class Data
Property Attributes
6-8
Property Attributes
(Continued)
6-9
6 Properties — Storing Class Data
(Continued)
6-10
Property Attributes
(Continued)
6-11
6 Properties — Storing Class Data
(Continued)
6-12
Mutable and Immutable Properties
• Public set access means any code with access to an object can set public
property values. There are differences between the behavior of handle and
value classes with respect to modifying object properties. See “Modifying
Objects” on page 3-49 for information on these differences.
• Protected set access — only code executing from within class methods or
methods of subclasses can set property values. You cannot change the
value of an object property unless the class or any of its subclasses defines
a method to do so.
• Private set access — only the defining class can set property values. You
can change the value of an object property only if the class defines a method
to perform this action.
• Immutable set access — only the class constructor can set property values.
You cannot change the value of an object property.
6-13
6 Properties — Storing Class Data
• Execute code before assigning property values to perform actions such as:
- Impose value range restrictions (“Restricting Properties to Specific
Values” on page 2-25)
- Check for proper types and dimensions
- Provide error handling
• Execute code before returning the current values of properties to perform
actions such as:
- Calculate the value of properties that do not store values (for an example,
see “Using a Dependent Property” on page 2-27)
- Change the value of other properties
- Trigger events (for an example, see “Defining and Triggering an Event”
on page 9-4)
6-14
Property Access Methods
• For concrete properties (that is, properties that are not abstract)
• Within the class that defines the property (unless the property is abstract
in that class, in which case the concrete subclass must define the access
method).
MATLAB has no default set or get property access methods. Therefore, if you
do not define property access methods, MATLAB software does not invoke
any methods before assigning or returning property values.
Once defined, only the set and get methods can set and query the actual
property values. See “Set Method Behavior” on page 6-17 for information on
cases where MATLAB does not call property set methods.
Note Property set and get access methods are not equivalent to user-callable
set and get methods used to access property values from an instance of the
class. See “Implementing a Set/Get Interface for Properties” on page 5-23 for
information on user-callable set and get methods.
6-15
6 Properties — Storing Class Data
For example, if the class myClass defines a set function for its Text property,
you can obtain a function handle to this method from the meta.class object:
m = ?myClass;
m.Properties{1}.SetMethod % Assuming Text is the first property in the cell array
ans =
@\mydir\@myClass\myClass.m>myClass.set.Text % This is a function handle
Here obj is the object whose property is being assigned a value and value
is the new value that is assigned to the property.
6-16
Property Access Methods
Value class set functions must return the object with the new value for the
property assigned. Value classes replace the object whose property is being
assigned with the object returned by the set method. Handle classes do not
need to return the modified object.
The property set method can perform actions like error checking on the input
value before taking whatever action is necessary to store the new property
value.
• Assigning a value to a property from within its own property set method,
which prevents recursive calling of the set method
• Specifying default values in class definitions do not invoke the set method
• Assigning a property to its default value, which is specified in the class
definition
• Copying a value object (that is, not derived from the handle class). Neither
the set or get method is called when copying property values from one
object to another.
6-17
6 Properties — Storing Class Data
• Assigning a property value that is the same as the current value when
the property’s AbortSet attribute is true does not call the property’s set
method. See “Aborting Set When Value Does Not Change” on page 9-31 for
more information on this attribute.
When assigning a property value, the calling function’s copy of the object that
has been passed to the set method reflects the changed value. Therefore, an
assignment to even a single property is able to affect the whole object. This
behavior enables a set method to change other properties in the object as well
as its designated property.
For example, a graphics window object can have a Units property and a Size
property. Changing the Units property can also require a change to the
values of the Size property to reflect the new units.
plot(obj.XYData)
Property get methods have the following syntax, where PropertyName is the
name of the property. The function must return the property value.
6-18
Property Access Methods
classdef Account
properties
Now the get method for the PropertyName property determines the value of
that property and assigns it to the object from within the method:
For example, suppose you have a class that changes the name of a property
from OldPropName to NewPropName. You want to continue to allow the use of
the old name without exposing it to new users. You can make OldPropName
a dependent property with set and get methods as show in the following
example:
6-19
6 Properties — Storing Class Data
properties
NewPropName
end
properties (Dependent, Hidden)
OldPropName
end
methods
function obj = set.OldPropName(obj,val)
obj.NewPropName = val;
end
function value = get.OldPropName(obj)
value = obj.NewPropName;
end
end
There is no memory wasted by storing both old and new property values, and
code that accesses OldPropName continues to work as expected.
methods
function mval = get.MaxValue(obj)
mval = max(obj.BigArray(:));
end
end
This example uses the MaxValue property to return a value that it calculates
only when queried. For this application, define the MaxValue property as
dependent and private:
6-20
Property Access Methods
MaxValue
end
• PreSet — Triggered before assigning the new property value within the
set method
• PostSet — Triggered after assigning the new property value within the
set method
“Implementing the PostSet Property Event and Listener” on page 9-47 shows
an example of a property listener.
“Example – Property Set Listener” on page 9-8 is another example that uses
property events.
6-21
6 Properties — Storing Class Data
MATLAB always passes scalar objects to set and get methods. When reference
or assignment occurs on an object array, the set and get methods are called
in a loop.
The property get methods applies a scale factor before returning its current
value:
classdef Testpoint
properties (Dependent)
expectedResult = [];
end
properties(Constant)
6-22
Property Access Methods
scalingFactor = 0.001;
end
methods
function obj = set.expectedResult(obj,erIn)
if erIn >= 0 && erIn <= 100
erIn = erIn.*obj.scalingFactor
obj.expectedResult = erIn;
else
obj.expectedResult = NaN;
end
end
function er = get.expectedResult(obj)
er = obj.expectedResult/obj.scalingFactor;
end
end
end
6-23
6 Properties — Storing Class Data
classdef ReadOnlyProps
properties(SetAccess = private)
PropHandle
PropValue
end
methods
function obj = ReadOnlyProps
obj.PropHandle = HanClass;
obj.PropValue = ValClass;
end
end
end
6-24
Properties Containing Objects
Hprop
end
end
classdef ValClass
properties
Vprop
end
end
a = ReadOnlyProps
a =
ReadOnlyProps
Properties:
PropHandle: [1x1 HanClass]
PropValue: [1x1 ValClass]
Use the private PropHandle property to set the property of the HanClass
object it contains:
a.PropHandle.Hprop = 7;
a.PropHandle.Hprop
ans =
a.PropValue.Vprop = 11;
Setting the 'PropValue' property of the 'ReadOnlyProps' class is not allowe
6-25
6 Properties — Storing Class Data
It is possible for more than one program to define dynamic properties on the
same object so you must take care to avoid name conflicts.
• Set and query the values of dynamic properties using dot notation (see
“Assigning Data to the Dynamic Property” on page 6-28)
• MATLAB saves and loads dynamic properties when you save and load
the objects to which they are attached (see “Saving and Loading Dynamic
Properties” on page 11-20 and “Dynamic Properties and ConstructOnLoad”
on page 6-32)
• Define attributes for dynamic property (see “Setting Dynamic Property
Attributes” on page 6-27).
• Add property set and get access methods (see “Defining Property Access
Methods for Dynamic Properties” on page 6-31)
6-26
Dynamic Properties — Adding Properties to an Instance
P = addprop(H,'PropertyName')
where:
H is an array of handles
PropertyName is the name of the dynamic property you are adding to each
object
P.Hidden = true;
6-27
6 Properties — Storing Class Data
delete(P);
The property attributes Constant and Abstract have no meaning for dynamic
properties and setting the value of these attributes to true has no effect.
Create an instance of the button class, add a dynamic property, and set its
value:
6-28
Dynamic Properties — Adding Properties to an Instance
You can access the dynamic property just like any other property, but only on
the instance on which you defined it:
b1.myCoord
ans =
2 3
The dynamicprops class defines two events and inherits one from handle:
b2 = button([20 40 80 20]);
Create a function to attach listeners to the button object, b2, and a listener
callback function:
function listenDynoEvent(obj)
addlistener(obj,'PropertyAdded',@eventPR);
addlistener(obj,'PropertyRemoved',@eventPR);
function eventPR(src,evnt)
mc = metaclass(src);
fprintf(1,'%s %s \n',mc.Name,'object')
fprintf(1,'%s %s \n','Event triggered:',evnt.EventName)
end
end
6-29
6 Properties — Storing Class Data
Add the listeners to the button object, b2. Then, add a dynamic property,
myCoord.
% add listeners
listenDynoEvent(b2)
% add dynamic property and save meta.DynamicProperty object
mp = b2.addprop('myCoord');
The listener callback function, eventPR, executes and displays the object
class and event name:
button object
Event triggered: PropertyAdded
delete(mp)
button object
Event triggered: PropertyRemoved
mp = findprop(b2,'myCoord');
Having a listener defined for a deleted dynamic property does not cause an
error, but the listener callback is never executed.
6-30
Dynamic Properties — Adding Properties to an Instance
Note You can set and get the property values only from within your property
access methods. You cannot call another function from the set or get method
and attempt to access the property value from that function.
Suppose you want to create a property set function for the button class
dynamic property myCoord created previously. Write the function as follows:
function set_myCoord(obj,val)
if ~(length(val) == 2) % require two values
error('myCoords require two values ')
end
obj.myCoord = val; % set property value
6-31
6 Properties — Storing Class Data
end
Because button is a handle class, the property set function does not need to
return the object as an output argument. Assign the value to the property
if the value is valid.
mb1 = b1.findprop('myCoord');
mb1.SetMethod = @set_myCoord;
The property set function is now called whenever you set this property:
• A saved object saves the names and values of properties, including dynamic
properties
• When loaded, a new object is created and all properties are restored to the
values at the time the object was saved
• Then, the ConstructOnLoad attribute causes a call to the class constructor,
which would create another dynamic property with the same name as the
loaded property (see “The Default Save and Load Process” on page 11-2 for
more on the load sequence)
• MATLAB prevents a conflict by loading the saved dynamic property, and
does not execute addprop when calling the constructor.
6-32
Dynamic Properties — Adding Properties to an Instance
Transient attribute to true. This setting prevents the property from being
saved. For example:
6-33
6 Properties — Storing Class Data
6-34
7
Class Methods
Methods are functions that implement the operations performed on objects
of a class. Methods, along with other class members support the concept of
encapsulation—class instances contain data in properties and class methods
operate on that data. This allows the internal workings of classes to be hidden
from code outside of the class, and thereby enabling the class implementation
to change without affecting code that is external to the class.
See “Methods That Modify Default Behavior” on page 15-2 for a discussion of
how to create classes that modify standard MATLAB behavior.
See “Saving Class Files” on page 3-2 for information on the use of @ and path
directors and packages to organize your class files.
See “Methods In Separate Files” on page 3-16 for the syntax to use when
defining classes in more than one file.
Kinds of Methods
There are specialized kinds of methods that perform certain functions or
behave in particular ways:
• Ordinary methods are functions that act on one or more objects and
return some new object or some computed value. These methods are
like ordinary MATLAB functions that cannot modify input arguments.
Ordinary methods enable classes to implement arithmetic operators and
7-2
How to Use Methods
Method Naming
The name of a function that implements a method can contain dots (for
example, set.PropertyName) only if the method is one of the following:
7-3
7 Methods — Defining Class Operations
See “Defining Methods” on page 7-7 for more information on how you can
define methods.
See “Rules for Naming to Avoid Conflicts” on page 7-28 for related information.
7-4
Method Attributes
Method Attributes
Attribute values apply to all methods defined within the methods block that
specifies the nondefault values.
methods (attribute1=value1,attribute2=value2,...)
...
end
Attribute
Name Class Description
Abstract logical If true, the method has no implementation. The method
Default=false has a syntax line that can include arguments, which
subclasses use when implementing the method:
7-5
7 Methods — Defining Class Operations
(Continued)
Attribute
Name Class Description
7-6
Ordinary Methods
Ordinary Methods
In this section...
“Defining Methods” on page 7-7
“Determining Which Method Is Invoked” on page 7-9
“Specifying Precedence” on page 7-13
“Controlling Access to Methods” on page 7-13
“Invoking Superclass Methods in Subclass Methods” on page 7-14
“Invoking Built-In Functions” on page 7-15
Defining Methods
You can specify methods:
classdef ClassName
methods (AttributeName = value,...)
function x = compute(obj,inc)
x = obj.y + inc;
end % compute method
...
end % methods block
...
end % classedf
7-7
7 Methods — Defining Class Operations
Either of the following statements is correct syntax for calling a method where
obj is an object of the class defining the compute method:
obj.compute(inc)
compute(obj,inc)
classdef myClass
methods (AttributeName = value,...)
tdata = testdata(obj,arg1,arg2)
...
end % methods
...
end % classdef
Do not use methods blocks in the separate files. Define the method as a
function. Using the example above, the file testdata.m, must contain the
definition of the testdata function. Note that the signatures must match.
7-8
Ordinary Methods
• If you want to specify attributes for a method defined in a separate file, you
must declare this method in a methods block (specifying attribute values)
within the classdef block.
• The syntax declared in the methods block (if used) must match the
method’s function line.
• The separate file must be in the class @-folder.
• The constructor method must be defined within the classdef block and,
therefore, cannot be in a separate file. (See “Class Constructor Methods” on
page 7-16 for information on this method.)
• Set and get property access methods must be defined within the classdef
block and, therefore, cannot be in separate files. (See “Property Access
Methods” on page 6-14 for information on these methods.)
• The class of the left-most argument whose class is not specified as inferior
to any other argument’s class is chosen as the dominant class and its
method is invoked.
• If this class does not define the named method, then a function with that
name on the MATLAB path is invoked.
• If no such function exists, MATLAB issues an error indicating that the
dominant class does not define the named method.
Dominant Argument
The dominant argument in a method’s argument list determines which
version of the method or function that the MATLAB runtime calls. Dominance
is determined by the relative precedences of the classes of the arguments. In
general, user-defined classes take precedence over built-in MATLAB classes.
Therefore, the left most argument determines which method to call. However,
user-defined classes can specify the relative dominance of specific classes.
7-9
7 Methods — Defining Class Operations
For example, suppose classA defines classB as inferior and suppose both
classes define a method called combine.
combine(B,A)
X = setColor(X,'red');
X = X.setColor('red')
However, in certain cases, the results for dot notation can differ with respect
to how MATLAB dispatching works:
7-10
Ordinary Methods
The methodA method is defined with two input arguments, one of which is an
object of classB:
classdef classA
methods
function methodA(obj,obj_classB)
...
end
end
classB does not define a method with the same name as methodA. Therefore,
the following syntax causes the MATLAB runtime to search the path for a
function with the same name as methodA because the second argument is an
object of a dominant class. If a function with that name exists on the path,
then MATLAB attempts to call this function instead of the method of classA
and most likely returns a syntax error.
obj = classA(...);
methodA(obj,obj_classB)
Dot notation is stricter in its behavior. For example, this call to methodA:
obj = classA(...);
obj.methodA(obj_classB)
obj.(expression)
7-11
7 Methods — Defining Class Operations
obj.Property1
obj.('Property1')
propName = 'Property1';
obj.(propName)
You can call a method and pass input arguments to the method using another
set of parentheses:
obj.(expression)(arg1,arg2,...)
Using this notation, you can make dynamic references to properties and
methods in the same way you can create dynamic references to the fields
of structs (see “Generate Field Names from Variables” for information on
MATLAB structures).
obj.(datestr(date,'dddd'))(datestr(date,'dd'))
datestr(date,'dddd')
ans =
Tuesday
7-12
Ordinary Methods
datestr(date,'dd')
ans =
11
obj.Tuesday('11')
Specifying Precedence
“Class Precedence” on page 4-19 provides information on how you can specify
the relative precedence of user-define classes.
• public — Any code having access to an object of the class can access this
method (the default).
• private — Restricts method access to the defining class, excluding
subclasses. Subclasses do not inherit private methods.
• protected — Restricts method access to the defining class and subclasses
derived from the defining class. Subclasses inherit this method.
Local and nested functions inside the method files have the same access as the
method. Note that local functions inside a class-definition file have private
access to the class defined in the same file.
7-13
7 Methods — Defining Class Operations
The syntax to call a superclass method in a subclass class uses the @ symbol:
MethodName@SuperclassName
For example, the following disp method is defined for a Stock class that is
derived from an Asset class. The method first calls the Asset class disp
method, passing the Stock object so that the Asset components of the Stock
object can be displayed. After the Asset disp method returns, the Stock disp
method displays the two Stock properties:
See “The DocStock disp Method” on page 17-10 for more information on this
example.
Limitations of Use
The following restrictions apply to calling superclass methods. You can use
this notation only within:
• A method having the same name as the superclass method you are invoking
• A class that is a subclass of the superclass whose method you are invoking
7-14
Ordinary Methods
7-15
7 Methods — Defining Class Operations
7-16
Class Constructor Methods
Related Information
See “Creating Object Arrays” on page 8-3 for information on constructing
arrays of objects.
7-17
7 Methods — Defining Class Operations
For example, the following constructor function can assign the value of the
object’s property A as the first statement because the object obj has already
been assigned to an instance of myClass.
You can call other class methods from the constructor because the object
is already initialized.
The constructor also creates an object whose properties have their default
values—either empty ([]) or the default value specified in the property
definition block. See “Property Definition Block” on page 6-5 for a description
of this syntax and see “Defining Default Values” on page 3-11 for a discussion
of how best to define property values.
For example, the following code calls the class method CalculateValue to
assign the value of the property Value.
7-18
Class Constructor Methods
If there are no input arguments, the constructor creates an object using only
default properties values. A good practice is to always add a check for zero
arguments to the class constructor to prevent an error if either of the two
cases above occur:
See “Basic Structure of Constructor Methods” on page 7-23 for ways to handle
superclass constructors.
7-19
7 Methods — Defining Class Operations
Constructing Subclasses
Subclass constructor functions must explicitly call superclass constructors
if the superclass constructors require input arguments. The subclass
constructor must specify these arguments in the call to the superclass
constructor using the constructor output argument and the returned object
must be assigned to the constructor output argument. Here is the syntax:
The class constructor must make all calls to superclass constructors before
any other references to the object, such as assigning property values or calling
ordinary class methods. Also, a subclass constructor can call a superclass
constructor only once.
7-20
Class Constructor Methods
Suppose in the case of the cube class example above, all property values in
the shape superclass and the cube subclass have initial values specified in
the class definitions that create a default cube. Then you could create an
instance of cube without specifying any arguments for the superclass or
7-21
7 Methods — Defining Class Operations
subclass constructors. Here is how you can implement this behavior in the
cube constructor:
More on Subclasses
See “Creating Subclasses — Syntax and Techniques” on page 10-7 for
information on creating subclasses.
See “Handle Class Destructor” on page 5-16 for information on how objects
are destroyed.
7-22
Class Constructor Methods
7-23
7 Methods — Defining Class Operations
obj = obj@baseClass1(args{:});
See “Creating Object Arrays” on page 8-3 for information on creating object
arrays in the constructor.
7-24
Static Methods
Static Methods
In this section...
“Why Define Static Methods” on page 7-25
“Calling Static Methods” on page 7-26
Static methods are useful when you do not want to first create an instance
of the class before executing some code. For example, you might want to
set up the MATLAB environment or use the static method to calculate data
needed to create class instances.
classdef MyClass
...
methods(Static)
function p = pi(tol)
[n d] = rat(pi,tol);
p = n/d;
end
end
end
7-25
7 Methods — Defining Class Operations
classname.staticMethodName(args,...)
Calling the pi method of MyClass in the previous section would require this
statement:
value = MyClass.pi(.001);
You can also invoke static methods using an instance of the class, like any
method:
obj = MyClass;
value = obj.pi(.001);
7-26
Overloading Functions for Your Class
In cases where a class defines a function with the same name as a global
function, the class’s implementation of the function is said to overload the
original global implementation.
For example, suppose you define a class to represent polynomials that can
have only single precision coefficients. You want a roots method to work
on objects of your new class, but want to use the existing MATLAB roots
function, which accepts a row vector of doubles that are the coefficients of a
polynomial, ordered in descending powers.
7-27
7 Methods — Defining Class Operations
methods
function rts = roots(polyobject)
% Extract data for MATLAB version of roots function
coef = double(polyobject.coefficients);
rts = roots(coef);
end
end
For example, the addition + (plus) function cannot add two polynomials
because this operation is not defined by simple addition. However, a
polynomial class can define its own plus method that the MATLAB language
calls to perform addition of polynomial objects when you use the + symbol:
p1 + p2
7-28
Overloading Functions for Your Class
• You can reuse names that you have used in unrelated classes.
• You can reuse names in subclasses if the member does not have public or
protected access. These names then refer to entirely different methods,
properties, and events without affecting the superclass definitions
• Within a class, all names exist in the same name space and must be unique.
A class cannot define two methods with the same name and a class cannot
define a subfunction with the same name as a method.
• The name of a static method is considered without its class prefix. Thus,
a static method name without its class prefix cannot match the name of
any other method.
7-29
7 Methods — Defining Class Operations
objectA + objectB
Ordinarily, objects have equal precedence and the method associated with the
left-most object is called. However, there are two exceptions:
p = DocPolynom([1 0 -2 -5])
p =
x^3-2*x-5
the expression:
1 + p
ans =
x^3-2*x-4
7-30
Object Precedence in Expressions Using Operators
places a class below other classes in the precedence hierarchy. Define the
InferiorClasses property in the classdef statement:
This attribute establishes a relative priority of the class being defined with
the order of the classes listed.
objectA + objectB
See “Rules for Naming to Avoid Conflicts” on page 7-28 for related information.
7-31
7 Methods — Defining Class Operations
Callback Arguments
You can use class methods as callbacks for Handle Graphics objects by
specifying the callback as an anonymous function. Anonymous functions
enable you to pass the arguments required by methods (i.e., the first argument
is a class object) and graphics object callbacks (i.e., the event source and the
event data), as well as any other arguments you want to pass to the function.
Background Information
@(src,event)method_name(object,src,event,additional_arg,...)
You must define the callback method with the following signature:
method_name(object,src,event)
7-32
Class Methods for Graphics Callbacks
classdef SeaLevelAdjuster
properties
Slider
end
methods
function seal = SeaLevelAdjuster
...
seal.Slider = uicontrol('Style','slider');
set(seal.Slider,'Callback',@(src,event)slider_cb(seal,src,event))
end
end
end
This class assigns the Callback property in a separate set statement so that
the value object’s (seal) Slider property has been defined when you create
the function handle. Otherwise, Handle Graphics freezes seal before the
uicontrol’s handle is assigned to the Slider property.
7-33
7 Methods — Defining Class Operations
methods
function seal = SeaLevelAdjuster
...
seal.Slider = uicontrol('Style','slider',...
'Callback',@(src,event)slider_cb(seal,src,event));
end
end
end
Class Properties
The class defines properties to store graphics object handles and the
calculated color limits:
7-34
Class Methods for Graphics Callbacks
Class Constructor
The class constructor creates the graphics objects and assigns the slider
callback (last line in code snippet):
methods
function seal = SeaLevelAdjuster(x,map)
seal.Figure = figure('Colormap',map,...
'Resize','off',...
'Position',[100 100 560 580]);
seal.Axes = axes('DataAspectRatio',[1 1 1],...
'XLimMode','manual',...
'YLimMode','manual',...
'DrawMode','fast',...
'Parent',seal.Figure);
seal.Image = image(x,'CDataMapping','scaled','Parent',seal.Axes);
seal.CLimit = get(seal.Axes,'CLim');
seal.Slider = uicontrol('Style','slider',...
'Parent',seal.Figure,...
'Max',seal.CLimit(2),...
'Min',seal.CLimit(1)-1,...
'Value',seal.CLimit(1),...
'Units','normalized',...
'Position',[.9286 .1724 .0357 .6897],...
'SliderStep',[.005 .002],...
'Callback',@(src,event)slider_cb(seal));
end % SeaLevelAdjuster
end % methods
The callback function for the slider is defined to accept the three required
arguments — a class instance, the handle of the event source, and the event
data:
methods
function slider_cb(seal)
min_val = get(seal.Slider,'Value');
max_val = max(max(get(seal.Image,'CData')));
set(seal.Axes,'CLim',[min_val max_val])
drawnow
end % slider_cb
end % methods
7-35
7 Methods — Defining Class Operations
load cape
After loading the data, create a SeaLevelAdjuster object for the image:
seal = SeaLevelAdjuster(X,map)
Move the slider to change the apparent sea level and visualize what would
happen to Cape Cod if the sea level were to rise.
7-36
Class Methods for Graphics Callbacks
50
100
150
200
250
300
350
50 100 150 200 250 300 350
7-37
7 Methods — Defining Class Operations
7-38
8
Object Arrays
Basic Knowledge
The material presented in this section builds on an understanding of the
information presented in the following sections.
8-2
Creating Object Arrays
classdef DocArrayExample
properties
Value
end
methods
function obj = DocArrayExample(F)
if nargin ~= 0 % Allow nargin == 0 syntax
m = size(F,1);
n = size(F,2);
obj(m,n) = DocArrayExample; % Preallocate object array
for i = 1:m
for j = 1:n
obj(i,j).Value = F(i,j);
end
end
end
end
8-3
8 Object Arrays
end
end
To preallocate the object array, assign the last element of the array
first. MATLAB fills the first to penultimate array elements with default
DocArrayExample objects.
After preallocating the array, assign each object Value property to the
corresponding value in the input array F. For example:
classdef SimpleClass
properties
Value
end
methods
function obj = SimpleClass(v)
obj.Value = v;
end
end
end
a(1,7) = SimpleClass(7)
Error using SimpleClass>SimpleClass.SimpleClass
Not enough input arguments.
This error occurs because MATLAB calls the constructor with no arguments
to initialize elements 1 through 6 in the array (that is, a(1,1:6)).
Therefore, you must ensure the constructor supports the no input argument
syntax. A simple solution is to test nargin and let the case when nargin
== 0 execute no code, but not error:
8-4
Creating Object Arrays
classdef SimpleClass
properties
Value
end
methods
function obj = SimpleClass(v)
if nargin > 0
obj.Value = v;
end
end
end
end
Using the revised class definition, the previous array assignment statement
executes without error:
a(1,7) = SimpleClass(7)
a =
1x7 SimpleClass
Properties:
Value
The object assigned to array element a(1,7) uses the input argument passed
to the constructor as the value assigned to the property:
a(1,7)
ans =
SimpleClass
Properties:
Value: 7
a(1,1)
ans =
SimpleClass
Properties:
Value: []
8-5
8 Object Arrays
MATLAB calls the SimpleClass constructor once and copies the returned
object to each element of the array.
ary = SimpleClass.empty(5,0);
8-6
Creating Object Arrays
ary = SimpleClass.empty(5,0);
class(ary)
ans =
SimpleClass
ary(1)
Index exceeds matrix dimensions.
ary(5).Value = 7;
ary(5).Value
ans =
ary(1).Value
ans =
[]
In this case, MATLAB populates array elements one through five with
SimpleClass objects created by calling the class constructor with no
arguments. Then MATLAB assigns the property value 7 to the object at
ary(5).
8-7
8 Object Arrays
property values from the constructed object without calling the constructor
for each additional element.
The property RandNumb contains a random number that is assigned from the
InitArray class constructor. The next section uses the InitArray class to
show when MATLAB calls the class constructor when expanding an array.
A(4,5) = InitArray;
A(4,5).RandNumb
ans =
59
8-8
Creating Object Arrays
A(1,1).RandNumb
ans =
91
A(2,2).RandNumb
ans =
91
A(2,3).RandNumb
ans =
91
A(1,1) == A(2,2)
ans =
A(4,5) = InitArray;
results in two calls to the class constructor. The first creates the object for
array element A(4,5). The second creates a default object (no arguments
passed to the constructor) that MATLAB copies to all remaining empty array
elements.
8-9
8 Object Arrays
objarray.PropName
classdef ObjArray
properties
RegProp
end
methods
function obj = ObjArray
% Assign property a random integer
obj.RegProp = randi(100);
end
end
end
Create an array of ObjArray objects and assign all values of the RegProp
property to the propvalues cell array:
for k = 1:5
a(k) = ObjArray;
end
propvalues = {a.RegProp}
propvalues =
8-10
Creating Object Arrays
You cannot reference all the dynamic properties in an object array using a
single statement, as shown in the previous section for ordinary properties.
For example, suppose the ObjArray class subclasses the dynamicprops class,
which enables you to add properties to instances of the ObjArray class.
Create an object array and add dynamic properties to each member of the
array:
You can get the values of the ordinary properties, as with any array:
a.RegProp
ans =
8-11
8 Object Arrays
ans =
85
MATLAB returns an error if you try to access the dynamic properties of all
array elements using this syntax.
a.DynoProp
No appropriate method, property, or field DynoProp
for class ObjArray.
You must refer to each object individually to access dynamic property values:
a(1).DynoProp
ans =
1
a(2).DynoProp
ans =
8-12
Concatenating Objects of Different Classes
Basic Knowledge
The material presented in this section builds on an understanding of the
information presented in the following sections.
The following sections describe these rules in more detail. See “Combining
Unlike Classes” for related information.
8-13
8 Object Arrays
Concatenating Objects
Concatenation combines objects into arrays:
The class of the resulting array, ary, is the same as the class of the objects
being concatenated. Concatenating unlike objects is possible if MATLAB can
convert objects to the dominant class. MATLAB attempts to convert unlike
objects by:
8-14
Concatenating Objects of Different Classes
For example, consider the class ColorClass and two subclasses, RGBColor
and HSVColor:
classdef ColorClass
properties
Color
end
end
The class RGBColor inherits the Color property from ColorClass. RGBColor
stores a color value defined as a three-element vector of red, green, and
blue (RGB) values. The constructor does not restrict the value of the input
argument. It assigns this value directly to the Color property.
The class HSVColor also inherits the Color property from ColorClass.
HSVColor stores a color value defined as a three-element vector of hue,
saturation, brightness value (HSV) values.
8-15
8 Object Arrays
end
end
end
Create an instance of each class and concatenate them into an array. The
RGBColor object is dominant because it is the left most object and neither
class defines a dominance relationship:
class(ary)
ans =
RGBColor
MATLAB can combine these different objects into an array because it can pass
the inferior object of class HSVColor to the constructor of the dominant class.
However, notice that the Color property of the second RGBColor object in the
array actually contains an HSVColor object, not an RGB color specification:
ary(2).Color
ans =
HSVColor
Properties:
Color: [0 1 1]
8-16
Concatenating Objects of Different Classes
classdef ColorClass
properties
Color
end
methods
function rgbObj = RGBColor(obj)
% Convert HSVColor object to RGBColor object
if strcmp(class(obj),'HSVColor')
rgbObj = RGBColor(hsv2rgb(obj.Color));
end
end
function hsvObj = HSVColor(obj)
% Convert RGBColor object to HSVColor object
if strcmp(class(obj),'RGBColor')
hsvObj = HSVColor(rgb2hsv(obj.Color));
end
end
end
end
Create an array of RGBColor and HSVColor objects with the revised superclass:
ans =
RGBColor
MATLAB calls the converter method for the HSVColor object, which it inherits
from the superclass. The second array element is now an RGBColor object
with an RGB color specification assigned to the Color property:
ary(2)
8-17
8 Object Arrays
ans =
RGBColor
Properties:
Color: [1 0 0]
ary(2).Color
ans =
1 0 0
If the left-most object is of class HSVColor, the array ary is also of class
HSVColor, and MATLAB converts the Color property data to HSV color
specification.
1x2 HSVColor
Properties:
Color
ary(2).Color
ans =
0 1 1
8-18
Concatenating Objects of Different Classes
Your applications might require additional error checking and other coding
techniques. The classes in these examples are designed only to demonstrate
concepts.
8-19
8 Object Arrays
8-20
9
See “Events and Listeners — Concepts” on page 9-11 for a more thorough
discussion of the MATLAB event model.
• Only handle classes can define events and listeners (See “Naming Events”
on page 9-18 for syntax).
• Call the handle notify method to trigger the event (See “Triggering
Events” on page 9-18, and “Defining and Triggering an Event” on page 9-4,
for examples). The event notification broadcasts the named event to all
listeners registered for this event.
9-2
Learning to Use Events and Listeners
9-3
9 Events — Sending and Responding to Messages
The “Defining the Event Data” on page 9-5 section shows an implementation
of this subclass.
See “Defining Event-Specific Data” on page 9-21 for another example that
subclasses event.EventData.
9-4
Learning to Use Events and Listeners
9-5
9 Events — Sending and Responding to Messages
function overflowHandler(eventSrc,eventData)
disp('The value of Prop1 is overflowing!')
disp(['It''s value was: ' num2str(eventData.OrgValue)])
disp(['It''s current value is: ' num2str(eventSrc.Prop1)])
end
end
9-6
Learning to Use Events and Listeners
Use the PropLis class by creating an instance and calling its attachListener
method:
plObj = PropLis;
plObj.ObservedProp
ans =
1
plObj.attachListener
plObj.ObservedProp = 2;
The ObservedProp property has changed.
The new value is: 2
It's defaul value is: 1
9-7
9 Events — Sending and Responding to Messages
The PushButton class creates figure, uicontrol, axes graphics objects and a
listener object in the class constructor.
The push button’s callback is a class method (named pressed). When the
push button is activated, the following sequence occurs:
1 MATLAB executes the pressed method, which graphs a new set of data
and increments the ResultNumber property.
3 The listener callback uses the event data to obtain the handle of the
callback object (an instance of the PushButton class), which then provides
the handle of the axes object that is stored in its AxHandle property.
4 The listener callback updates the axes Title property, after the callback
completes execution, MATLAB sets the ResultsNumber property to its
new value.
9-8
Example – Property Set Listener
9-9
9 Events — Sending and Responding to Messages
end
end
The scatter graph looks similar to this after three push-button clicks:
See “Listening for Changes to Property Values” on page 9-27 for more on
property events.
9-10
Events and Listeners — Concepts
Basically, any activity that you can detect programmatically can generate an
event and communicate information to other objects.
9-11
9 Events — Sending and Responding to Messages
• Listeners execute a callback function when notified that the event has
occurred. “Defining Listener Callback Functions” on page 9-24
• You can bind listeners to the lifecycle of the object that defines the event,
or limit listeners to the existence and scope of the listener object. “Ways
to Create Listeners” on page 9-22
BankAccount
1. The withdraw method is called.
Properties
AccountNumber
if AccountBalance <= 0
AccountBalance
notify(obj,’InsufficientFunds’);
end Methods
deposit
withdraw
Events
InsufficientFunds
2. The notify method
triggers an event, and a
message is broadcast.
InsufficientFunds
InsufficientFunds
9-12
Events and Listeners — Concepts
MATLAB passes the source object to the listener callback in the required
event data argument. This enables you to access any of the object’s public
properties from within your listener callback function.
“Events and Listeners — Syntax and Techniques” on page 9-18 shows the
syntax for defining a handle class and events.
9-13
9 Events — Sending and Responding to Messages
• PreSet — Triggered just before the property value is set, before calling
its set access method
• PostSet — Triggered just after the property value is set
• PreGet — Triggered just before a property value query is serviced, before
calling its get access method
• PostGet — Triggered just after returning the property value to the query
These events are predefined and do not need to be listed in the class events
block.
You can define your own property-change event data by subclassing the
event.EventData class. Note that the event.PropertyEvent class is a sealed
subclass of event.EventData.
See “Listening for Changes to Property Values” on page 9-27 for a description
of the process for creating property listeners.
See “Implementing the PostSet Property Event and Listener” on page 9-47
for an example.
See “Property Access Methods” on page 6-14 for information on methods that
control access to property values.
9-14
Events and Listeners — Concepts
Listeners
Listeners encapsulate the response to an event. Listener objects belong to the
event.listener class, which is a handle class that defines the following
properties:
• Source — Handle or array of handles of the object that generated the event
• EventName — Name of the event
• Callback — Function to execute with an enabled listener receives event
notification
• Enabled — Callback function executes only when Enabled is true. See
“Enabling and Disabling the Listeners” on page 9-50 for an example.
• Recursive — Allow listener to cause the same event that triggered the
execution of the callback
Recursive is true by default. It is possible to create a situation where
infinite recursion reaches the recursion limit and eventually triggers
an error. If you set Recursive to false, the listener cannot execute
recursively if the callback triggers its own event.
9-15
9 Events — Sending and Responding to Messages
Event Attributes
To define other events in the same class definition that have different
attribute settings, create another events block.
Attribute
Name Class Description
Hidden logical Default = If true, event does not appear in list of events returned
false by events function (or other event listing functions or
viewers).
ListenAccess • enumeration, Determines where you can create listeners for the event.
default = public
• public — Unrestricted access
• meta.class object
• protected — Access from methods in class or
• cell array of
subclasses
meta.class
objects • private — Access by class methods only (not from
subclasses)
• List classes that have listen access to this event.
Specify classes as meta.class objects in the form:
- A single meta.class object
- A cell array of meta.class objects. An empty cell
array, {}, is the same as private access.
9-16
Event Attributes
(Continued)
Attribute
Name Class Description
9-17
9 Events — Sending and Responding to Messages
Naming Events
Define an event by declaring an event name inside an events block, typically
in the class that generates the event. For example, the following class creates
an event called ToggledState, which might be triggered whenever a toggle
button’s state changes.
Triggering Events
At this point, the ToggleButton class has defined a name that it associates
with the toggle button state changes—toggling on and toggling off. However,
a class method controls the actual firing of the events. To accomplish this, the
ToggleButton class adds a method to trigger the event:
9-18
Events and Listeners — Syntax and Techniques
end
events
ToggledState
end
methods
...
function OnStateChange(obj,newState)
% Call this method to check for state change
if newState ~= obj.State
obj.State = newState;
notify(obj,'ToggledState'); % Broadcast notice of event
end
end
end
end
The OnStateChange method calls notify to trigger the event, using the
handle of the ToggleButton object that owns the event and the string name
of the event.
Listening to Events
Once the call to notify triggers an event, MATLAB broadcasts a message
to all registered listeners. To register a listener for a specific event, use
the addlistener handle class method. For example, the following class
defines objects that listen for the ToggleState event defined in the class
ToggleButton.
9-19
9 Events — Sending and Responding to Messages
end
end
end
end
The class RespondToToggle adds the listener from within its constructor.
The class defines the callback (handleEvnt) as a static method that accepts
the two standard arguments:
• src — the handle of the object triggering the event (i.e., a ToggleButton
object)
• evtdata — an event.EventData object
The listener executes the callback when the specific ToggleButton object
executes the notify method, which it inherits from the handle class.
tb = ToggleButton;
rtt = RespondToToggle(tb);
tb.OnStateChange(true)
ToggledState is true
tb.OnStateChange(false)
ToggledState is false
Removing Listeners
You can remove a listener object by calling delete on its handle. For example,
if the class RespondToToggle above saved the listener handle as a property,
you could delete the listener:
9-20
Events and Listeners — Syntax and Techniques
methods
function obj = RespondToToggle(toggle_button_obj)
hl = addlistener(toggle_button_obj,'ToggledState',@RespondToToggle.handleEvnt);
obj.ListenerHandle = hl;
end
end
...
end
With this code change, you can remove the listener from an instance of the
RespondToToggle class. For example:
tb = ToggleButton;
rtt = RespondToToggle(tb);
At this point, the object rtt is listening for the ToggleState event triggered
by object tb. To remove the listener, call delete on the property containing the
listener handle:
delete(rtt.ListenerHandle)
methods
9-21
9 Events — Sending and Responding to Messages
notify(obj,'ToggledState',ToggleEventData(newState));
• Use the addlistener method, which binds the listener to the lifecycle of
the object(s) that will generate the event. The listener object persists until
the object it is attached to is destroyed.
• Use the event.listener class constructor. In this case, the listeners you
create are not tied to the lifecycle of the object(s) being listened to. Instead
the listener is active so long as the listener object remains in scope and is
not deleted.
lh = addlistener(obj,'ToggleState',@CallbackFunction)
The listener callback function must accept at least two arguments, which
are automatically passed by the MATLAB runtime to the callback. The
arguments are:
9-22
Events and Listeners — Syntax and Techniques
• The source of the event (that is, obj in the call to addlistener)
• An event.EventData object, or a subclass of event.EventData , such as
the ToggleEventData object described earlier “Defining Event-Specific
Data” on page 9-21.
function CallbackFunction(src,evnt)
...
end
In cases where the event data (evnt) object is user defined, it must be
constructed and passed as an argument to the notify method. For example,
the following statement constructs a ToggleEventData object and passes
it to notify as the third argument:
notify(obj,'ToggledState',ToggleEventData(newState));
lh = event.listener(obj,'ToggleState',@CallbackFunction)
If you want the listener to persist beyond the normal variable scope, you
should use addlistener to create it.
9-23
9 Events — Sending and Responding to Messages
lh.Enabled = false;
Callback Syntax
For an function:
@fuctionName
9-24
Events and Listeners — Syntax and Techniques
@obj.methodName
@ClassName.methodName
hlistener = addlistener(eventSourceObj,'MyEvent',@obj.listenMyEvent)
hlistener =
addlistener(eventSourceObj,'MyEvent',@(src,evnt)listenMyEvent(obj,src,evnt))
methods
function listenMyEvent(obj,src,evnt)
% obj - instance of this class
% src - object generating event
% evnt - the event data
...
end
end
9-25
9 Events — Sending and Responding to Messages
Callback Execution
Listeners execute their callback function when notified that the event
has occurred. Listeners are passive observers in the sense that errors in
the execution of a listener callback does not prevent the execution of other
listeners responding to the same event, or execution of the function that
triggered the event.
9-26
Listening for Changes to Property Values
properties (SetObservable)
% Can define PreSet and PostSet property listeners
% for properties defined in this block
PropOne
PropTwo
...
end
9-27
9 Events — Sending and Responding to Messages
methods (Static)
function handlePropEvents(src,evnt)
switch src.Name % switch on the property name
case 'PropOne'
% PropOne has triggered an event
...
case 'PropTwo'
% PropTwo has triggered an event
...
end
end
end
“Use Class Metadata” on page 14-2 provides more information about the
meta.property class.
9-28
Listening for Changes to Property Values
If the call
addlistener(EventObject,'PropOne','PostSet',@ClassName.handlePropertyEvents);
If your listener callback is an ordinary method and not a static method, the
syntax is:
addlistener(EventObject,'PropOne','PostSet',@obj.handlePropertyEvents);
where obj is the handle of the object defining the callback method.
If the listener callback is a function that is not a class method, you pass a
function handle to that function. Suppose the callback function is a package
function:
addlistener(EventObject,'PropOne','PostSet',@package.handlePropertyEvents);
9-29
9 Events — Sending and Responding to Messages
You could define listeners for other events or other properties using a similar
approach and it is not necessary to use the same callback function for each
listener. See the meta.property and event.PropertyEvent reference pages
for more on the information contained in the arguments passed to the listener
callback function.
9-30
Listening for Changes to Property Values
When AbortSet is true, MATLAB gets the current property value to compare
it to the value you are assigning to the property. This causes the property
get method (get.Property) to execute, if one exists. However, MATLAB
does not catch errors resulting from the execution of this method and these
errors are visible to the user.
9-31
9 Events — Sending and Responding to Messages
Note Save the AbortTheSet class in a file with the same name in a folder on
your MATLAB path.
9-32
Listening for Changes to Property Values
end
end
The class specifies an initial value of 7 for the PropOne property. Therefore, if
you create an object with the property value of 7, there is not need to trigger
the PreSet event:
If you specify a value other than 7, then MATLAB triggers the PreSet event:
Similarly, if you set the PropOne property to the value 9, the AbortSet
attribute prevents the property assignment and the triggering of the PreSet
event. Notice also, that there is not PreGet event generated. Only the
property get method is called:
>> ats.PropOne = 9;
get.PropOne called
>> a = ats.PropOne
Pre-get event triggered
get.PropOne called
9-33
9 Events — Sending and Responding to Messages
Example Overview
This example defines two classes:
• A class-defined event that occurs when a new value is specified for the
MATLAB function
• A property event that occurs when the property containing the limits is
changed
The following diagram shows the relationship between the two objects. The
fcnview object contains a fcneval object and creates graphs from the data it
9-34
Example — Using Events to Update Graphs
contains. fcnview creates listeners to change the graphs if any of the data in
the fcneval object change.
fcnview
Properties
fcneval object fcneval
graph Properties
FofXY
Lm observable
Data
Events
UpdateGraph
Listeners
Lm property
UpdateGraph
fcneval class
fcnview class
You can open all files in your editor by clicking this link:
Open in editor
To use the classes, save the files in folders with the following names:
9-35
9 Events — Sending and Responding to Messages
• @fcneval/fcneval.m
• @fcnview/fcnview.m
• @fcnview/createViews.m
9-36
Example — Using Events to Update Graphs
Method Purpose
fcneval Class constructor. Inputs are function handle and
two-element vector specifying the limits over which to
evaluate the function.
set.FofXY FofXY property set function. Called whenever property
value is set, including during object construction.
set.Lm Lm property set function. Used to test for valid limits.
get.Data Data property get function. This method calculates the
values for the Data property whenever that data is queried
(by class members or externally).
grid A static method (Static attribute set to true) used in the
calculation of the data.
9-37
9 Events — Sending and Responding to Messages
Method Purpose
fcnview Class constructor. Input is fcneval object.
createLisn Calls addlistener to create listeners for
UpdateGraph and Lm property PostSet listeners.
lims Sets axes limits to current value of fcneval object’s
Lm property. Used by event handlers.
updateSurfaceData Updates the surface data without creating a new
object. Used by event handlers.
listenUpdateGraph Callback for UpdateGraph event.
9-38
Example — Using Events to Update Graphs
“Handle Class Methods” on page 5-12 provides a complete list of methods that
are inherited when you subclass the handle class.
Methods Purpose
Inherited
from Handle
Class
addlistener Register a listener for a specific event and attach listener
to event-defining object.
notify Trigger an event and notify all registered listeners.
You create a fcneval object by calling its constructor with two arguments—an
anonymous function and a two-element, monotonically increasing vector.
For example:
Use the createViews static method to create the graphs of the function. Note
that you must use the class name to call a static function:
fcnview.createViews(feobject);
9-39
9 Events — Sending and Responding to Messages
The createView method generates four views of the function contained in the
fcneval object.
Each subplot defines a context menu that can enable and disable the listeners
associated with that graph. For example, if you disable the listeners on
subplot 221 (upper left) and change the MATLAB expression contained
by the fcneval object, only the remaining three subplots update when the
UpdateGraph event is triggered:
9-40
Example — Using Events to Update Graphs
In this figure the listeners are re-enabled via the context menu for subplot
221. Because the listener callback for the property PostSet event also
updates the surface data, all views are now synchronized
9-41
9 Events — Sending and Responding to Messages
9-42
Example — Using Events to Update Graphs
The fcnview class defines a listener for this event. When fcneval triggers
the event, the fcnview listener executes a callback function that performs
the follow actions:
• Determines if the handle of the surface object stored by the fcnview object
is still valid (that is, does the object still exist)
• Updates the surface XData, YData, and ZData by querying the fcneval
object’s Data property.
9-43
9 Events — Sending and Responding to Messages
events
UpdateGraph
end
function set.FofXY(obj,func)
% Determine if function is suitable to create a surface
me = fcneval.isSuitable(func);
if ~isempty(me)
throw(me)
end
% Assign property value
obj.FofXY = func;
% Trigger UpdateGraph event
notify(obj,'UpdateGraph');
end
9-44
Example — Using Events to Update Graphs
set.FofXY issues the exception using the MException throw method. Issuing
the exception terminates execution of set.FofXY and prevents the method
from making an assignment to the property or triggering the UpdateGraph
event.
Other Approaches
The class could have implemented a property set event for the FofXY property
and would, therefore, not need to call notify (see “Listening for Changes
9-45
9 Events — Sending and Responding to Messages
For example, suppose you wanted to update the graph only if the new data
is significantly different. If the new expression produced the same data
within some tolerance, the set.FofXY method could not trigger the event and
avoid updating the graph. However, the method could still set the property
to the new value.
obj.HLUpdateGraph = addlistener(obj.FcnObject,'UpdateGraph',...
@(src,evnt)listenUpdateGraph(obj,src,evnt));
% Add obj to argument list
The fcnview object (obj) is added to the two default arguments (src, evnt)
passed to the listener callback. Keep in mind, the source of the event (src) is
the fcneval object, but the fcnview object contains the handle of the surface
object that is updated by the callback.
function listenUpdateGraph(obj,src,evnt)
if ishandle(obj.HSurface) % If surface exists
obj.updateSurfaceData % Update surface data
end
end
function updateSurfaceData(obj)
9-46
Example — Using Events to Update Graphs
9-47
9 Events — Sending and Responding to Messages
9-48
Example — Using Events to Update Graphs
The PostSet event does not occur until an actual assignment of the property
occurs. The property set function provides an opportunity to deal with
potential assignment errors before the PostSet event occurs.
obj.HLLm = addlistener(obj.FcnObject,'Lm','PostSet',...
@(src,evnt)listenLm(obj,src,evnt)); % Add
obj to argument list
The fcnview object stores a handle to the event.listener object in its HLLm
property, which is used to enable/disable the listener by a context menu (see
“Enabling and Disabling the Listeners” on page 9-50).
The fcnview object (obj) is added to the two default arguments (src, evnt)
passed to the listener callback. Keep in mind, the source of the event (src) is
the fcneval object, but the fcnview object contains the handle of the surface
object that is updated by the callback.
9-49
9 Events — Sending and Responding to Messages
The callback sets the axes limits and updates the surface data because
changing the limits causes the mathematical function to be evaluated over a
different range:
function listenLm(obj,src,evnt)
if ishandle(obj.HAxes) % If there is an axes
lims(obj); % Update its limits
if ishandle(obj.HSurface) % If there is a surface
obj.updateSurfaceData % Update its data
end
end
end
• Listen — Sets the Enabled property for both the UpdateGraph and PostSet
listeners to true and adds a check mark next to the Listen menu item.
• Don’t Listen — Sets the Enabled property for both the UpdateGraph
and PostSet listeners to false and adds a check mark next to the Don’t
Listen menu item.
Both callbacks include the fcnview object as an argument (in addition to the
required source and event data arguments) to provide access to the handle
of the listener objects.
The enableLisn function is called when the user selects Listen from the
context menu.
9-50
Example — Using Events to Update Graphs
function enableLisn(obj,src,evnt)
obj.HLUpdateGraph.Enabled = true; % Enable listener
obj.HLLm.Enabled = true; % Enable listener
set(obj.HEnableCm,'Checked','on') % Check Listen
set(obj.HDisableCm,'Checked','off') % Uncheck Don't Listen
end
The disableLisn function is called when the user selects Don’t Listen from
the context menu.
function disableLisn(obj,src,evnt)
obj.HLUpdateGraph.Enabled = false; % Disable listener
obj.HLLm.Enabled = false; % Disable listener
set(obj.HEnableCm,'Checked','off') % Unheck Listen
set(obj.HDisableCm,'Checked','on') % Check Don't Listen
end
9-51
9 Events — Sending and Responding to Messages
9-52
10
Classification
Organizing classes into hierarchies facilitates the reuse of code and the reuse
of solutions to design problems that have already been solved. You can
think of class hierarchies as sets — supersets (referred to as superclasses or
base classes), and subsets (referred to as subclasses or derived classes). For
example, the following picture shows how you could represent an employee
database with classes.
10-2
Hierarchies of Classes — Concepts
TestEngineer
(is an Engineer)
Properties
TestStage
At the root of the hierarchy is the Employees class. It contains data and
operations that apply to the set of all employees. Contained in the set
of employees are subsets whose members, while still employees, are also
members of sets that more specifically define the type of employee. Subclasses
like TestEngineer are examples of these subsets.
10-3
10 Building on Other Classes
for the intended use of the class. Name, address, and department can be
what all employees have in common.
When designing classes, your abstraction should contain only those elements
that are necessary. For example, the employee hair color and shoe size
certainly characterize the employee, but are probably not relevant to the
design of this employee class. Their sales region is relevant only to some
employee so this characteristic belongs in a subclass.
This relationship implies that objects belonging to a subclass have the same
properties, methods, and events as the superclass, as well as any new features
defined by the subclass. Test this relationship with the isa function.
10-4
Hierarchies of Classes — Concepts
Two points about super and subclass behavior to keep in mind are:
Therefore, you can treat an Engineer object like any other Employees object,
but an Employee object cannot pass for an Engineer object.
Generally, MATLAB does not allow you to create arrays containing a mix of
superclass and subclass objects because an array can be of only one class. If
you attempt to concatenate objects of different classes, MATLAB looks for a
converter method defined by the less dominant class (usually, the left-most
object in the expression is the dominant class).
10-5
10 Building on Other Classes
See “Abstract Classes and Interfaces” on page 10-73 for more information
and an example.
10-6
Creating Subclasses — Syntax and Techniques
Defining a Subclass
To define a class that is a subclass of another class, add the superclass to
the classdef line after a < character:
When inheriting from multiple classes, use the & character to indicate the
combination of the superclasses:
Class Attributes
Subclasses do not inherit superclass attributes.
obj@baseclass1(args);
...
10-7
10 Building on Other Classes
obj@baseclassN(args);
For example, the following segment of a class definition shows a class called
stock that is a subclass of a class called asset.
10-8
Creating Subclasses — Syntax and Techniques
end
end
If you do not explicitly call the superclass constructors from the subclass
constructor, MATLAB implicitly calls these constructors with no arguments.
In this case, the superclass constructors must support no argument syntax.
See “Supporting the No Input Argument Case” on page 7-19 for more
information.
10-9
10 Building on Other Classes
However, always ensure that your class constructor supports the zero
arguments syntax. You can satisfy the need for a zero-argument syntax by
assigning appropriate values to input argument variables before constructing
the object:
For example, the stock class constructor supports the no argument case
with the if statement, but initializes the object for the superclass outside
of the if code block.
10-10
Creating Subclasses — Syntax and Techniques
classdef A
properties
x
y
end
methods
function obj = A(x)
obj.x = x;
end
end
end
Class B inherits properties x and y from class A. The class B constructor calls
the class A constructor to initialize x and then assigns a value to y.
classdef B < A
methods
function obj = B(x,y)
obj = obj@A(x);
obj.y = y;
end
end
end
Class C accepts values for the properties x and y, and passes these values to
the class B constructor, which in turn calls the class A constructor:
classdef C < B
methods
function obj = C(x,y)
obj = obj@B(x,y);
end
end
end
10-11
10 Building on Other Classes
ClassA
ClassB
ClassC
MATLAB always calls the most specific class constructor (ClassC in this case)
first. This approach enables you to process input arguments and perform any
necessary setup before calling the superclass constructors.
If you do not make an explicit call to a superclass constructor from the subclass
constructor, MATLAB makes the implicit call before accessing the object.
The order is always from most specific to least specific and all the superclass
constructors must finish executing before the subclass can access the object.
You can change the order in which class constructors are called by calling
superclass constructors explicitly from the subclass constructor.
10-12
Creating Subclasses — Syntax and Techniques
The old class constructor must be callable with zero input arguments. If not,
see “Old Class Constructor Requires Arguments” on page 10-13.
This technique is useful when reloading objects that you saved using the
old class name. However, the class of the object reflects the new name. For
example,
class(obj)
10-13
10 Building on Other Classes
For example, this subclass defines a foo method, which calls the superclass
foo method
10-14
Modifying Superclass Methods and Properties
function foo(obj)
preprocessing steps
foo@super(obj); % Call superclass foo method
postprocessing steps
end
end
end
classdef super
methods
function foo(obj)
step1(obj)
step2(obj)
step3(obj)
end
end
methods (Access = protected)
function step1(obj)
superclass version
end
...
end
end
The subclass does not reimplement the foo method, it reimplements only
the methods that carry out the series of steps (step1(obj), step2(obj),
step3(obj)). That is, the subclass can specialize the actions taken by each
step, but does not control the order of the steps in the process. When you pass
10-15
10 Building on Other Classes
a subclass object to the superclass foo method, MATLAB calls the subclass
step methods because of the dispatching rules.
In the first case, the superclass is just requesting that you define a concrete
version of this property to ensure a consistent interface. In the second case,
only the superclass can access the private property, so the subclass is free to
reimplement it in any way.
classdef Super
10-16
Modifying Superclass Methods and Properties
If you create an instance of the subclass and use it to call the superclass
method, MATLAB access the private property of the method’s class:
Sub
Properties:
Prop: 1
Methods, Superclasses
>> subObj.superMethod
ans =
10-17
10 Building on Other Classes
There are various situations where you can resolve name and definition
conflicts, as described in the following sections.
Property Conflicts
If two or more superclasses define a property with the same name, then at
least one of the following must be true:
• All, or all but one of the properties must have their SetAccess and
GetAccess attributes set to private
• The properties have the same definition in all superclasses (for example,
when all superclasses inherited the property from a common base class)
Method Conflicts
If two or more superclasses define methods with the same name, then at
least one of the following must be true:
10-18
Subclassing Multiple Classes
• Only one superclass defines the method as Sealed, in which case, the
subclass adopts the sealed method definition.
• The superclasses define the methods as Abstract and rely on the subclass
to define the method.
Event Conflicts
If two or more superclasses define events with the same name, then at least
one of the following must be true:
See “Defining a Subclass” on page 10-7 for the syntax used to derive a subclass
from multiple superclasses.
10-19
10 Building on Other Classes
Basic Knowledge
The material presented in this section builds on an understanding of the
following information:
See “Define a Sealed Hierarchy of Classes” on page 10-22 for more about
this technique.
10-20
Controlling Allowed Subclasses
Use a cell array of meta.class objects to define more than one allowed
subclass:
classdef (AllowedSubclasses =
{?ClassName1,?ClassName2,...?ClassNameN}) MySuperClass
...
end
Always use the fully qualified class name when referencing the class name:
10-21
10 Building on Other Classes
Note Use only the ? operator and the class name to generate meta.class
objects. Values assigned to the AllowedSubclasses attribute cannot contain
any other MATLAB expressions, including functions that return either
meta.class objects or cell arrays of meta.class objects.
Declaring a class as an allowed subclass does not affect whether this class
can itself be subclassed.
Note If MATLAB does not find any of the classes in the allowed classes list,
the class is effectively Sealed. This is equivalent to AllowedSubclasses
= {}.
10-22
Controlling Allowed Subclasses
end
Sealed class hierarchies enable you to use the level of abstraction that your
design requires while maintaining a closed systems of classes.
10-23
10 Building on Other Classes
Basic Knowledge
The material presented in this section builds on an understanding of the
following information:
Related Topics
10-24
Controlling Access to Class Members
10-25
10 Building on Other Classes
Use the class meta.class object to refer to classes in the access list. To specify
more than one class, use a cell array of meta.class objects. Use the package
name when referring to classes that are in packages.
Note You must specify the meta.class objects explicitly (created with the ?
operator), not as values returned by functions or other MATLAB expressions.
Property Access
The following class declares access lists for the property GetAccess and
Access attributes:
classdef PropertyAccess
properties (GetAccess = {?ClassA, ?ClassB}, SetAccess = private)
Prop1
end
properties (Access = ?ClassC)
Prop2
end
end
• Gives the classes ClassA and ClassB get access to the Prop1 property.
• Gives all subclasses of ClassA and ClassB get access to the Prop1 property.
• Does not give get access to Prop1 from subclasses of PropertyAccess.
• Defines private set access for the Prop1 property.
• Gives set and get access to Prop2 for ClassC and its subclasses.
10-26
Controlling Access to Class Members
Method Access
The following class declares an access list for the method Access attribute:
classdef MethodAccess
methods (Access = {?ClassA, ?ClassB, ?MethodAccess})
function listMethod(obj)
...
end
end
end
Event Access
The following class declares an access list for the event ListenAccess
attribute:
classdef EventAccess
events (NotifyAccess = private, ListenAccess = {?ClassA, ?ClassB})
Event1
Event2
end
end
• Limits notify access for Event1 and Event2 to EventAccess; only methods
of the EventAccess can trigger these events.
10-27
10 Building on Other Classes
• Gives listen access for Event1 and Event2 to methods of ClassA and
ClassB. Methods of EventAccess, ClassA, and ClassB can define listeners
for these events. Subclasses of MyClass cannot define listeners for these
events. See “Methods with Access Lists” on page 10-29.
• meta.class objects
• Cell arrays of meta.class objects
• The values public, protected, or private
You must specify these values explicitly, as shown in the example code in
this section.
10-28
Controlling Access to Class Members
classdef GrantAccess
properties (GetAccess = ?NeedAccess)
Prop1 = 7;
end
end
The NeedAccess class defines a method that uses the value of the
GrantAccess Prop1 value. The dispObj is defined as a Static method,
however, it could be an ordinary method.
classdef NeedAccess
methods (Static)
function dispObj(GrantAccessObj)
% Display the value of Prop1
disp(['Prop1 is: ',num2str(GrantAccessObj.Prop1)])
end
end
end
>> a = GrantAccess;
>> a.Prop1
Getting the 'Prop1' property of the 'GrantAccess' class is not allowed.
>> NeedAccess.dispObj(a)
Prop1 is: 7
10-29
10 Building on Other Classes
These sample classes show the behavior of methods called from methods of
other classes that are in the access list. The class AcListSuper gives the
AcListNonSub class access to itsm1 method:
classdef AcListSuper
methods (Access = {?AcListNonSub})
function obj = m1(obj)
disp ('Method m1 called')
end
end
end
Because AcListNonSub is in the access list of m1, its methods can call m1 using
an instance of AcListSuper:
classdef AcListNonSub
methods
function obj = nonSub1(obj,AcListSuper_Obj)
% Call m1 on AcListSuper class
AcListSuper_Obj.m1;
end
function obj = m1(obj)
% Define a method named m1
disp(['Method m1 defined by ',class(obj)])
end
end
end
>> a = AcListSuper;
>> b = AcListNonSub;
>> b.nonSub1(a);
Method m1 called
10-30
Controlling Access to Class Members
>> b.m1;
Method m1 defined by AcListNonSub
10-31
10 Building on Other Classes
>> a = AcListSuper;
>> b = AcListNonSub;
>> c = AcListSub;
>> c.sub1(a);
Error using AcListSuper/m1
Cannot access method 'm1' in class 'AcListSuper'.
The AcListSub sub2 method can call a method of a class that is on the access
list for m1, and that method (nonSub1) does have access to the superclass m1
method:
>> c.sub2(b,a);
Method m1 called
When subclasses are not included in the access list for a method, those
subclasses cannot define a method with the same name. This behavior is
not the same as cases in which the method’s Access is explicitly declared
as private.
For example, adding the following method to the AcListSub class definition
produces an error when you attempt to instantiate the class.
>> c = AcListSub;
Error using AcListSub
Class 'AcListSub' is not allowed to override the method 'm1' because neither it nor its
superclasses have been granted access to the method by class 'AcListSuper'.
10-32
Controlling Access to Class Members
The AcListNonSub class, which is in the m1 method access list, can define a
method that calls the m1 method using an instance of the AcListSub class.
While AcListSub is not in the access list for method m1, it is a subclass of
AcListSuper.
methods
function obj = nonSub2(obj,AcListSub_Obj)
disp('Call m1 via subclass object:')
AcListSub_Obj.m1;
end
end
>> b = AcListNonSub;
>> c = AcListSub;
>> b.nonSub2(c);
Call m1 via subclass object:
Method m1 called
This is consistent with the behavior of any subclass object, which can be
substituted for an instance of its superclass.
When an abstract method has an access list, only the classes in the access list
can implement the method. A subclass that is not in the access list cannot
implement the abstract method so that subclass is itself abstract.
10-33
10 Building on Other Classes
Basic Knowledge
The material presented in this section builds on knowledge of the following
information.
Key Concepts
Handle-compatible class is a class that you can combine with handle classes
when defining a set of superclasses.
10-34
Supporting Both Handle and Value Subclasses — Handle-Compatible Classes
A class that does not explicitly set its HandleCompatible attribute to true is:
• It is a handle class
• Its HandleCompatible attribute is set to true
The HandleCompatible class attribute identifies classes that you can combine
with handle classes when specifying a set of superclasses.
10-35
10 Building on Other Classes
class defines a method to reset property values to the default values defined
in the respective class definition:
The Utility class is handle compatible. Therefore, you can use it in the
derivation of classes that are either handle classes or value classes. See
Chapter 14, “Information from Class Metadata” for information on using
meta-data classes.
Consider the behavior of a value class that subclasses the Utility class. The
PropertyDefaults class defines three properties, all of which have default
values:
10-36
Supporting Both Handle and Value Subclasses — Handle-Compatible Classes
pd = PropertyDefaults
Properties:
p1: ' 4:54 PM'
p2: 'red'
p3: 1.5708
Assign new values that are different from the default values:
pd.p1 = datestr(rem(now,1));
pd.p2 = 'green';
pd.p3 = pi/4;
All pd object property values now contain values that are different from the
default values originally defined by the class:
pd =
PropertyDefaults
Properties:
p1: ' 5:36 PM'
p2: 'green'
p3: 0.7854
Call the resetDefaults method, which is inherited from the Utility class.
Because the PropertyDefaults class is not a handle class, you must return
the modified object for reassignment in the calling function’s workspace.
pd = pd.resetDefaults
pd =
PropertyDefaults
10-37
10 Building on Other Classes
Properties:
p1: ' 4:54 PM'
p2: 'red'
p3: 1.5708
If the PropertyDefaults class was a handle class, then you would not need to
save the object returned by the resetDefaults method. However, to design a
handle compatible class like Utility, you need to ensure that all methods
work with both kinds of classes.
10-38
Supporting Both Handle and Value Subclasses — Handle-Compatible Classes
hpd = HPropertyDefaults;
mc = metaclass(hpd);
mc.HandleCompatible
ans =
hv = ValueSub('MATLAB:narginchk:notEnoughInputs',...
'Not enough input arguments.');
mc = metaclass(hv);
mc.HandleCompatible
ans =
10-39
10 Building on Other Classes
• If an input object is a handle object, then the method can alter the handle
object and these changes are visible to all workspaces that have the same
handle.
• If an input object is a value object, then changes to the object made inside
the method affect only the value inside the method workspace.
Handle compatible methods generally do not alter input objects because the
effect of such changes are not the same for handle and nonhandle objects.
See “Modifying Objects” on page 3-49 for information about modifying handle
and value objects.
isa(obj,'handle')
10-40
Supporting Both Handle and Value Subclasses — Handle-Compatible Classes
end
10-41
10 Building on Other Classes
10-42
Subclassing MATLAB® Built-In Classes
See “Classes (Data Types)” for more information on MATLAB built-in classes.
Note It is an error to define a class that has the same name as a built-in class.
10-43
10 Building on Other Classes
See “Built-In Classes You Cannot Subclass” on page 10-44 for a list of which
MATLAB built-in classes you can subclass.
To see a list of functions that the subclass has inherited as methods, use
the methods function:
methods('SubclassName')
Generally, you can use an object of the subclass with any of the inherited
methods and any functions coded in MATLAB that normally accept input
arguments of the same class as the superclass.
See “Behavior of Built-In Functions with Subclass Objects” on page 10-45 for
information on other required methods.
• char
• cell
• struct
• function_handle
10-44
Subclassing MATLAB® Built-In Classes
Behavior Categories
When you call an inherited method on a subclass of a built-in class, the result
of that call depends on the nature of the operation performed by the method.
The behaviors of these methods fit into several categories.
10-45
10 Building on Other Classes
To list the built-in functions that work with a subclass of a built-in class, use
the methods function.
The sections that follow list the methods you must implement in the subclass
to support indexing and concatenation. Also, the section “Example — Adding
Properties to a Built-In Subclass” on page 10-59 provides an example of these
methods.
10-46
Subclassing MATLAB® Built-In Classes
You can create an instance of the class DocSimpleDouble and call any
methods of the double class.
sc = DocSimpleDouble(1:10);
sc =
DocSimpleDouble
double data:
1 2 3 4 5 6 7 8 9 10
10-47
10 Building on Other Classes
Methods, Superclasses
Calling a method inherited from class double that operates on the data,
like sum, returns a double and, therefore, uses the display method of class
double:
sum(sc)
ans =
55
You can index sc like an array of doubles. The returned value is the class
of the subclass, not double:
a = sc(2:4)
a =
DocSimpleDouble
double data:
2 3 4
Methods, Superclasses
sc(1:5) = 5:-1:1
sc =
DocSimpleDouble
double data:
5 4 3 2 1 6 7 8 9 10
Methods, Superclasses
Calling a method that modifies the order of the data elements operates on the
data, but returns an object of the subclass:
sc = DocSimpleDouble(1:10);
sc(1:5) = 5:-1:1;
a = sort(sc)
a =
DocSimpleDouble
double data:
1 2 3 4 5 6 7 8 9 10
Methods, Superclasses
10-48
Subclassing MATLAB® Built-In Classes
When you call a built-in method on a subclass object, MATLAB uses the
superclass part of the subclass object as inputs to the method, and the value
returned is same class as the built-in class. For example:
sc = DocSimpleDouble(1:10);
a = sin(sc)
class(a)
ans =
double
• reshape
• permute
• sort
• transpose
• ctranspose
10-49
10 Building on Other Classes
Indexing Methods
Built-in classes use specially implemented versions of the subsref, subsasgn,
and subsindex methods to implement indexing (subscripted reference and
assignment). When you index a subclass object, only the built-in data is
referenced (not the properties defined by your subclass). For example,
indexing element 2 in the DocSimpleDouble subclass object returns the
second element in the vector:
sc = DocSimpleDouble(1:10);
a = sc(2)
a =
DocSimpleDouble
double data:
2
Methods, Superclasses
sc(2) = 12
sc =
DocSimpleDouble
double data:
1 12 3 4 5 6 7 8 9 10
Methods, Superclasses
The subsref method also implements dot notation for methods. See “Example
— Adding Properties to a Built-In Subclass” on page 10-59 for an example
of a subsref method.
Concatenation Functions
Built-in classes use the functions horzcat, vertcat, and cat to implement
concatenation. When you use these functions with subclass objects of the
same type, MATLAB concatenates the superclass data to form a new object.
For example, you can concatenate objects of the DocSimpleDouble class:
10-50
Subclassing MATLAB® Built-In Classes
sc1 = DocSimpleDouble(1:10);
sc2 = DocSimpleDouble(11:20);
[sc1 sc2]
ans =
DocSimpleDouble
double data:
Columns 1 through 13
1 2 3 4 5 6 7 8 9 10 11 12 13
Columns 14 through 20
14 15 16 17 18 19 20
Methods, Superclasses
[sc1; sc2]
ans =
DocSimpleDouble
double data:
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
Methods, Superclasses
c = cat(3,sc1,sc2)
c = cat(3,sc1,sc2)
c =
DocSimpleDouble
double data:
(:,:,1) =
1 2 3 4 5 6 7 8 9 10
(:,:,2) =
11 12 13 14 15 16 17 18 19 20
Methods, Superclasses
10-51
10 Building on Other Classes
The class data are matrices of intensity image data stored in the superclass
part of the subclass object. This approach requires no properties.
The DocUint8 class stores the image data, which converts the data, if
necessary:
10-52
Subclassing MATLAB® Built-In Classes
cir = imread('circuit.tif');
img1 = DocUint8(cir);
img1.showImage;
10-53
10 Building on Other Classes
50
100
150
200
250
Because DocUint8 subclasses uint8, you can use any of its methods. For
example,
size(img1)
ans =
280 272
Indexing Operations
Inherited methods perform indexing operations, but return objects of the
same class as the subclass.
10-54
Subclassing MATLAB® Built-In Classes
Therefore, you can index into the image data and call a subclass method:
showImage(img1(100:200,1:160));
10
20
30
40
50
60
70
80
90
100
20 40 60 80 100 120 140 160
img1(100:120,140:160) = 255;
img1.showImage;
10-55
10 Building on Other Classes
50
100
150
200
250
Concatenation Operations
Concatenation operations work on DocUint8 objects because this class inherits
the uint8 horzcat and vertcat methods, which return a DocUint8 object:
showImage([img1 img1]);
10-56
Subclassing MATLAB® Built-In Classes
50
100
150
200
250
Data Operations
Methods that operate on data values, such as arithmetic operators, always
return an object of the built-in type (not of the subclass type). For example,
multiplying DocUint8 objects returns a uint8 object:
showImage(img1.*.8);
??? Undefined function or method 'showImage' for input
arguments of type 'uint8'.
10-57
10 Building on Other Classes
For example:
function o = times(obj,val)
u8 = uint8(obj).*val; % Call uint8 times method
o = DocUint8(u8);
end
Keep in mind that when you override a uint8 method, MATLAB calls
the subclass method and no longer dispatches to the base class method.
Therefore, explicitly call the uint8 times method or an infinite recursion can
occur. Make the explicit call in this statement of the DocUint8 times method:
u8 = uint8(obj).*val;
After adding the times method to DocUint8, you can use the showImage
method in expressions like:
showImage(img1.*1.8);
10-58
Subclassing MATLAB® Built-In Classes
50
100
150
200
250
Methods Implemented
The following methods modify the behavior of the DocExtendDouble class:
10-59
10 Building on Other Classes
Property Added
The DocExtendDouble class defines the DataString property to contain text
that describes the data contained in instances of the DocExtendDouble class.
Keep in mind that the superclass part (double) of the class contains the data.
properties
DataString
end
methods
function obj = DocExtendDouble(data,str)
% Support calling with zero arguments but do not return empty object
if nargin == 0
data = 0;
10-60
Subclassing MATLAB® Built-In Classes
str = '';
elseif nargin == 1
str = '';
end
obj = obj@double(data);
obj.DataString = str;
end
10-61
10 Building on Other Classes
str = horzcat(cellfun(@char,varargin,'UniformOutput',false));
newobj = DocExtendDouble(data,str);
end
function disp(obj)
% Change the default display
disp(obj.DataString)
disp(double(obj))
end
end
end
ed = DocExtendDouble(1:10,'One to ten')
ed =
One to ten
1 2 3 4 5 6 7 8 9 10
The sum function continues to operate on the superclass part of the object:
sum(ed)
ans =
55
10-62
Subclassing MATLAB® Built-In Classes
ed(10:-1:1)
ans =
One to ten
10 9 8 7 6 5 4 3 2 1
However, subscripted assignment does not work because the class does not
define a subsasgn method:
ed(1:5) = 5:-1:1
Error using DocExtendDouble/subsasgn
Cannot use '(' or '{' to index into an object of class 'DocExtendDouble' be
'DocExtendDouble' defines properties and subclasses 'double'.
Click here for more information.
sort(ed)
ans =
One to ten
1 2 3 4 5 6 7 8 9 10
ed = DocExtendDouble(1:10,'One to ten');
a = ed(2)
a =
One to ten
2
whos
Name Size Bytes Class Attributes
a 1x1 132 DocExtendDouble
ed 1x10 204 DocExtendDouble
c = ed.DataString
10-63
10 Building on Other Classes
c =
One to ten
whos
Name Size Bytes Class
c 1x10 20 char
ed 1x10 204 DocExtendDouble
vcat = [ed1;ed2]
vcat =
'One to ten' 'Ten to one'
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1
Both horzcat and vertcat return a new object of the same class as the
subclass.
10-64
Subclassing MATLAB® Built-In Classes
The default size and numel functions behave consistently with user-defined
classes (see “Classes Not Derived from Built-In Classes” on page 10-67).
Other MATLAB functions use size and numel to perform their operations and
you usually do not need to overload them.
When used with subclasses of built-in classes, the size and numel functions
behave the same as in the superclasses.
d = 1:10;
size(d)
ans =
1 10
numel(d)
ans =
10
dsubref = d(7:end);
whos dsub
Name Size Bytes Class Attributes
10-65
10 Building on Other Classes
Create an object and assign to the superclass part of the object the values
1:10:
sd = DocSimpleDouble(1:10);
size(sd)
ans =
1 10
The numel function returns the number of elements in the superclass part:
numel(sd)
ans =
10
size([sd;sd])
10-66
Subclassing MATLAB® Built-In Classes
ans =
2 10
numel([sd;sd])
ans =
20
The DocSimpleDouble class inherits the indexing behavior of the double class:
sdsubref = sd(7:end);
whos sdsubref
Name Size Bytes Class Attributes
classdef VerySimpleClass
properties
Value
end
end
Create an instance of this class and assign a ten-element vector to the Value
property:
vs = VerySimpleClass;
vs.Value = 1:10;
size(vs)
ans =
1 1
numel(vs)
10-67
10 Building on Other Classes
ans =
size([vs;vs])
ans =
2 1
numel([vs;vs])
ans =
size(vs.Value)
ans =
1 10
vssubref = vs.Value(7:end);
whos vssubref
Name Size Bytes Class Attributes
class(vs.Value)
ans =
double
10-68
Subclassing MATLAB® Built-In Classes
vsArray(1:10) = VerySimpleClass;
MATLAB does not apply scalar expansion to object array property value
assignment. Use the deal function for this purpose:
[vsArray.Value] = deal(1:10);
Indexing rules for object arrays are equivalent to those of struct arrays:
v1 = vsArray(1).Value;
>> whos v1
Name Size Bytes Class Attributes
v1 1x10 80 double
vsArray(1).Value(6)
ans =
Keep in mind that other MATLAB functions use the values returned by size.
If you change the way size behaves, ensure that the values returned make
sense for the intended use of your class.
A(index1,index2,...,indexn)
10-69
10 Building on Other Classes
If you define a class in which nargout for subsref or nargin for subsasgn is
different from the value returned by the default numel, then overload numel
for that class to ensure that it returns the correct values.
The DocMuxCard class defines the output rate as a Dependent property, and
then defines a get access method for this property. The get.OutPutRate
method calculates the actual output rate whenever the OutPutRate property
is queried. See “Property Get Methods” on page 6-18 for more information
on this technique.
10-70
Subclassing MATLAB® Built-In Classes
Class Definition
Here is the definition of the DocMuxCard class. Notice that the input port rates
initialize the int32 portion of class.
10-71
10 Building on Other Classes
You can treat an DocMuxCard object like an int32. For example, this
statement accesses the int32 data in the object to determine the names of the
input ports that have a rate of 12:
>> omx.InPutNames(omx==12)
ans =
'inp2' 'inp3'
Indexing the DocMuxCard object accesses the int32 vector of input port rates:
>> omx(1:2)
ans =
3 12
The OupPutRate property get access method uses sum to sum the output port
rates:
>> omx.OutPutRate
ans =
75
10-72
Abstract Classes and Interfaces
Abstract Classes
An abstract class serves as a basis (that is, 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, you cannot instantiate the abstract class. You can only
create instances of the subclasses. These subclasses are sometimes referred
to as concrete classes.
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 commutative
methods (Abstract)
rsult = add(numeric,polynom)
rsult = times(numeric,polynom)
end
end
10-73
10 Building on Other Classes
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.
Abstract Properties
For properties that have Abstract attributes set to true:
Abstract Methods
For methods that have Abstract attributes set to true:
10-74
Abstract Classes and Interfaces
must implement a Data property to contain the data used to generate the
graph. However, the form of the data can differ considerably from one type
of graph to another. Consequently, the way each class implements the Data
property can be different.
The same differences apply to methods. All classes can have a draw method
that creates the graph, but the implementation of this method changes with
the type of graph.
In this example, the interface, derived subclasses, and a utility function are
contained in a package folder:
10-75
10 Building on Other Classes
• AxesHandle — Handle of the axes used for the graph. The specialized
graph objects can set axes object properties and also limit this property’s
SetAccess and GetAccess to protected.
• Data — All specialized graph objects must store data, but the type of data
varies so each subclass defines the storage mechanism. Subclass users can
change the data so this property has public access rights.
The graph class names three abstract methods that subclasses must
implement. The graph class also suggests in comments that each subclass
constructor must accept the plot data and property name/property value pairs
for all class properties.
10-76
Abstract Classes and Interfaces
10-77
10 Building on Other Classes
'Callback',@(src,evnt)zoom(gobj,2),...
'Position',[100 20 60 20]);
end
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 each subclass
must implement), the graph interface imposes a specific design on the whole
package of classes, without limiting flexibility.
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
10-78
Abstract Classes and Interfaces
(graph) and subclass are all contained in a package (graphics), which you
must use to reference the class name:
Adding Properties
The 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, so specifying property values in the
constructor is optional. You can create a linegraph object with no data, but
you cannot produce a graph from that object.
properties
LineColor = [0 0 0];
LineType = '-';
end
10-79
10 Building on Other Classes
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 graph class implements the Data property set method. 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.
10-80
Abstract Classes and Interfaces
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.
10-81
10 Building on Other Classes
10-82
11
• The full name of the object’s class, including any package qualifiers.
• Values of dynamic properties.
• The names and current values of all properties, except:
- Properties that have their Transient, Constant, or Dependent
attributes set to true. See “Specifying Property Attributes” on page 6-7
for a description of property attributes.
You can use property set methods to ensure property values are still valid in
cases where the class definition has changed.
11-2
Understanding the Save and Load Process
See “Property Set Methods” on page 6-16 for information on property set
methods.
In cases where the saved object is derived from multiple superclasses that
define private properties having the same name, the struct contains the
property value of the most direct superclass only.
ans =
1
% Delete the handle object
>> delete(a)
>> isvalid(a)
ans =
11-3
11 Saving and Loading Objects
See the handle class delete method and the clear command for more
information on these operations.
When you issue a save command, MATLAB first calls your saveobj method
and passes the output of saveobj to save. Similarly, when you call load,
MATLAB passes the result of loading what you saved to loadobj. loadobj
must then return a properly constructed object. Therefore, you must design
saveobj and loadobj to work together.
• The class’s properties have changed (just adding a new property does not
necessarily require special code because it can be initialized to its default
value when loaded).
• The order in which properties are initialized is important due to a circular
reference to handle objects.
11-4
Understanding the Save and Load Process
• You must call the object’s constructor with arguments and, therefore,
cannot support a default constructor (no arguments).
Information to Consider
If you decide to modify the default save and load process, keep the following
points in mind:
• If your loadobj method generates an error, MATLAB still loads the objects
in whatever state the object was in before the invocation of loadobj.
• Subclass objects inherit superclass loadobj and saveobj methods.
Therefore, if you do not implement a loadobj or saveobj method in the
most specific class, MATLAB calls only the inherited methods.
If a superclass implements a loadobj or saveobj method, then your
subclass can also implement a loadobj or saveobj method that calls the
superclass methods as necessary. See “Saving and Loading Objects from
Class Hierarchies” on page 11-17 for more information.
• The load function does not call the default constructor by default. See
“Calling Constructor When Loading” on page 11-25 for more information.
• If an error occurs while the object is loading from a file, the load function
passes your loadobj method as much data as it can successfully load
from the file. In case of an error, load passes loadobj a struct whose
field names correspond to the property names extracted from the file. See
“Reconstructing Objects with loadobj” on page 11-15 for an example of a
loadobj method that processes a struct.
See “Tips for Saving and Loading” on page 11-22 for guidelines on saving and
loading objects.
11-5
11 Saving and Loading Objects
• The save function calls your class’s saveobj method before performing the
save operation. The save function then saves the value returned by the
object’s saveobj method. You can use the saveobj method to return a
modified object or any other type of variable, such as a struct array.
• The load function calls your class’s loadobj method after loading the
object. The load function loads into the workspace the value returned
by the object’s loadobj method. If you define a loadobj method you can
modify the object being returned or reconstruct an object from the data
saved by your saveobj method.
If you implement a saveobj method that modifies the object being saved,
implement a loadobj method to return the object to its proper state when
reloading it. For example, you might want to store an object’s data in a
struct array and reconstruct the object when reloaded to manage changes
to the class definition.
MATLAB saves the object’s class name so that load can determine which
loadobj method to call, even if your saveobj method saves only the object’s
data in an array and not the object itself.
11-6
Modifying the Save and Load Process
• The class definition has changed since the object was saved and you need to
modify the object before reloading.
• A saveobj method modified the object during the save operation, perhaps
saving data in an array, and the loadobj method must reconstruct the
object based on the output of saveobj.
In this case, you do not need to implement a saveobj method. You are using
loadobj only to ensure older saved objects are brought up to date before
loading.
The “Save and Load Applications” on page 11-7 section provides an example
in which loadobj performs specific operations to recreate an object based on
the data returned by saveobj during the save operation.
11-7
11 Saving and Loading Objects
11-8
Example — Maintaining Class Compatibility
One of the key elements of this program is that it uses a data structure
to contain the information for each phone book entry. You save these
data structures in MAT-files. This example shows ways to maintain the
compatibility of subsequent versions of the data structures as you implement
new versions of the program.
When the phone book application program loads a particular phone book
entry by reading a variable from a Mat-file, it must ensure that the loaded
data can be used by the current version of the application.
classdef PhoneBookEntry
properties
Name
11-9
11 Saving and Loading Objects
Address
PhoneNumber
end
methods (Static)
function obj = loadobj(obj)
if isstruct(obj)
% Call default constructor
newObj = PhoneBookEntry;
% Assign property values from struct
newObj.Name = obj.Name;
newObj.Address = obj.Address;
newObj.PhoneNumber = obj.PhoneNumber;
obj = newObj;
end
end
end
methods
function obj = saveobj(obj)
s.Name = obj.Name;
s.Address = obj.Address;
s.PhoneNumber = obj.PhoneNumber;
obj = s;
end
end
end
saveobj saves the object data in a struct that uses property names for field
names. This struct is compatible with Version 1 of the product. When the
struct is loaded into Version 2 of the phone book application program, the
static loadobj method converts the struct to a PhoneBookEntry object. For
example, given the previously defined struct V1:
V1 =
The application program can use the loadobj static method to convert this
Version 1 struct to a Version 2 object:
11-10
Example — Maintaining Class Compatibility
V2 = PhoneBookEntry.loadobj(V1)
V2 =
PhoneBookEntry
Properties:
Name: 'MathWorks, Inc.'
Address: '3 Apple Hill Drive, Natick, MA, 01760'
PhoneNumber: '5086477000'
classdef PhoneBookEntry
properties
Name
StreetAddress
City
State
ZipCode
PhoneNumber
end
properties (Constant)
Sep = ', ';
end
properties (Dependent, SetAccess=private)
Address
end
11-11
11 Saving and Loading Objects
properties (Transient)
SaveInOldFormat = 0;
end
methods (Static)
function obj = loadobj(obj)
if isstruct(obj)
% Call default constructor
newObj = PhoneBookEntry;
% Assign property values from struct
newObj.Name = obj.Name;
newObj.Address = obj.Address;
newObj.PhoneNumber = obj.PhoneNumber;
obj = newObj;
end
end
end
methods
function address = get.Address(obj)
address=[obj.StreetAddress obj.Sep obj.City obj.Sep obj.State obj.Sep obj.ZipCode];
end
function obj = set.Address(obj,address)
addressItems = regexp(address,obj.Sep,'split');
if length(addressItems) == 4
obj.StreetAddress = addressItems{1};
obj.City = addressItems{2};
obj.State = addressItems{3};
obj.ZipCode = addressItems{4};
else
error('PhoneBookEntry:InvalidAddressFormat', ...
'Invalid address format.');
end
end
function obj = saveobj(obj)
% If set to true, save as a struct
if obj.SaveInOldFormat
s.Name = obj.Name;
s.Address = obj.Address;
s.PhoneNumber = obj.PhoneNumber;
obj = s;
end
11-12
Example — Maintaining Class Compatibility
end
end
See “Property Access Methods” on page 6-14 for more on property set and
get methods.
11-13
11 Saving and Loading Objects
If the object you are loading requires a call to its class constructor and this
call requires you to pass arguments to the constructor, you can implement a
loadobj method that performs this task. For example, suppose the object’s
constructor adds a listener and, therefore, must be passed a handle to the
object triggering the event (required by the addlistener handle class method)
to create this listener. Your loadobj method could call the constructor with
the required argument.
Example Overview
This example shows how to use loadobj to call a class constructor with
arguments at load time. Because the constructor requires arguments, you
cannot use the ConstructOnLoad attribute to load the object, which causes
a call to the default (no arguments) constructor.
11-14
Passing Arguments to Constructors During Load
The saveobj method extracts the data from the object and writes this data
into a struct, which saveobj returns to the save function.
methods
function A = saveobj(obj)
A.AccountNumber = obj.AccountNumber;
A.AccountBalance = obj.AccountBalance;
end
end
To create a valid object, loadobj calls the constructor using the data saved in
the struct A and passes any other required arguments.
The following loadobj method calls the class constructor with the appropriate
values for the arguments:
methods (Static)
11-15
11 Saving and Loading Objects
11-16
Saving and Loading Objects from Class Hierarchies
If any class in the hierarchy defines special save and load behavior:
11-17
11 Saving and Loading Objects
The following superclass (MySuper) and subclass (MySub) definitions show how
to code these methods. The MySuper class defines a loadobj method to enable
an object of this class to be loaded directly. The subclass loadobj method calls
a method named reload after it constructs the subclass object. reload first
calls the superclass reload method to assign superclass property values and
then assigns the subclass property value.
classdef MySuper
% Superclass definition
properties
X
Y
end
methods
function S = saveobj(obj)
% Save property values in struct
% Return struct for save function to write to MAT-file
S.PointX = obj.X;
S.PointY = obj.Y;
end
function obj = reload(obj,S)
% Method used to assign values from struct to properties
% Called by loadobj and subclass
obj.X = S.PointX;
obj.Y = S.PointY;
end
end
methods (Static)
function obj = loadobj(S)
% Constructs a MySuper object
% loadobj used when a superclass object is saved directly
% Calls reload to assign property values retrived from struct
% loadobj must be Static so it can be called without object
obj = MySuper;
obj = reload(obj,S);
end
end
end
11-18
Saving and Loading Objects from Class Hierarchies
Your subclass implements saveobj and loadobj methods that call superclass
methods.
11-19
11 Saving and Loading Objects
If your class implements a saveobj method that converts the object to another
type of MATLAB variable, such as a struct, you can save the dynamic
property’s attribute values so that your loadobj method can reconstruct these
properties. The attribute values of dynamic properties are not part of the
class definition and might have been set after the properties were attached to
the object, so these values might not be known to the loadobj method.
methods
function s = saveobj(obj)
...
% Obtain the meta.DynamicProperty object for the dynamic property
metaDynoProp = findprop(obj,'DynoProp');
% Record name and value for the dynamic property
s.dynamicprops(1).name = metaDynoProp.Name;
11-20
Saving and Loading Dynamic Properties
s.dynamicprops(1).value = obj.DynoProp;
% Record additional dynamic property attributes so they can be
% restored at load time, for example SetAccess and GetAccess
s.dynamicprops(1).setAccess = metaDynoProp.SetAccess;
s.dynamicprops(1).getAccess = metaDynoProp.GetAccess;
...
end
end
Your loadobj method can add the dynamic property and set the attribute
values:
methods (Static)
function obj = loadobj(s)
% first, create an instance of the class
obj = ClassConstructor;
...
% Add new dynamic property to object
metaDynoProp = addprop(obj,s.dynamicprops(1).name);
obj.(s.dynamicprops(1).name) = s.dynamicprops(1).value;
% Restore dynamic property attributes
metaDynoProp.SetAccess = s.dynamicprops(1).setAccess;
metaDynoProp.GetAccess = s.dynamicprops(1).getAccess;
end
end
11-21
11 Saving and Loading Objects
See “Defining Default Values” on page 3-11 for more information on how
MATLAB evaluates default value expressions.
11-22
Tips for Saving and Loading
classdef Odometer
properties(Constant)
ConversionFactor = 1.6
end
properties
TotalDistance = 0
end
properties(Dependent)
Units
end
properties(Access=private)
PrivateUnits = 'mi'
end
methods
function unit = get.Units(obj)
unit = obj.PrivateUnits;
end
function obj = set.Units(obj, newUnits)
% validate newUnits to be a string
switch(newUnits)
case 'mi'
if strcmp(obj.Units, 'km')
obj.TotalDistance = obj.TotalDistance / ...
obj.ConversionFactor;
11-23
11 Saving and Loading Objects
obj.PrivateUnits = newUnits;
end
case 'km'
if strcmp(obj.Units, 'mi')
obj.TotalDistance = obj.TotalDistance * ...
obj.ConversionFactor;
obj.PrivateUnits = newUnits;
end
otherwise
error('Odometer:InvalidUnits', ...
'Units ''%s'' is not supported.', newUnits);
end
end
end
end
odObj = Odometer;
odObj.Units = 'km';
odObj.TotalDistance = 16;
When you save the object, the following happens to property values:
When you load the object, the following happens to property values:
11-24
Tips for Saving and Loading
• PrivateUnits is loaded and contains the value that is used if the Units
get method is called.
If the Units property was not Dependent, loading it calls its set method and
causes the TotalDistance property to be set again.
You can use Transient properties to reduce storage space and simplify the
load process in cases where:
In cases where the class constructor sets only some property values based
on input arguments, then using ConstructOnLoad is probably not useful.
See “Passing Arguments to Constructors During Load” on page 11-14 for an
alternative.
11-25
11 Saving and Loading Objects
11-26
12
Enumerations
• Constant properties
• Enumerations
Constant Properties
Use constant properties when you want a collection of related constant values
whose values can belong to different types (numeric values, character strings,
and so on). Define properties with constant values by setting the property
Constant attribute. Reference constant properties by name whenever you
need access to that particular value.
See “Properties with Constant Values” on page 13-2 for more information.
Enumerations
Use enumerations when you want to create a fixed set of names representing
a single type of value. You can derive enumeration classes from other classes
to inherit the operations of the superclass. For example, if you define an
enumeration class that subclasses a MATLAB numeric class like double or
int32, the enumeration class inherits all of the mathematical and relational
operations that MATLAB defines for those classes.
12-2
Defining Named Values
12-3
12 Enumerations
Enumerations
In this section...
“Basic Knowledge” on page 12-4
“Using Enumeration Classes” on page 12-5
“Defining Methods in Enumeration Classes” on page 12-9
“Defining Properties in Enumeration Classes” on page 12-9
“Array Expansion Operations” on page 12-11
“Constructor Calling Sequence” on page 12-11
“Restrictions Applied to Enumeration Classes” on page 12-13
“Techniques for Defining Enumerations” on page 12-13
Basic Knowledge
The material presented in this section builds on an understanding of the
information provided in the following sections.
12-4
Enumerations
classdef WeekDays
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
end
end
ClassName.MemberName
today = WeekDays.Tuesday;
>> whos
Name Size Bytes Class Attributes
>> today
today =
12-5
12 Enumerations
Tuesday
Default Methods
Enumeration classes have four methods by default:
>> methods(today)
WeekDays char eq ne
today = WeekDays.Friday;
['Today is ',char(today)]
ans =
Today is Friday
today = WeekDays.Tuesday;
teamMeetings = [WeekDays.Wednesday WeekDays.Friday];
ismember(today,teamMeetings)
12-6
Enumerations
ans =
0
function c = Reminder(day)
% Add error checking here
switch(day)
case WeekDays.Monday
c = 'Department meeting at 10:00';
case WeekDays.Tuesday
c = 'Meeting Free Day!';
case {WeekDays.Wednesday WeekDays.Friday}
c = 'Team meeting at 2:00';
case WeekDays.Thursday
c = 'Volley ball night';
end
end
ans =
enumeration WeekDays
Monday
Tuesday
12-7
12 Enumerations
Wednesday
Thursday
Friday
For example, the Bearing class derives from the uint32 built-in class:
a = Bearing.East;
b = uint32(a);
whos
Name Size Bytes Class Attributes
a 1x1 60 Bearing
b 1x1 4 uint32
12-8
Enumerations
classdef WeekDays
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
end
methods
function tf = isMeetingDay(obj)
tf = ~(WeekDays.Tuesday == obj);
end
end
end
ans =
>> isMeetingDay(WeekDays.Wednesday)
ans =
classdef SyntaxColors
properties
12-9
12 Enumerations
R
G
B
end
methods
function c = SyntaxColors(r, g, b)
c.R = r; c.G = g; c.B = b;
end
end
enumeration
Error (1, 0, 0)
Comment (0, 1, 0)
Keyword (0, 0, 1)
String (1, 0, 1)
end
end
e = SyntaxColors.Error;
e.R
ans =
Because SyntaxColors is a value class (it does not derive from handle), only
the class constructor can set property values:
e.R = 0
Setting the 'R' property of the 'SyntaxColors' class
is not allowed.
12-10
Enumerations
classdef WeekDays
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
end
end
clear
ary(5) = WeekDays.Tuesday;
MATLAB must initialize the values of array elements ary(1:4). The default
value of an enumeration class is the first enumeration member defined by
the class in the enumeration block. The result of the assignment to the fifth
element of the array ary is, therefore:
ary
ary =
For example, the input arguments for the Boolean class are 0 for Boolean.No
and 1 for Boolean.Yes.
12-11
12 Enumerations
The values of 0 and 1 are of class logical because the default constructor
passes the argument to the first superclass. That is,
n = Boolean.No;
MATLAB passes the member argument only to the first superclass. For
example, suppose Boolean derived from another class:
classdef MyBool
methods
function boolValues = testBools(obj)
...
end
end
end
Now, the default Boolean constructor behaves as if defined like this function:
12-12
Enumerations
12-13
12 Enumerations
You can define enumeration classes in ways that are most useful to your
application, as described in the following sections.
Enumerations do not support the colon (:) operator, even if the superclass
does. See “Restrictions Applied to Enumeration Classes” on page 12-13 for
more information.
The constructor can save input arguments in property values. For example,
a Color class can specify a Red enumeration member color with three (Red,
Green, Blue) values:
enumeration
Red (1,0,0)
end
12-14
Enumerations
12-15
12 Enumerations
Basic Knowledge
The material presented in this section builds on an understanding of the
information provided in the following sections.
Note Enumeration classes derived from built-in numeric and logical classes
cannot define properties.
For example, the Results class subclasses the int32 built-in class and
associates an integer value with each of the four enumeration members —
First, Second, Third, and NoPoints.
12-16
Enumerations Derived from Built-In Classes
NoPoints (0)
end
end
Because the enumeration member inherits the methods of the int32 class
(not the colon operator), you can use these enumerations like numeric values
(summed, sorted, averaged, and so on).
isa(Results.Second,'int32')
ans =
For example, use enumeration names instead of numbers to rank two teams:
sum(Team1)
ans =
160
mean(Team1)
ans =
40
sort(Team2,'descend')
ans =
ans =
1 0 0 0
sum(Team1) < sum(Team2)
12-17
12 Enumerations
ans =
Second (50)
int32(50)
a = Boolean.No
12-18
Enumerations Derived from Built-In Classes
a =
No
b = Boolean.off
b =
No
This class derives from the built-in logical class. Therefore, underlying
values for an enumeration member depend only on what value logical
returns when passed that value:
a = Boolean.Yes
a =
Yes
logical(a)
ans =
12-19
12 Enumerations
setFlow = FlowRate.Medium;
setFlow = FlowRate.Medium;
int32(setFlow)
ans =
50
Default Converter
All enumeration classes based on built-in classes have a default conversion
method to convert built-in data to an enumeration member of that class.
For example:
a = Boolean(1)
a =
12-20
Enumerations Derived from Built-In Classes
Yes
Boolean(a)
ans =
Yes
Nonscalar inputs to the converter method return an object of the same size:
Boolean([0,1])
ans =
No Yes
Boolean.empty
ans =
12-21
12 Enumerations
Basic Knowledge
The material presented in this section builds on an understanding of the
information provided in the following sections.
12-22
Mutable (Handle) vs. Immutable (Value) Enumeration Members
classdef WeekDays
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
end
end
a = WeekDays.Monday;
b = WeekDays.Monday;
isequal(a,b)
ans =
a == b
ans =
12-23
12 Enumerations
classdef Colors
properties
R = 0;
G = 0;
B = 0;
end
methods
function c = Colors(r, g, b)
c.R = r; c.G = g; c.B = b;
end
end
enumeration
Red (1, 0, 0)
Green (0, 1, 0)
Blue (0, 0, 1)
end
end
red = Colors.Red;
red.G = 1;
Setting the 'G' property of the 'Colors' class is not allowed.
12-24
Mutable (Handle) vs. Immutable (Value) Enumeration Members
methods
function c = HandleColors(r, g, b)
c.R = r; c.G = g; c.B = b;
end
end
enumeration
Red (1, 0, 0)
... % Other colors omitted
end
end
a = HandleColors.Red;
a.R
ans =
12-25
12 Enumerations
a.R = .8;
After setting the value of the R property to .8, create another instance, b,
of HandleColors.Red:
b = HandleColors.Red;
b.R
ans =
0.8000
The value of the R property of the newly created instance is also 0.8000.
The MATLAB session has only one value for any enumeration member at
any given time.
Clearing the workspace variables does not change the current definition of
the enumeration member HandleColors.Red:
clear
a = HandleColors.Red;
a.R
ans =
0.8000
Clear the class to reload the definition of the HandleColors class (see clear
classes):
clear classes
a = HandleColors.Red;
a.R
12-26
Mutable (Handle) vs. Immutable (Value) Enumeration Members
ans =
If you do not want to allow reassignment of a given property value, set that
property’s SetAccess attribute to immutable.
See “Property Attributes” on page 6-8 for more information about property
attributes.
a = HandleColors.Red;
b = HandleColors.Red;
>> isequal(a,b)
ans =
The property values of a and b are the same, so isequal returns true.
However, unlike nonenumeration handle classes, a and b are the same handle
because there is only one enumeration member. Determine handle equality
using == (the handle eq method).
>> a == b
ans =
See the handle eq method for information on how isequal and == differ when
used with handles.
12-27
12 Enumerations
classdef MachineState
enumeration
Running
NotRunning
end
end
The Machine class represents a machine with start and stop operations. The
MachineState enumerations are easy to work with because of their eq and
char methods, and they result in code that is easy to read.
methods
function start(machine)
if machine.State == MachineState.NotRunning
machine.State = MachineState.Running;
end
disp (machine.State.char)
end
function stop(machine)
if machine.State == MachineState.Running
machine.State = MachineState.NotRunning;
end
disp (machine.State.char)
end
end
end
12-28
Mutable (Handle) vs. Immutable (Value) Enumeration Members
>> m.start
Running
% Stop the machine
>> m.stop
NotRunning
12-29
12 Enumerations
Basic Knowledge
The material presented in this section builds on an understanding of the
information provided in the following sections.
Representing Colors
Suppose you want to use a particular set of colors in all your graphs. You can
define an enumeration class to represent the RGB values of the colors in your
color set. The Colors class defines names for the colors, each of which uses
the RGB values as arguments to the class constructor:
classdef Colors
properties
R = 0;
G = 0;
B = 0;
end
12-30
Enumerations That Encapsulate Data
methods
function c = Colors(r, g, b)
c.R = r; c.G = g; c.B = b;
end
end
enumeration
Blueish (18/255,104/255,179/255)
Reddish (237/255,36/255,38/255)
Greenish (155/255,190/255,61/255)
Purplish (123/255,45/255,116/255)
Yellowish (1,199/255,0)
LightBlue (77/255,190/255,238/255)
end
end
Suppose you want to specify the new shade of red named Reddish:
a = Colors.Reddish;
a.R
ans =
0.9294
a.G
ans =
0.1412
a.B
ans =
0.1490
12-31
12 Enumerations
function h = myPlot(x,y,LineColor)
% Simple plotting function
h = line('XData',x,'YData',y);
r = LineColor.R;
g = LineColor.G;
b = LineColor.B;
set(h,'Color',[r g b])
end
r = Colors.Reddish;
h = myPlot(1:10,1:10,r);
The Cars class uses Colors enumerations to specify a finite set of available
colors. The exact definition of any given color can change independently of
the Cars class.
12-32
Enumerations That Encapsulate Data
end
methods
function obj = Cars(cyl,trans,mpg,colr)
obj.Cylinders = cyl;
obj.Transmission = trans;
obj.MPG = mpg;
obj.Color = colr;
end
function paint(obj,colorobj)
if isa(colorobj,'Colors')
obj.Color = colorobj;
else
[~,cls] = enumeration('Colors');
disp('Not an available color')
disp(cls)
end
end
end
end
The CarPainter class requires its subclasses to define a method called paint:
c1 = Cars.Compact;
c1.Color
ans =
Greenish
12-33
12 Enumerations
c1.paint(Colors.Reddish)
c1.Color
ans =
Reddish
12-34
Saving and Loading Enumerations
Basic Knowledge
See the save and load functions and “Understanding the Save and Load
Process” on page 11-2 for general information on saving and loading objects.
However, when loading these types of enumerations, MATLAB does not check
the values associated with the names in the current class definition. This
behavior results from the fact that simple enumerations have no underlying
values and handle-based enumerations can legally have values that are
different than those defined by the class.
12-35
12 Enumerations
If there are changes to the enumeration class definition that do not prevent
MATLAB from loading the object (that is, all of the named values in the
MAT-File are present in the modified class definition), then MATLAB issues a
warning that the class has changed and loads the enumeration.
In the following cases, MATLAB issues a warning and loads as much of the
saved data as possible as a struct:
Struct Fields
The returned struct has the following fields:
12-36
Saving and Loading Enumerations
12-37
12 Enumerations
12-38
13
Constant Properties
13 Constant Properties
You can define a package of classes defining various sets of constants and
import these classes into any function that needs them.
classdef NamedConst
properties (Constant)
R = pi/180;
D = 1/RadDeg.R;
AccCode = '0145968740001110202NPQ';
RN = rand(5);
end
end
MATLAB evaluates the expressions when loading the class (when you first
reference a constant property from that class). Therefore, the values MATLAB
assigns to RN are the result to a single call to the rand function and do not
change with subsequent references to NamedConst.RN. Calling clear classes
causes MATLAB to reload the class.
13-2
Properties with Constant Values
ClassName.PropName
For example, to use the RadDeg class defined in the previous section, reference
the constant for the degree to radian conversion, R:
radi = 45*RadDeg.R
radi =
0.7854
+Constants/@AstroConstants/AstroConstants.m
The class defines a set of Constant properties with initial values assigned:
classdef AstroConstants
properties (Constant)
C = 2.99792458e8; % m/s
G = 6.67259; % m/kgs
Me = 5.976e24; % Earth mass (kg)
Re = 6.378e6; % Earth radius (m)
end
end
To use this set of constants, reference them with a fully qualified class name.
For example, the following function uses some of the constants defined in
AstroContants:
function E = energyToOrbit(m,r)
E = Constants.AstroConstants.G * Constants.AstroConstants.Me * m * ...
13-3
13 Constant Properties
(1/Constants.AstroConstants.Re-0.5*r);
end
You cannot import class properties. Therefore, use the fully qualified class
name to reference constant properties.
classdef MyCnstClass
properties (Constant)
Instance = MyCnstClass;
end
properties
Date
end
methods (Access = private)
function obj = MyCnstClass
obj.Date = clock;
end
end
end
MyCnstClass.Instance.Date
ans =
1.0e+003 *
ans =
13-4
Properties with Constant Values
1.0e+003 *
ans =
1.0e+003 *
For properties that are not Constant, you cannot use a class instance for
a default value.
13-5
13 Constant Properties
13-6
14
Each block in a class definition has an associated metaclass that defines the
attributes for that block. Each attribute corresponds to a property in the
metaclass. An instance of a metaclass has values assigned to each property
that correspond to the values of the attributes of the associated class block.
meta.package
meta.class
meta.property
meta.DynamicProperty
meta.EnumeratedValue
meta.method
meta.event
Each metaclass has properties, methods, and events that contain information
about the class or class component. See meta.package, meta.class,
meta.property, meta.DynamicProperty, meta.EnumeratedValue,
meta.method and meta.event for more information on these metaclasses.
14-2
Use Class Metadata
Note Metaclass is a term used here to refer to all of the classes in the meta
package. meta.class is a class in the meta package whose instances contain
information about MATLAB classes. Metadata is information about classes
contained in metaclasses.
See the following sections for examples that show how to use metadata:
14-3
14 Information from Class Metadata
14-4
Use Metadata to Inspect Classes and Objects
Inspecting a Class
The EmployeeData class is a handle class with two properties, one of which
has private Access and defines a set access method.
14-5
14 Information from Class Metadata
mc = ?EmployeeData;
ans =
handle
The EmployeeData class has only one superclass. For classes having more
than one superclass, a would contain a meta.class object for each superclass.
Use an indexed reference to refer to any particular superclass:
a(1).Name
mc.SuperclassList(1).Name
ans =
handle
Inspecting Properties
Find the names of the properties defined by the EmployeeData class.
First obtain an array of meta.properties objects from the meta.class
PropertyList property.
mpArray = mc.PropertyList;
The length of mpArray indicates there are two meta.property objects, one for
each property defined by the EmployeeData class:
length(mpArray)
ans =
2
14-6
Use Metadata to Inspect Classes and Objects
prop1 = mpArray(1);
prop1.Name
ans =
EmployeeName
The Name property of the meta.property object identifies the class property
represented by that meta.property object.
mpArray(1).SetMethod
ans =
@D:\MyDir\@EmployeeData\EmployeeData.m>EmployeeData.set.EmployeeName
14-7
14 Information from Class Metadata
classdef WeekDays
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
end
end
mc = ?WeekDays;
mc.EnumerationMemberList(2).Name
ans =
Tuesday
14-8
Find Objects Having Specific Settings
PB(2).addprop('HighSpeedInternet');
PB(2).HighSpeedInternet = '1M';
14-9
14 Information from Class Metadata
NW = findobj(PB,'Name','Nancy Wong');
[NW.Name,' - ',NW.Number]
ans =
H = findobj(PB,'-property','HighSpeedInternet');
H.HighSpeedInternet
ans =
1M
The -property option enables you to omit the value of the property and
search for objects using only the property name.
ans =
5081234568
14-10
Find Objects Having Specific Settings
The cell array, methodNames, contains the names of the abstract methods
in the class.
mc = ?containers.Map;
% findobj returns an array of meta.property objects
% use braces to convert the comman separated list to a cell array
mpArray = findobj(mc.PropertyList,'GetAccess','public');
% create cell array of property names
names = {mpArray.Name};
celldisp(names)
names{1} =
Count
names{2} =
14-11
14 Information from Class Metadata
KeyType
names{3} =
ValueType
isempty(findobj([mc.MethodList(:)],'Static',true))
ans =
You can get the names of any static methods from the meta.method array:
staticMethInfo = findobj([mc.MethodList(:)],'Static',true);
staticMethodInfo(:).Name
ans =
empty
The name of the static method (there is only one in this case) is empty. Here is
the information from the meta.method object for the empty method:
staticMethodInfo
meta.method handle
Package: meta
Properties:
Name: 'empty'
14-12
Find Objects Having Specific Settings
14-13
14 Information from Class Metadata
For example, create a default containers.Map object and use the handle
findprop method to get the meta.property object for the Count property:
mp = findprop(containers.Map,'Count')
mp =
meta.property handle
Package: meta
Properties:
Name: 'Count'
Description: 'Number of pairs in the collection'
DetailedDescription: ''
GetAccess: 'public'
SetAccess: 'private'
Dependent: 1
Constant: 0
Abstract: 0
Transient: 1
Hidden: 0
GetObservable: 0
SetObservable: 0
AbortSet: 0
14-14
Get Information About Properties
GetMethod: []
SetMethod: []
DefiningClass: [1x1 meta.class]
The preceding meta.property display shows that the default Map object
Count property has public GetAccess and private SetAccess, is Dependent,
and Transient. See “Table of Property Attributes” on page 6-8 for a list of
property attributes.
If you are working with a class that is not a handle class, get the
meta.property objects from the meta.class object. All metaclasses are
subclasses of the handle class. Use the metaclass function if you have an
instance or the ? operator with the class name:
mc = ?containers.Map
mc =
meta.class handle
Package: meta
Properties:
Name: 'containers.Map'
Description: 'MATLAB Map Container'
DetailedDescription: 'MATLAB Map Container'
Hidden: 0
Sealed: 0
ConstructOnLoad: 1
HandleCompatible: 1
InferiorClasses: {0x1 cell}
ContainingPackage: [1x1 meta.package]
PropertyList: [4x1 meta.property]
MethodList: [35x1 meta.method]
EventList: [1x1 meta.event]
EnumerationMemberList: [0x1 meta.EnumeratedValue]
SuperclassList: [1x1 meta.class]
14-15
14 Information from Class Metadata
containers.Map class. For example, the name of the property associated with
the meta.property object in element 1 is:
mc.PropertyList(1).Name
ans =
Count
properties('containers.Map')
Count
KeyType
ValueType
The serialization property is Hidden and has its GetAccess and SetAccess
attributes set to private. Therefore, the properties function does not
list it. However, you can get information about this property from its
associated meta.property object (which is the fourth element in the array of
meta.property objects in this case):
mc.PropertyList(4)
ans =
meta.property handle
Package: meta
Properties:
Name: 'serialization'
Description: 'Serialization property.'
DetailedDescription: ''
GetAccess: 'private'
SetAccess: 'private'
Dependent: 0
14-16
Get Information About Properties
Constant: 0
Abstract: 0
Transient: 0
Hidden: 1
GetObservable: 0
SetObservable: 0
AbortSet: 0
GetMethod: []
SetMethod: []
DefiningClass: [1x1 meta.class]
mc = ?containers.Map;
class(mc)
ans =
meta.class
class(mc.PropertyList)
ans =
meta.property
mc.Properties(1)
ans =
[1x1 meta.property]
14-17
14 Information from Class Metadata
class(mc.PropertyList(1).Name)
ans =
char
mc.PropertyList(1).Name([1 end])
ans =
Ct
14-18
Get Information About Properties
14-19
14 Information from Class Metadata
if attrValue
if islogical(attrValue) || strcmp(varargin{1},attrValue)
ii = ii + 1;
cl_array(ii) = {mp.Name};
end
end
end
% Return used portion of array
cl_out = cl_array(1:ii);
end
mapobj =
containers.Map({'rose','bicycle'},{'flower','machine'});
findAttrValue(mapobj,'SetAccess','private')
ans =
findAttrValue(mapobj,'GetAccess','public')
ans =
14-20
Get Property Default Values
meta.property handle
Package: meta
Properties:
Name: 'type'
Description: 'Type of error reporting'
DetailedDescription: ''
GetAccess: 'private'
SetAccess: 'private'
Dependent: 0
Constant: 0
Abstract: 0
Transient: 0
Hidden: 0
GetObservable: 1
SetObservable: 1
AbortSet: 0
GetMethod: []
SetMethod: []
HasDefault: 1
DefaultValue: {}
DefiningClass: [1x1 meta.class]
14-21
14 Information from Class Metadata
1 Getting the meta.property object for the property whose default value
you want to query.
classdef MyDefs
properties
Material = 'acrylic';
InitialValue = 1.0;
end
end
14-22
Get Property Default Values
Follow these steps to obtain the default value defined for the Material
property. Include any error checking that is necessary for your application.
mc = ?MyDefs;
mp = mc.PropertyList;
3 The length of the mp array equals the number of properties. You can use the
meta.property Name property to find the property of interest:
for k = 1:length(mp)
if (strcmp(mp(k).Name,'Material')
4 Before querying the default value of the Material property, test the
HasDefault meta.property to determine if MyClass defines a default
property for this property:
if mp(k).HasDefault
dv = mp(k).DefaultValue;
end
end
end
The DefaultValue property is read only. Changing the default value in the
class definition changes the value of DefaultValue property. You can query
the default value of a property regardless of its access settings.
14-23
14 Information from Class Metadata
MATLAB evaluates these expressions the first time the default value is
needed, such as the first time you create an instance of the class.
classdef MyFoo
properties
Foo
end
end
The meta.property instance for property Foo has a value of false for
HasDefault. The class does not explicitly define a default value for Foo.
Therefore, attempting to access the DefaultValue property causes an error:
mc = ?MyFoo;
mp = mc.PropertyList(1);
mp.HasDefault
ans =
dv = mp.DefaultValue;
No default value has been defined for property Foo
Abstract Property
MyClass defines the Foo property as Abstract:
classdef MyAbst
properties (Abstract)
Foo
end
14-24
Get Property Default Values
end
The meta.property instance for property Foo has a value of false for its
HasDefault property because you cannot define a default value for an
Abstract property. Attempting to access DefaultValue causes an error:
mc = ?MyAbst;
mp = mc.PropertyList(1);
mp.HasDefault
ans =
dv = mp.DefaultValue;
Property Foo is abstract and therefore cannot have a default value.
classdef MyPropEr
properties
Foo = sin(pie/2);
end
end
The meta.property instance for property Foo has a value of true for its
HasDefault property because Foo does have a default value determined by
the evaluation of the expression:
sin(pie/2)
mc = ?MyPropEr;
mp = mc.PropertyList(1);
mp.HasDefault
ans =
14-25
14 Information from Class Metadata
dv = mp.DefaultValue;
Error using pie
Not enough input arguments.
Querying the default value causes the evaluation of the expression and
returns the error.
classdef MyEmptyProp
properties
Foo = [];
end
end
The meta.property instance for property Foo has a value of true for its
HasDefault property. Accessing DefaultValue returns the value []:
mc = ?MyEmptyProp;
mp = mc.PropertyList(1);
mp.HasDefault
ans =
dv = mp.DefaultValue;
dv =
[]
14-26
15
Specializing Object
Behavior
You can change how user-defined objects behave by overloading the function
that controls the particular behavior. To change a behavior, implement the
appropriate method with the same name and signature as the MATLAB
function. If an overloaded method exists, MATLAB calls this method
whenever you perform that action on an object of the class.
15-2
Methods That Modify Default Behavior
15-3
15 Specializing Object Behavior
See “Implementing Operators for Your Class” on page 15-35 for a list of
functions that implement operators like +, >, ==, and so on.
Here is how we use these terms in MATLAB. See “Class Precedence” on page
4-19 for information on how MATLAB determines argument dominance.
Overloading
Overloading means that there is more than one function or method having
the same name within the same scope. MATLAB dispatches to a particular
function or method based on the dominant argument. For example, the
15-4
Methods That Modify Default Behavior
timeseries class overloads the MATLAB plot function. When you call plot
with a timeseries object as an input argument, MATLAB dispatches to the
timeseries class method named plot.
Overriding
Overriding means redefining a method inherited from a superclass. MATLAB
dispatches to the most specific version of the method. That is, if the dominant
argument is an instance of the subclass, then MATLAB calls the subclass
method.
p(3)
However, suppose you define a class to represent polynomials and you want
an indexed reference like:
polyobj(3)
to cause an evaluation of the scalar polynomial object with the value of the
independent variable equal to the index value, 3. You overload the subsref
function for the polynomial class to accomplish this.
Select the appropriate function from the preceding table to change the
behavior indicated. For example, MATLAB displays certain information about
objects when you use the disp function or when you enter a statement that
returns an object and is not terminated by a semicolon. Suppose you want
15-5
15 Specializing Object Behavior
your polynomial class to display the MATLAB expression for the polynomial
represented by the object, instead of the default behavior. The display might
look like this:
>> p
p =
x^3 - 2*x - 5
You can implement this specialized behavior by overloading the disp and
char methods. See “The DocPolynom disp Method” on page 16-10 for an
example that shows how to implement this change.
You might need to overload numel to restore proper behavior when you have
overloaded size to perform an action that is appropriate for your class design.
If the MATLAB runtime produces errors when calling your class’s overloaded
subsref or subsagn methods because nargout is wrong for subsref or nargin
15-6
Methods That Modify Default Behavior
is wrong for subsasgn, then you need to overload numel to return a value that
is consistent with your implementation of these indexing functions.
See “Understanding size and numel” on page 10-65 and “Indexed Reference
and Assignment” on page 15-13 for more information on implementing
subsref and subsagn methods.
obj.methodName(args)
See “Determining Which Method Is Invoked” on page 7-9 for more information.
15-7
15 Specializing Object Behavior
Default Concatenation
You can concatenate objects into arrays. For example, suppose you have three
instances of the class MyClass, obj1, obj2, obj3. You can form various arrays
with these objects using brackets. Horizontal concatenation calls horzcat:
HorArray = [obj1,obj2,obj3];
HorArray is a 1–by–3 array of class MyClass. You can concatenate the objects
along the vertical dimension, which calls vertcat:
VertArray = [obj1;obj2;obj3]
VertArray is a 3–by–1 array of class MyClass. You can use the cat function
to concatenate arrays along different dimensions. For example:
ndArray = cat(3,HorArray,HorArray);
You can overload horzcat, vertcat, and cat to produce specialized behaviors
in your class. You must overload both horzcat and vertcat whenever you
want to modify object concatenation because MATLAB uses both functions for
any concatenation operation.
15-8
Displaying Objects in the Command Window
Default Display
MATLAB calls a method named display whenever an object is referred to in
a statement that is not terminated by a semicolon. For example, the following
statement creates the variable a and calls the MATLAB display method for
class double. This method displays the value of a in the command line.
a = 5
a =
5
All MATLAB objects use default disp and display functions. You do not
need to overload the defaults, but you can overload in cases where you want
objects to display in different ways.
You can define a disp method for your classes if you want MATLAB to display
more useful information on the command line when referring to objects from
your class. In many classes, disp can print the variable name, and then use
the char converter method to print the contents of the variable. You need
to define the char method to convert the object’s data to a character string
because MATLAB displays output as character strings.
You might also use sprintf or other data formatting functions to implement
the disp method for your class.
15-9
15 Specializing Object Behavior
15-10
Converting Objects to Another Class
For example, suppose you have defined a polynomial class, but you have not
overloaded any of the MATLAB functions that operate on the coefficients
of polynomials, which are doubles. If you create a double method for the
polynomial class, you can use it to call other functions that require inputs of
type double.
roots(double(p))
A(1) = myobj;
15-11
15 Specializing Object Behavior
variable. To do this, MATLAB first searches for a method of the RHS class
that has the same name as the LHS class. Such a method is a converter
method, which is similar to a typecast operation in other languages.
If the RHS class does not define a method to convert from the RHS class to
the LHS class, then MATLAB software calls the LHS class constructor and
passes it to the RHS variable.
You can create arrays of objects of different classes using cell arrays (see cell
for more information on cell arrays).
15-12
Indexed Reference and Assignment
Overview
This section describes how indexed reference and assignment work in
MATLAB, and provides information on the behaviors you can modify. There
are also examples of classes that modify the default indexing behavior.
MATLAB provides support for object array indexing by default and many
class designs will require no modification to this behavior. The information in
this section can help you determine if modifying object indexing is useful for
your class design and can show you how to approach those modifications.
15-13
15 Specializing Object Behavior
A =
4 8 5 7
4 2 6 3
7 5 7 7
% Create a 1-by-3 array of the numbers 3, 6, 9
B = [3 6 9];
You can reference and assign elements of either array using index values
in parentheses:
B(2) = A(3,4);
B
B =
3 2 9
C = A(3,4);
C(4) = 7;
The MATLAB default subsref and subsasgn functions also work with
user-defined objects. For example, suppose you want to create an array
of objects of the same class:
for k=1:3
objArray(k) = MyClass;
end
Referencing the second element in the object array, objArray, returns the
object constructed when k = 2:
D = objArray(2);
15-14
Indexed Reference and Assignment
class(D)
ans =
MyClass
You also can assign an object to an array of objects of the same class, or an
uninitialized variable (see “Creating Empty Arrays” on page 8-6 for related
information):
newArray(3,4) = D;
Arrays of objects behave much like numeric arrays in MATLAB. You do not
need to implement any special methods to provide this behavior with your
class.
15-15
15 Specializing Object Behavior
obj.Data(2,3)
returns the value contained in the second row, third column of the array. If
you have an array of objects, you can use an expression like:
objArray(3).Data(4:end)
to return the fourth through last elements in the array contained in the Data
property of the third object in the object array, objArray.
Modify the default indexing behavior when your class design requires
behavior that is different from that provided by MATLAB by default.
calls the built-in subsref function. To call the class-defined subsref method,
use:
15-16
Indexed Reference and Assignment
For example, suppose you define a polynomial class with a subsref method
that causes the polynomial to be evaluated with the value of the independent
variable equal to the subscript. This statement defines the polynomial with
its coefficients:
p = polynom([1 0 -2 -5]);
x^3 - 2*x - 5
p(3)
ans =
16
Suppose that you want to use this feature in another class method. To do
so, call the subsref function directly. The evalEqual method accepts two
polynom objects and a value at which to evaluate the polynomials:
methods
function ToF = evalEqual(p1,p2,x)
% Create arguments for subsref
subs.type = '()';
subs.subs = {x};
% Need to call subsref explicity
y1 = subsref(p1,subs);
y2 = subsref(p2,subs);
if y1 == y2
ToF = true;
else
ToF = false;
end
end
end
15-17
15 Specializing Object Behavior
A(I)
A{I}
A.name
B = subsref(A,S)
The first argument is the object being referenced, A. The second argument,
S, is a struct array with two fields:
A(1:4,:)
S.type = '()'
S.subs = {1:4,':'} % A 2-element cell array
% containing the numbers 1 2 3 4 and ":"
15-18
Indexed Reference and Assignment
Returning the contents of each cell of S.subs gives the index values for the
first dimension and a string ':' for the second dimension:
S.subs{:}
ans =
1 2 3 4
ans =
The default subsref returns all array elements in rows 1 through 4 and all
of the columns in the array.
A{1:4}
uses
S.type ='{}'
S.subs = {1:4} % A cell array
% containing the numbers 1 2 3 4
The default subsref returns the contents of all cell array elements in rows
1 through 4 and all of the columns in the array.
The expression
A.Name
S.type = '.'
S.subs = 'Name' % The string 'Name'
The default subsref returns the contents of the Name field in the struct
array or the value of the property Name if A is an object with the specified
property name.
15-19
15 Specializing Object Behavior
A(1,2).PropertyName(1:4)
Writing subsref
Your class’s subsref method must interpret the indexing expressions passed
in by MATLAB. Any behavior you want your class to support must be
implemented by your subsref. However, your method can call the built-in
subsref to handle indexing types that you do not want to change.
You can use a switch statement to determine the type of indexing used and to
obtain the actual indices. The following three code fragments illustrate how
to interpret the input arguments. In each case, the function must return the
value (B) that is returned by your subsref function.
% Handle A(n)
switch S.type
case '()'
B = A(S.subs{:});
end
% Handle A{n}
switch S.type
case '{}'
% Determine what this indexing means to your class
% E.g., CellProperty contained a cell array
B = A.CellProperty{S.subs{:}};
end
15-20
Indexed Reference and Assignment
While braces are used for cell arrays in MATLAB, your subsref method is
free to define its own meaning for this syntax.
For a name index, you might access property values. Method calls require a
second level of indexing if there are arguments. The name can be an arbitrary
string for which you take an arbitrary action:
switch S.type
case '.'
switch S.subs
case 'name1'
B = A.name1;
case 'name2'
B = A.name2;
end
end
Examples of subsref
These links show examples of classes that implement subsref methods:
classdef MyPlot
15-21
15 Specializing Object Behavior
This subsref enables users to use dot notation to perform an action (create a
plot) using the name 'plot'. The statement:
obj = MyPlot(1:10,1:10);
h = obj.plot;
calls the plot function and returns the handle to the graphics object.
15-22
Indexed Reference and Assignment
You do not need to explicitly code each method and property name because
the otherwise code in the inner switch block handles any name reference
that you do not explicitly specify in case statements. However, using this
technique exposes any private and protected class members via dot notation.
For example, you can reference the private property, x, with this statement:
obj.x
ans =
1 2 3 4 5 6 7 8 9 10
The same issue applies to writing a subsasgn method that enables assignment
to private or protected properties. Your subsref and subsasgn methods
might need to code each specific property and method name explicitly to avoid
violating the class design.
A(I) = B
A{I} = B
A.name = B
A = subsasgn(A,S,B)
The first argument, A, is the object being assigned the value in the third
argument B.
15-23
15 Specializing Object Behavior
A(2,3) = B;
S.type = '()'
S.subs = {2,3}
• Determines the class of A. If B is not the same class a A, then MATLAB tries
to construct an object of the same class as A using B as an input argument
(e.g., by calling a converter method, if one exists). If this attempt fails,
MATLAB returns an error.
• If A and B are, or can be made, into the same class, then MATLAB assigns
the value of B to the array element at row 2, column 3.
• If A does not exist before you execute the assignment statement, then
MATLAB initializes the five array elements that come before A(2,3) with
a default object of the class of A and B. For example, empty elements are
initialized to zero in the case of a numeric array or an empty cell ([]) in
the case of cell arrays. See “Creating Empty Arrays” on page 8-6 for more
information on how MATLAB initializes empty arrays.
A{2,3} = B
uses
S.type ='{}'
S.subs = {2,3} % A 2-element cell array containing the numbers 2 and 3
15-24
Indexed Reference and Assignment
The expression
A.Name = B
S.type = '.'
S.subs = 'Name' % The string 'Name'
A.Name = B
S.type = '.'
S.subs = 'Name' % The string 'Name'
15-25
15 Specializing Object Behavior
A(1,2).PropertyName(1:4) = B
15-26
Indexed Reference and Assignment
Class Description
The class has three properties:
d = randi(9,3,4)
d =
8 9 3 9
9 6 5 2
2 1 9 9
obj = MyDataClass(d,'Test001');
The constructor arguments pass the values for the Data and Description
properties. The clock function assigns the value to the Date property from
within the constructor. This approach captures the time and date information
when the instance is created.
Here is the basic code listing without the subsref and subsasgn methods.
classdef MyDataClass
properties
Data
Description
end
properties (SetAccess = private)
Date
end
methods
function obj = MyDataClass(data,desc)
if nargin > 0
obj.Data = data;
end
15-27
15 Specializing Object Behavior
if nargin > 1
obj.Description = desc;
end
obj.Date = clock;
end
end
end
obj(2,3)
ans =
obj.Data(2,3)
Redefining '()' indexing as described here means you cannot create arrays
of MyDataClass objects and use '()' indexing to access individual objects.
Create only scalar objects.
To achieve the design goals, the subsref method calls the builtin subsref
for indexing of type '.' and defines its own version of '()' type indexing.
15-28
Indexed Reference and Assignment
sref = builtin('subsref',obj.Data,s);
return
else
sref = builtin('subsref',obj,s);
end
% No support for indexing using '{}'
case '{}'
error('MYDataClass:subsref',...
'Not a supported subscripted reference')
end
end
obj(2,3) = 9;
is equivalent to:
obj.Data(2,3) = 9;
Like the subsref method, the subsasgn method calls the builtin subsasgn
for indexing of type '.' and defines its own version of '()' type indexing.
Another useful approach is the use of the substruct function to redefine the
index type and index subscripts struct that MATLAB passes to subsref
and subsasgn.
15-29
15 Specializing Object Behavior
if strcmp(class(val),'MYDataClass')
error('MYDataClass:subsasgn',...
'Object must be scalar')
elseif strcmp(class(val),'double')
% Redefine the struct s to make the call: obj.Data(i)
snew = substruct('.','Data','()',s(1).subs(:));
obj = subsasgn(obj,snew,val);
end
end
% No support for indexing using '{}'
case '{}'
error('MYDataClass:subsasgn',...
'Not a supported subscripted assignment')
end
end
function a = double(obj)
a = obj.Data;
end
function c = plus(obj,b)
c = double(obj) + double(b);
end
ans =
8 9 3 9
9 6 5 2
2 1 9 9
15-30
Indexed Reference and Assignment
obj + 7
ans =
15 16 10 16
16 13 12 9
9 8 16 16
ind = end(A,k,n)
where
• A is the object
• k is the index in the expression using the end syntax
• n is the total number of indices in the expression
• ind is the index value to use in the expression
A(end-1,:)
15-31
15 Specializing Object Behavior
MATLAB calls the end method defined for the object A using the arguments
ind = end(A,1,2)
These arguments mean the end statement occurs in the first index element
and there are two index elements. The end class method returns the index
value for the last element of the first dimension (from which 1 is subtracted in
this case). If your class implements an end method, ensure that it returns a
value appropriate for the class.
The end method for the MyDataClass example (see “A Class with Modified
Indexing” on page 15-26) operates on the contents of the Data property. The
objective of this method is to return a value that can replace end in any
indexing expression, such as:
obj(4:end)
obj.Data(2,3:end)
and so on.
The following end function determines a positive integer value for end and
returns it so that MATLAB can plug it into the indexing expression.
15-32
Indexed Reference and Assignment
subsindex must return the value of the object as a zero-based integer index
values in the range 0 to prod(size(X))-1).
Implementing subsindex
MATLAB calls the subsindex method defined for the object used as the index.
For example, suppose you want to use object A to index into object B. B can be
a single object or an array, depending on your objectives.
C = B(A);
15-33
15 Specializing Object Behavior
end
Or, your class might implement a special converter method that returns a
numeric value representing an object based on particular values of object
properties.
15-34
Implementing Operators for Your Class
Overloading Operators
You can implement MATLAB operators (+, *, >, etc.) to work with objects of
your class. Do this by defining the relevant functions as class methods.
Object Precedence
User-defined classes have a higher precedence than built-in classes. For
example, if q is an object of class double and p is a user-defined class,
MyClass, both of these expressions:
q + p
p + q
generate a call to the plus method in the MyClass, if it exists. Whether this
method can add objects of class double and class MyClass depends on how
you implement it.
When p and q are objects of different classes, MATLAB applies the rules of
precedence to determine which method to use.
15-35
15 Specializing Object Behavior
15-36
Implementing Operators for Your Class
15-37
15 Specializing Object Behavior
15-38
16
See “Comparing Handle and Value Classes” on page 5-2 for more information
on value classes.
16-2
Example — A Polynomial Class
To use the class, create a folder named @DocPolynom and save DocPolynom.m
to this folder. The parent folder of @DocPolynom must be on the MATLAB
path.
The following table summarizes the properties defined for the DocPolynom
class.
The following table summarizes the methods for the DocPolynom class.
Name Description
DocPolynom Class constructor
double Converts a DocPolynom object to a double (i.e., returns
its coefficients in a vector)
char Creates a formatted display of the DocPolynom object as
powers of x and is used by the disp method
disp Determines how MATLAB displays a DocPolynom
objects on the command line
subsref Enables you to specify a value for the independent
variable as a subscript, access the coef property with
dot notation, and call methods with dot notation.
plus Implements addition of DocPolynom objects
16-3
16 Implementing a Class for Polynomials
Name Description
minus Implements subtraction of DocPolynom objects
mtimes Implements multiplication of DocPolynom objects
roots Overloads the roots function to work with DocPolynom
objects
polyval Overloads the polyval function to work with
DocPolynom objects
diff Overloads the diff function to work with DocPolynom
objects
plot Overloads the plot function to work with DocPolynom
objects
p1 = DocPolynom([1 0 -2 -5])
p1 =
x^3 - 2*x - 5
p2 = DocPolynom([2 0 3 2 -7])
p2 =
2*x^4 + 3*x^2 + 2*x - 7
Find the roots of the polynomial using the overloaded root method.
>> roots(p1)
ans =
16-4
Example — A Polynomial Class
2.0946
-1.0473 + 1.1359i
-1.0473 - 1.1359i
The MATLAB runtime calls the plus method defined for the DocPolynom
class when you add two DocPolynom objects.
p1 + p2
ans =
2*x^4 + x^3 + 3*x^2 - 12
16-5
16 Implementing a Class for Polynomials
p = DocPolynom([1 0 -2 -5])
p =
x^3 - 2*x -5
This statement creates an instance of the DocPolynom class with the specified
coefficients. Note how class methods display the equivalent polynomial using
MATLAB language syntax. The DocPolynom class implements this display
using the disp and char class methods.
Some DocPolynom class methods use the length of the coefficient vector to
determine the degree of the polynomial. It is useful, therefore, to remove
leading zeros from the coefficient vector so that its length represents the
true value.
The DocPolynom class stores the coefficient vector in a property that uses
a set method to remove leading zeros from the specified coefficients before
setting the property value.
16-6
Example — A Polynomial Class
if ~isempty(ind);
obj.coef = val(ind(1):end);
else
obj.coef = val;
end
end
See “Property Set Methods” on page 6-16 for more information on controlling
property values.
function c = double(obj)
% DocPolynom/Double Converter
c = obj.coef;
end
p = DocPolynom([1 0 -2 -5])
the statement:
c = double(p)
returns:
c=
16-7
16 Implementing a Class for Polynomials
1 0 -2 -5
class(c)
ans =
double
The char method uses a cell array to collect the string components that make
up the displayed polynomial.
The disp method uses char to format the DocPolynom object for display.
Class users are not likely to call the char or disp methods directly, but
these methods enable the DocPolynom class to behave like other data classes
in MATLAB.
16-8
Example — A Polynomial Class
else
s(ind) = {' - '};
a = -a;
ind = ind + 1;
end
end
if a ~= 1 || d == 0
if a == -1
s(ind) = {'-'};
ind = ind + 1;
else
s(ind) = {num2str(a)};
ind = ind + 1;
if d > 0
s(ind) = {'*'};
ind = ind + 1;
end
end
end
if d >= 2
s(ind) = {['x^' int2str(d)]};
ind = ind + 1;
elseif d == 1
s(ind) = {'x'};
ind = ind + 1;
end
end
d = d - 1;
end
end
str = [s{:}];
end
p = DocPolynom([1 0 -2 -5]);
16-9
16 Implementing a Class for Polynomials
char(p)
ans =
x^3 - 2*x - 5
The value returned by char is a string that you can pass to eval after you
have defined a scalar value for x. For example:
x = 3;
eval(char(p))
ans =
16
This disp method relies on the char method to produce a string representation
of the polynomial, which it then displays on the screen.
function disp(obj)
% DISP Display object in MATLAB syntax
c = char(obj); % char returns a cell array
if iscell(c)
disp([' ' c{:}])
else
disp(c) % all coefficients are zero
end
end
16-10
Example — A Polynomial Class
p = DocPolynom([1 0 -2 -5])
p =
x^3 - 2*x - 5
p = DocPolynom([1 0 -2 -5])
p =
x^3 - 2*x - 5
p([3 4])
ans =
16 51
16-11
16 Implementing a Class for Polynomials
if length(s)>1
b = a.(s(1).subs)(s(2).subs{:}); % method with arguments
else
b = a.(s.subs); % method without input arguments
16-12
Example — A Polynomial Class
end
s(1).type is '.'
s(2).type is '()'
s(1).subs is 'polyval'
s(2).subs is [3 5 7]
When you implement a subsref method for a class, you must implement all
subscripted reference explicitly, as show in the following code listing.
function b = subsref(a,s)
% Implement a special subscripted assignment
switch s(1).type
case '()'
ind = s.subs{:};
b = a.polyval(ind);
case '.'
switch s(1).subs
case 'coef'
b = a.coef;
case 'plot'
a.plot;
otherwise
if length(s)>1
b = a.(s(1).subs)(s(2).subs{:});
else
b = a.(s.subs);
end
end
otherwise
error('Specify value for x as obj(x)')
end
end
16-13
16 Implementing a Class for Polynomials
When overloading arithmetic operators, keep in mind what data types you
want to operate on. In this section, the plus, minus, and mtimes methods
are defined for the DocPolynom class to handle addition, subtraction,
and multiplication on DocPolynom/DocPolynom and DocPolynom/double
combinations of operands.
p + q
The following function redefines the plus (+) operator for the DocPolynom
class:
function r = plus(obj1,obj2)
% Plus Implement obj1 + obj2 for DocPolynom
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
k = length(obj2.coef) - length(obj1.coef);
r = DocPolynom([zeros(1,k) obj1.coef]+[zeros(1,-k) obj2.coef]);
16-14
Example — A Polynomial Class
end
p + 1
function r = minus(obj1,obj2)
% MINUS Implement obj1 - obj2 for DocPolynom
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
k = length(obj2.coef) - length(obj1.coef);
r = DocPolynom([zeros(1,k) obj1.coef]-[zeros(1,-k) obj2.coef]);
end
function r = mtimes(obj1,obj2)
16-15
16 Implementing a Class for Polynomials
p = DocPolynom([1 0 -2 -5])
The following two arithmetic operations call the DocPolynom plus and mtimes
methods:
q = p+1
r = p*q
to produce
q =
x^3 - 2*x - 4
r =
x^6 - 4*x^4 - 9*x^3 + 4*x^2 + 18*x + 20
In the case of DocPolynom objects, the overloaded methods can simply apply
the original MATLAB function to the coefficients (i.e., the values returned
by the coef property).
16-16
Example — A Polynomial Class
function r = roots(obj)
% roots(obj) returns a vector containing the roots of obj
r = roots(obj.coef);
end
p = DocPolynom([1 0 -2 -5]);
roots(p)
ans =
2.0946
-1.0473 + 1.1359i
-1.0473 - 1.1359i
16-17
16 Implementing a Class for Polynomials
function y = polyval(obj,x)
% polyval(obj,x) evaluates obj at the points x
y = polyval(obj.coef,x);
end
function q = diff(obj)
% diff(obj) is the derivative of the DocPolynom obj
c = obj.coef;
d = length(c) - 1; % degree
q = DocPolynom(obj.coef(1:d).*(d:-1:1));
end
function plot(obj)
% plot(obj) plots the DocPolynom obj
r = max(abs(roots(obj)));
x = (-1.1:0.01:1.1)*r;
y = polyval(obj,x);
plot(x,y);
title(['y = ' char(obj)])
xlabel('X')
ylabel('Y','Rotation',0)
grid on
end
Plotting the two DocPolynom objects x and p calls most of these methods:
x = DocPolynom([1 0]);
16-18
Example — A Polynomial Class
p = DocPolynom([1 0 -2 -5]);
plot(diff(p*p + 10*p + 20*x) - 20)
16-19
16 Implementing a Class for Polynomials
16-20
17
The DocAsset class holds the data that is common to all of the specialized
asset subclasses in class properties. The subclasses inherit the super class
properties in addition to defining their own properties. The subclasses are all
kinds of assets.
17-2
Example — A Simple Class Hierarchy
The following diagram shows the properties defined for the classes of assets.
DocAsset
Properties
Description
Date
Type
CurrentValue
The DocStock, DocBond, and DocSavings classes inherit properties from the
DocAsset class. In this example, the DocAsset class provides storage for data
common to all subclasses and shares methods with these subclasses.
• Constructor
17-3
17 Designing Related Classes
To use the class, create a folder named @DocAsset and save DocAsset.m to
this folder. The parent folder of @DocAsset must be on the MATLAB path.
The following table summarizes the properties defined for the DocAsset class.
The following table summarizes the methods for the DocAsset class.
Name Description
DocAsset Class constructor
disp Displays information about this object
set.Type Set function for Type. Property tests for correct
value when property is set.
17-4
Example — A Simple Class Hierarchy
properties
Description = '';
CurrentValue = 0;
end
properties(SetAccess = private)
Date % Set value in constructor
Type = 'savings'; % Provide a default value
end
function a = DocAsset(description,type,current_value)
% DocAsset constructor
if nargin > 0
17-5
17 Designing Related Classes
a.Description = description;
a.Date = date;
a.Type = type;
a.CurrentValue = current_value;
end
end % DocAsset
properties
Type = 'cash';
end
The only exception is the set.Type function itself, where the statement:
obj.Type = type;
17-6
Example — A Simple Class Hierarchy
simply formats the data for display in a way that is consistent with the
formatting of the child’s disp method:
function disp(a)
% Display a DocAsset object
fprintf('Description: %s\nDate: %s\nType: %s\nCurrentValue:%9.2f\n',...
a.Description,a.Date,a.Type,a.CurrentValue);
end % disp
The DocAsset subclass display methods can now call this method to display
the data stored in the parent class. This approach isolates the subclass disp
methods from changes to the DocAsset class.
To use the class, create a folder named @DocStock and save DocStock.m to
this folder. The parent folder of @DocStock must be on the MATLAB path.
17-7
17 Designing Related Classes
The following table summarizes the properties defined for the DocStock class.
The following table summarizes the methods for the DocStock class.
Name Description
DocStock Class constructor
disp Displays information about the object
17-8
Example — A Simple Class Hierarchy
properties
NumShares = 0;
SharePrice = 0;
end
XdotcomStock = DocStock('Xdotcom',200,23.47);
function s = DocStock(description,num_shares,share_price)
if nargin ~= 3 % Support no argument constructor syntax
description = '';
num_shares = 0;
share_price = 0;
end
17-9
17 Designing Related Classes
s = s@DocAsset(description,'stock',share_price*num_shares);
s.NumShares = num_shares;
s.SharePrice = share_price;
end % DocStock
XdotcomStock = DocStock('Xdotcom',100,25)
the MATLAB runtime looks for a method in the @DocStock folder called disp.
The disp method for the DocStock class produces this output:
Description: Xdotcom
Date: 17-Nov-1998
Type: stock
Current Value: $2500.00
Number of shares: 100
Share price: $25.00
The following function is the DocStock disp method. When this function
returns from the call to the DocAsset disp method, it uses fprintf to display
the Numshares and SharePrice property values on the screen:
function disp(s)
disp@DocAsset(s)
fprintf('Number of shares: %g\nShare price: %3.2f\n',...
s.NumShares,s.SharePrice);
end % disp
17-10
Example — A Simple Class Hierarchy
To use the class, create a folder named @DocBond and save DocBond.m to this
folder . The parent folder of @DocBond must be on the MATLAB path. See the
addpath function for more information.
The following table summarize the properties defined for the DocBond class
The following table summarizes the methods for the DocStock class.
17-11
17 Designing Related Classes
Name Description
DocBond Class constructor
disp Displays information about this object and calls the
DocAsset disp method
calc_value Utility function to calculate the bond’s current
value
properties
FaceValue = 0;
Yield = 0;
CurrentBondYield = 0;
end
17-12
Example — A Simple Class Hierarchy
b = DocBond('xyzbond',100,4.3,6.2);
function b = DocBond(description,face_value,yield,current_yield)
if nargin ~= 4
description = '';
face_value = 0;
yield = 0;
current_yield = 0;
end
market_value = DocBond.calc_value(face_value,yield,current_yield);
b = b@DocAsset(description,'bond',market_value);
b.FaceValue = face_value;
b.Yield = yield;
b.CurrentBondYield = current_yield;
end % DocBond
17-13
17 Designing Related Classes
Calculation of the asset’s market value requires that the yields be nonzero,
and should be positive just to make sense. While the calc_value method
issues no errors for bad yield values, it does ensure bad values are not used
in the calculation of market value.
methods (Static)
function market_value = calc_value(face_value,yield,current_yield)
if current_yield <= 0 || yield <= 0
market_value = face_value;
else
market_value = face_value*yield/current_yield;
end
end % calc_value
end % methods
b = DocBond('xyzbond',100,4.3,6.2)
the MATLAB runtime looks for a method in the @DocBond folder called disp.
The disp method for the DocBond class produces this output:
Description: xyzbond
Date: 17-Nov-1998
Type: bond
Current Value: $69.35
Face value of bonds: $100
Yield: 4.30%
17-14
Example — A Simple Class Hierarchy
The following function is the DocBond disp method. When this function
returns from the call to the DocAsset disp method, it uses fprintf to display
the FaceValue, Yield, and CurrentValue property values on the screen:
function disp(b)
disp@DocAsset(b) % Call DocAsset disp method
fprintf('Face value of bonds: $%g\nYield: %3.2f%%\n',...
b.FaceValue,b.Yield);
end % disp
To use the class, create a folder named @DocSavings and save DocSavings.m
to this folder . The parent folder of @DocSavings must be on the MATLAB
path.
The following table summarizes the properties defined for the DocSavings
class.
17-15
17 Designing Related Classes
The following table summarizes the methods for the DocSavings class.
Name Description
DocSavings Class constructor
disp Displays information about this object and calls
the DocAsset disp method
properties
17-16
Example — A Simple Class Hierarchy
InterestRate = 0;
end
sv = DocSavings('MyBank',1000,2.9);
function s = DocSavings(description,balance,interest_rate)
if nargin ~= 3
description = '';
balance = 0;
interest_rate = 0;
end
s = s@DocAsset(description,'savings',balance);
s.InterestRate = interest_rate;
17-17
17 Designing Related Classes
end % DocSavings
sv = DocSavings('MyBank',1000,2.9)
the MATLAB runtime looks for a method in the @DocSavings folder called
disp. The disp method for the DocSavings class produces this output:
Description: MyBank
Date: 17-Nov-1998
Type: savings
Current Value: $1000.00
Interest Rate: 2.90%
The following function is the DocSaving disp method. When this function
returns from the call to the DocAsset disp method, it uses fprintf to display
the Numshares and SharePrice property values on the screen:
function disp(b)
disp@DocAsset(b) % Call DocAsset disp method
fprintf('%s%3.2f%%\n','Interest Rate: ',s.InterestRate);
end % disp
17-18
Example — Containing Assets in a Portfolio
Kinds of Containment
Aggregation is the containment of objects by other objects. The basic
relationship is that each contained object "is a part of" the container object.
Composition is a more strict form of aggregation in which the contained
objects are parts of the containing object and are not associated with any
other objects. Portfolio objects form a composition with asset objects because
the asset objects are value classes, which are copied when the constructor
method creates the DocPortfolio object.
17-19
17 Designing Related Classes
The following table summarizes the properties defined for the DocPortfolio
class.
The following table summarizes the methods for the DocPortfolio class.
Name Description
DocPortfolio Class constructor
disp Displays information about this object and calls
the DocAsset disp method
pie3 Overloaded version of pie3 function designed to
take a single portfolio object as an argument
properties
Name = '';
end
17-20
Example — Containing Assets in a Portfolio
• Name — Stores the name of the client as a character string. The client’s
name is passed to the constructor as an input argument.
• IndAsset — A cell array that stores asset objects (i.e., DocStock,
DocBond, and DocSavings objects). These asset objects are passed to the
DocPortfolio constructor as input arguments and assigned to the property
from within the constructor function.
• IndAsset — The structure of this property is known only to DocPortfolio
class member functions so the property’s SetAccess attribute is set to
private.
• TotalValue — Stores the total value of the client’s assets. The class
constructor determines the value of each asset by querying the asset’s
CurrentValue property and summing the result. Access to the TotalValue
property is restricted to DocPortfolio class member functions by setting
the property’s SetAccess attribute to private.
The first step is to create an asset object to represent each type of asset
owned by the client:
17-21
17 Designing Related Classes
VictoriaSelna =
The IndAssets property is a cell array used to store all asset objects. From
these objects, the constructor determines the total value of the client’s assets.
This value is stored in the TotalValue property:
function p = DocPortfolio(name,varargin)
17-22
Example — Containing Assets in a Portfolio
if nargin > 0
p.Name = name;
for k = 1:length(varargin)
p.IndAssets{k} = varargin(k);
asset_value = p.IndAssets{k}{1}.CurrentValue;
p.TotalValue = p.TotalValue + asset_value;
end
end
end % DocPortfolio
function disp(p)
fprintf('\nAssets for Client: %s\n',p.Name);
for k = 1:length(p.IndAssets)
disp(p.IndAssets{k}{1}) % Dispatch to corresponding disp
end
fprintf('\nTotal Value: $%0.2f\n',p.TotalValue);
end % disp
function pie3(p)
% Step 1: Get the current value of each asset
stock_amt = 0; bond_amt = 0; savings_amt = 0;
for k = 1:length(p.IndAssets)
if isa(p.IndAssets{k},'DocStock')
stock_amt = stock_amt + p.IndAssets{k}.CurrentValue;
elseif isa(p.IndAssets{k},'DocBond')
bond_amt = bond_amt + p.IndAssets{k}.CurrentValue;
elseif isa(p.IndAssets{k},'DocSavings')
savings_amt = savings_amt + p.IndAssets{k}.CurrentValue;
end % if
17-23
17 Designing Related Classes
end % for
17-24
Example — Containing Assets in a Portfolio
Visualizing a Portfolio
You can use a DocPortfolio object to present an individual’s financial
portfolio. For example, given the following assets:
you can use the class’s pie3 method to display the relative mix of assets as
a pie chart.
pie3(VictoriaSelna)
17-25
17 Designing Related Classes
17-26
Index
A
Index overloading
arithmetic operators subscripting 15-18
overloading 16-14 objects
as indices into objects 15-32
overloaded function 7-27
C overloading 15-18
classes arithmetic operators 16-14
defining 3-5 functions 16-16
value classes 5-4 pie3 17-23
E P
end method 15-31 pie3 function overloaded 17-23
examples polynomials
container class 17-19 example class 16-2
polynomial class 16-2
R
F reference, subscripted 15-18
functions
overloading 16-16
S
subscripted assignment 15-23
M subscripting
methods overloading 15-18
end 15-31 subsref 15-18
O V
object-oriented programming value classes 5-4
Index-1