Object-Oriented Programming PDF
Object-Oriented Programming PDF
Object-Oriented Programming
R2020a
How to Contact MathWorks
Phone: 508-647-7000
Basic Example
2
Create a Simple Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2
Design Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-2
Create Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-3
Access Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-3
Call Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-3
Add Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-4
Vectorize Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-4
Overload Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-5
BasicClass Code Listing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-6
v
Using BankAccount Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-12
Static Data
4
Static Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-2
What Is Static Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-2
Static Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-2
Static Data Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-3
Constant Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-4
vi Contents
Classdef Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-8
How to Specify Attributes and Superclasses . . . . . . . . . . . . . . . . . . . . . . . 5-8
Class Attribute Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-8
Superclass Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-8
Local Functions in Class File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-9
vii
Use of Editor and Debugger with Classes . . . . . . . . . . . . . . . . . . . . . . . . . 5-37
Write Class Code in the Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-37
How to Refer to Class Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-37
How to Debug Class Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-37
viii Contents
How MATLAB Evaluates Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-10
When MATLAB Evaluates Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . 6-10
Expression Evaluation in Handle and Value Classes . . . . . . . . . . . . . . . . 6-10
ix
Relational Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-12
Test Handle Validity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-12
When MATLAB Destroys Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-12
x Contents
Property Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-13
What You Can Define . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-13
Initialize Property Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-13
Property Default Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-14
Initializing Properties to Handle Objects . . . . . . . . . . . . . . . . . . . . . . . . . 8-14
Assign Property Values in Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . 8-15
Property Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-16
Methods to Set and Get Property Values . . . . . . . . . . . . . . . . . . . . . . . . . 8-16
Reference Object Properties Using Variables . . . . . . . . . . . . . . . . . . . . . 8-17
xi
Get Method Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-48
xii Contents
Specify Method Attributes in classdef File . . . . . . . . . . . . . . . . . . . . . . . . 9-9
Methods You Must Define in the classdef File . . . . . . . . . . . . . . . . . . . . . 9-10
xiii
Use a Class Method for a Slider Callback . . . . . . . . . . . . . . . . . . . . . . . . 9-42
Object Arrays
10
Construct Object Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-2
Build Arrays in the Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-2
Referencing Property Values in Object Arrays . . . . . . . . . . . . . . . . . . . . . 10-2
xiv Contents
Events — Sending and Responding to Messages
11
Overview Events and Listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-2
Why Use Events and Listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-2
Events and Listeners Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-2
Event Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-2
Create Listener . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-3
xv
Determine If Event Has Listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-29
Do Listeners Exist for This Event? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-29
Why Test for Listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-29
Coding Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-29
Listeners in Heterogeneous Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-29
xvi Contents
Modify Inherited Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-13
When to Modify Superclass Methods . . . . . . . . . . . . . . . . . . . . . . . . . . 12-13
Extend Superclass Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-13
Redefine Superclass Methods in Subclass . . . . . . . . . . . . . . . . . . . . . . . 12-13
Override Superclass Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-14
xvii
Subclasses of MATLAB Built-In Types . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-41
MATLAB Built-In Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-41
Built-In Types You Can Subclass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-41
Why Subclass Built-In Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-41
Which Functions Work with Subclasses of Built-In Types . . . . . . . . . . . 12-42
Behavior of Built-In Functions with Subclass Objects . . . . . . . . . . . . . . 12-42
Built-In Subclasses That Define Properties . . . . . . . . . . . . . . . . . . . . . . 12-43
xviii Contents
Define an Interface Superclass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-76
Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12-76
Interface Class Implementing Graphs . . . . . . . . . . . . . . . . . . . . . . . . . . 12-76
xix
Save and Load Objects from Class Hierarchies . . . . . . . . . . . . . . . . . . . . 13-24
Saving and Loading Subclass Objects . . . . . . . . . . . . . . . . . . . . . . . . . . 13-24
Reconstruct the Subclass Object from a Saved struct . . . . . . . . . . . . . . 13-24
Enumerations
14
Named Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-2
Kinds of Predefined Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-2
Techniques for Defining Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . 14-2
xx Contents
Enumerations Derived from Built-In Classes . . . . . . . . . . . . . . . . . . . . . 14-26
Subclassing Built-In Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-26
Derive Enumeration Class from Numeric Class . . . . . . . . . . . . . . . . . . . 14-26
How to Alias Enumeration Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-27
Superclass Constructor Returns Underlying Value . . . . . . . . . . . . . . . . 14-28
Default Converter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14-29
Constant Properties
15
Define Class Properties with Constant Values . . . . . . . . . . . . . . . . . . . . . . 15-2
Defining Named Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15-2
Constant Property Assigned a Handle Object . . . . . . . . . . . . . . . . . . . . . 15-3
Constant Property Assigned Any Object . . . . . . . . . . . . . . . . . . . . . . . . . 15-4
Constant Properties — No Support for Get Events . . . . . . . . . . . . . . . . . 15-5
Class Aliasing
16
Aliases for Class Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-2
When to Use Aliases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-2
Defining Aliases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-2
Alias Definition Folders and Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-3
Aliases and the MATLAB Path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-3
Sequential Renaming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-3
Updating Aliases in a MATLAB Session . . . . . . . . . . . . . . . . . . . . . . . . . . 16-4
Aliasing Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16-4
xxi
Information from Class Metadata
17
Class Metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17-2
What Is Class Metadata? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17-2
The meta Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17-2
Metaclass Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17-3
Metaclass Object Lifecycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17-3
xxii Contents
Object Array Indexing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18-12
Default Indexed Reference and Assignment . . . . . . . . . . . . . . . . . . . . . 18-12
What You Can Modify . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18-13
When to Modify Indexing Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18-13
Built-In subsref and subsasgn Called in Methods . . . . . . . . . . . . . . . . . 18-14
Avoid Overriding Access Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18-15
xxiii
CustomDisplay Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19-3
Methods for Customizing Object Display . . . . . . . . . . . . . . . . . . . . . . . . . 19-3
xxiv Contents
Defining Custom Data Types
20
Representing Polynomials with Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . 20-2
Object Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20-2
DocPolynom Class Members . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20-2
DocPolynom Class Synopsis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20-4
The DocPolynom Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20-10
Remove Irrelevant Coefficients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20-11
Convert DocPolynom Objects to Other Types . . . . . . . . . . . . . . . . . . . . 20-11
Overload disp for DocPolynom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20-13
Display Evaluated Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20-13
Redefine Indexed Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20-14
Define Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20-16
xxv
1
The MATLAB language enables you to create programs using both procedural and object-oriented
techniques and to use objects and ordinary functions together in your programs.
In procedural programming, your design focuses on the steps that must execute to achieve a desired
state. Typically, you represent data as individual variables or fields of a structure. You implement
operations as functions that take the variables as arguments. Programs usually call a sequence of
functions, each one of which is passed data, and then returns modified data. Each function performs
an operation or many operations on the data.
• Identifying the components of the system or application that you want to build
• Analyzing and identifying patterns to determine what components are used repeatedly or share
characteristics
• Classifying components based on similarities and differences
After performing this analysis, you define classes that describe the objects your application uses.
A class describes a set of objects with common characteristics. Objects are specific instances of a
class. The values contained in an object's properties are what make an object different from other
objects of the same class. The functions defined by the class (called methods) are what implement
object behaviors that are common to all objects of a class.
As functions become too large, you can break them into smaller functions and pass data from one to
function to another. However, as the number of functions becomes large, designing, and managing
the data passed to functions becomes difficult and error prone. At this point, consider moving your
MATLAB programming tasks to object-oriented designs.
1-2
Why Use Object-Oriented Design
Thinking in terms of objects is simpler and more natural for some problems. Think of the nouns in
your problem statement as the objects to define and the verbs as the operations to perform.
Consider the design of classes to represent money lending institutions (banks, mortgage companies,
individual money lenders, and so on). It is difficult to represent the various types of lenders as
procedures. However, you can represent each one as an object that performs certain actions and
contains certain data. The process of designing the objects involves identifying the characteristics of
a lender that are important to your application.
Identify Commonalities
What do all money lenders have in common? All MoneyLender objects can have a loan method and
an InterestRate property, for example.
Identify Differences
How does each money lender differ? One can provide loans to businesses while another provides
loans only to individuals. Therefore, the loan operation might need to be different for different types
of lending institutions. Subclasses of a base MoneyLender class can specialize the subclass versions
of the loan method. Each lender can have a different value for its InterestRate property.
Factor out commonalities into a superclass and implement what is specific to each type of lender in
the subclass.
Add Only What Is Necessary
These institutions might engage in activities that are not of interest to your application. During the
design phase, determine what operations and data an object must contain based on your problem
definition.
Objects provide several useful features not available from structures and cell arrays. For example,
objects can:
Reducing Redundancy
As the complexity of your program increases, the benefits of an object-oriented design become more
apparent. For example, suppose that you implement the following procedure as part of your
application:
1 Check inputs
2 Perform computation on the first input argument
3 Transform the result of step 2 based on the second input argument
4 Check validity of outputs and return values
You can implement this procedure as an ordinary function. But suppose that you use this procedure
again somewhere in your application, except that step 2 must perform a different computation. You
1-3
1 Using Object-Oriented Design in MATLAB
could copy and paste the first implementation, and then rewrite step 2. Or you could create a function
that accepted an option indicating which computation to make, and so on. However, these options
lead to more complicated code.
An object-oriented design can factor out the common code into what is called a base class. The base
class would define the algorithm used and implement whatever is common to all cases that use this
code. Step 2 could be defined syntactically, but not implemented, leaving the specialized
implementation to the classes that you then derive from this base class.
Step 1
function checkInputs()
% actual implementation
end
Step 2
function results = computeOnFirstArg()
% specify syntax only
end
Step 3
function transformResults()
% actual implementation
end
Step 4
function out = checkOutputs()
% actual implementation
end
The code in the base class is not copied or modified. Classes you derive from the base class inherit
this code. Inheritance reduces the amount of code to be tested, and isolates your program from
changes to the basic procedure.
The use of a class as the basis for similar, but more specialized classes is a useful technique in object-
oriented programming. This class defines a common interface. Incorporating this kind of class into
your program design enables you to:
Reducing Complexity
Objects reduce complexity by reducing what you must know to use a component or system:
To illustrate these advantages, consider the implementation of a data structure called a doubly linked
list. See “Implementing Linked Lists with Classes” on page 3-23 for the actual implementation.
1-4
Why Use Object-Oriented Design
To add a node to the list, disconnect the existing nodes in the list, insert the new node, and reconnect
the nodes appropriately. Here are the basic steps:
Now create the new node, connect it, and renumber the original nodes:
1 Link new.Prev to n1
2 Link new.Next to n3 (was n2)
3 Link n1.Next to new (will be n2)
4 Link n3.Prev to new (will be n2)
The details of how methods perform these steps are encapsulated in the class design. Each node
object contains the functionality to insert itself into or remove itself from the list.
For example, in this class, every node object has an insertAfter method. To add a node to a list,
create the node object and then call its insertAfter method:
nnew = NodeConstructor;
nnew.insertAfter(n1)
Because the node class defines the code that implements these operations, this code is:
The object methods enforce the rules for how the nodes interact. This design removes the
responsibility for enforcing rules from the applications that use the objects. It also means that the
application is less likely to generate errors in its own implementation of the process.
1-5
1 Using Object-Oriented Design in MATLAB
Fostering Modularity
As you decompose a system into objects (car –> engine –> fuel system –> oxygen sensor), you form
modules around natural boundaries. Classes provide three levels of control over code modularity:
• Public — Any code can access this particular property or call this method.
• Protected — Only this object's methods and methods of objects 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.
When you define a class, you can overload existing MATLAB functions to work with your new object.
For example, the MATLAB serial port class overloads the fread function to read data from the device
connected to the port represented by this object. You can define various operations, such as equality
(eq) or addition (plus), for a class you have defined to represent your data.
See Also
More About
• “Role of Classes in MATLAB” on page 3-2
1-6
Handle Object Behavior
More than one variable can refer to the same handle object. Therefore, users interact with instances
of handle classes differently than instances of value classes. Understanding how handle objects
behave can help you determine whether to implement a handle or a value class. This topic illustrates
some of those interactions.
What Is a Handle?
Certain kinds of MATLAB objects are handles. When a variable holds a handle, it actually holds a
reference to the object.
Handle objects enable more than one variable to refer to the same object. Handle-object behavior
affects what happens when you copy handle objects and when you pass them to functions.
Copies of Handles
All copies of a handle object variable refer to the same underlying object. This reference behavior
means that if h identifies a handle object, then,
h2 = h;
For example, the MATLAB audioplayer function creates a handle object that contains the audio
source data to reproduce a specific sound segment. The variable returned by the audioplayer
function identifies the audio data and enables you to access object functions to play the audio.
MATLAB software includes audio data that you can load and use to create an audioplayer object.
This sample load audio data, creates the audio player, and plays the audio:
load gong Fs y
gongSound = audioplayer(y,Fs);
play(gongSound)
Suppose that you copy the gongSound object handle to another variable (gongSound2):
gongSound2 = gongSound;
The variables gongSound and gongSound2 are copies of the same handle and, therefore, refer to the
same audio source. Access the audioplayer information using either variable.
1-7
1 Using Object-Oriented Design in MATLAB
For example, set the sample rate for the gong audio source by assigning a new value to the
SampleRate property. First get the current sample rate and then set a new sample rate:
sr = gongSound.SampleRate;
disp(sr)
8192
gongSound.SampleRate = sr*2;
disp(gongSound2.SampleRate)
16384
play(gongSound2)
Passing a nonhandle variable to a function does not affect the original variable that is in the caller’s
workspace. For example, myFunc modifies a local variable called var, but when the function ends,
the local variable var no longer exists:
function myFunc(var)
var = var + 1;
end
x = 12;
myFunc(x)
disp(x)
12
The myFunc function can return the modified value, which you could assign to the same variable
name (x) or another variable.
x = 12;
x = myFunc(x);
disp(x)
13
1-8
Handle Object Behavior
When the argument is a handle variable, the function copies only the handle, not the object identified
by that handle. Both handles (original and local copy) refer to the same object.
When the function modifies the data referred to by the object handle, those changes are accessible
from the handle variable in the calling workspace without the need to return the modified object.
For example, the modifySampleRate function changes the audioplayer sample rate:
function modifySampleRate(audioObj,sr)
audioObj.SampleRate = sr;
end
load gong Fs y
gongSound = audioplayer(y,Fs);
disp(gongSound.SampleRate)
8192
modifySampleRate(gongSound,16384)
disp(gongSound.SampleRate)
16384
The modifySampleRate function does not need to return a modified gongSound object because
audioplayer objects are handle objects.
load gong Fs y
gongSound = audioplayer(y,Fs);
isa(gongSound,'handle')
load gong Fs y
gongSound = audioplayer(y,Fs);
The output argument, gongSound, is a handle variable. Calling delete deletes the object along with
the audio source information it contains:
1-9
1 Using Object-Oriented Design in MATLAB
delete(gongSound)
disp(gongSound)
whos
Fs 1x1 8 double
gongSound 1x1 0 audioplayer
y 42028x1 336224 double
Note The value for Bytes returned by the whos command does not include the data referenced by a
handle because many variables can reference the same data.
The handle gongSound no longer refers to a valid object, as shown by the isvalid handle method:
isvalid(gongSound)
ans =
logical
Calling delete on a deleted handle does nothing and does not cause an error. You can pass an array
containing both valid and invalid handles to delete. MATLAB deletes the valid handles, but does not
issue an error when encountering handles that are already invalid.
gongSound.SampleRate
play(gongSound)
clear gongSound
whos
Fs 1x1 8 double
y 42028x1 336224 double
1-10
Handle Object Behavior
See Also
More About
• “Handle Class Destructor” on page 7-13
• “Comparison of Handle and Value Classes” on page 7-2
1-11
2
Basic Example
2 Basic Example
In this section...
“Design Class” on page 2-2
“Create Object” on page 2-3
“Access Properties” on page 2-3
“Call Methods” on page 2-3
“Add Constructor” on page 2-4
“Vectorize Methods” on page 2-4
“Overload Functions” on page 2-5
“BasicClass Code Listing” on page 2-6
Design Class
The basic purpose of a class is to define an object that encapsulates data and the operations
performed on that data. For example, BasicClass defines a property and two methods that operate
on the data in that property:
• Value — Property that contains the numeric data stored in an object of the class
• roundOff — Method that rounds the value of the property to two decimal places
• multiplyBy — Method that multiplies the value of the property by the specified number
classdef BasicClass
properties
Value {mustBeNumeric}
end
methods
function r = roundOff(obj)
r = round([obj.Value],2);
end
function r = multiplyBy(obj,n)
r = [obj.Value] * n;
end
end
end
• Save the class definition in a .m file with the same name as the class.
• Create an object of the class.
• Access the properties to assign data.
• Call methods to perform operation on the data.
2-2
Create a Simple Class
Create Object
Create an object of the class using the class name:
a = BasicClass
a =
Value: []
Access Properties
Assign a value to the Value property using the object variable and a dot before the property name:
a.Value = pi/3;
a.Value
ans =
1.0472
Call Methods
Call the roundOff method on object a:
roundOff(a)
ans =
1.0500
Pass the object as the first argument to a method that takes multiple arguments, as in this call to the
myltiplyBy method:
multiplyBy(a,3)
ans =
3.1416
a.multiplyBy(3)
It is not necessary to pass the object explicitly as an argument when using dot notation. The notation
uses the object to the left of the dot and method name.
For information on class methods, see “Methods and Functions” on page 5-13
2-3
2 Basic Example
Add Constructor
Classes can define a special method to create objects of the class, called a constructor. Constructor
methods enable you to pass arguments to the constructor, which you can assign as property values.
The BasicClass Value property restricts its possible values using the mustBeNumeric function.
Here is a constructor for the BasicClass class. When you call the constructor with an input
argument, it is assigned to the Value property. If you call the constructor without an input argument,
the Value property has a default value of empty ([]).
methods
function obj = BasicClass(val)
if nargin == 1
obj.Value = val;
end
end
end
By adding this constructor to the class definition, you can create an object and set the property value
in one step:
a = BasicClass(pi/3)
a =
Value: 1.0472
The constructor can perform other operations related to creating objects of the class.
Vectorize Methods
MATLAB enables you to vectorize operations. For example, you can add a number to a vector:
[1 2 3] + 2
ans =
3 4 5
MATLAB adds the number 2 to each of the elements in the array [1 2 3]. To vectorize the
arithmetic operator methods, enclose the obj.Value property reference in brackets.
[obj.Value] + 2
This syntax enables the method to work with arrays of object. For example, create an object array
using indexed assignment.
obj(1) = BasicClass(2.7984);
obj(2) = BasicClass(sin(pi/3));
obj(3) = BasicClass(7);
2-4
Create a Simple Class
[obj.Value] + 2
roundOff(obj)
ans =
Overload Functions
Classes can implement existing functionality, such as addition, by defining a method with the same
name as the existing MATLAB function. For example, suppose that you want to add two BasicClass
objects. It makes sense to add the values of the Value properties of each object.
Here is an overloaded version of the MATLAB plus function. It defines addition for the BasicClass
class as adding the property values:
method
function r = plus(o1,o2)
r = [o1.Value] + [o2.Value];
end
end
By implementing a method called plus, you can use the “+” operator with objects of BasicClass.
a = BasicClass(pi/3);
b = BasicClass(pi/4);
a + b
ans =
1.8326
a = BasicClass(pi/3);
b = BasicClass(pi/4);
c = BasicClass(pi/2);
ar = [a b];
ar + c
ans =
2.6180 2.3562
Related Information
For information on overloading functions, see “Overload Functions in Class Definitions” on page 9-
26.
2-5
2 Basic Example
classdef BasicClass
properties
Value {mustBeNumeric}
end
methods
function obj = BasicClass(val)
if nargin == 1
obj.Value = val;
end
end
function r = roundOff(obj)
r = round([obj.Value],2);
end
function r = multiplyBy(obj,n)
r = [obj.Value] * n;
end
function r = plus(o1,o2)
r = [o1.Value] + [o2.Value];
end
end
end
See Also
Related Examples
• “Class Syntax Guide”
• “Validate Property Values” on page 8-20
2-6
3
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 text';
s.Name = 'Nancy';
s.Age = 64;
whos
whos
Name Size Bytes Class Attributes
a 1x1 8 double
b 1x9 18 char
s 1x1 370 struct
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 are
double precision numbers, and so on. Some variables can contain different classes of values like
structures.
Predefined Classes
MATLAB defines fundamental classes that comprise the basic types used by the language. These
classes include numeric, logical, char, cell, struct, and function handle.
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. 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
the plus operation must be able to add polynomial objects because the polynomial class defines this
operation.
When you define a class, you can overload special MATLAB functions (such as plus.m for the
addition operator). MATLAB calls these methods when users apply those operations to objects of your
class.
See “Representing Polynomials with Classes” on page 20-2 for an example that creates just such a
class.
3-2
Role of Classes in MATLAB
MATLAB classes use the following words to describe different parts of a class definition and related
concepts.
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 approach 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
objects defined by the superclass. A subclass is more specific than its superclass and might add new
properties, methods, and events to those components 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 Positives. All three sets are
subsets of Reals, which is a subset of All Numbers.
The definition of Positive Integers requires the additional specification that members of the set be
greater than zero. Positive Integers combine the definitions from both Integers and Positives. The
resulting subset is more specific, and therefore more narrowly defined, than the supersets, but still
shares all the characteristics that define the supersets.
3-3
3 MATLAB Classes Overview
The “is a” relationship is a good way to determine if it is appropriate to define a particular subset in
terms of existing supersets. For example, each of the following statements makes senses:
If the “is a” relationship holds, then it is likely you can define a new 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 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 derive subclasses from
the superclass in which you implement only what is unique to each specific port. Then the subclasses
would inherit all 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.
3-4
Role of Classes in MATLAB
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.
References
[1] Shalloway, A., J. R. Trott, Design Patterns Explained A New Perspective on Object-Oriented
Design.. Boston, MA: Addison-Wesley 2002.
[2] Gamma, E., R. Helm, R. Johnson, J. Vlissides, Design Patterns Elements of Reusable Object-
Oriented Software. Boston, MA: Addison-Wesley 1995.
[3] Freeman, E., Elisabeth Freeman, Kathy Sierra, Bert Bates, Head First Design Patterns.
Sebastopol, CA 2004.
See Also
Related Examples
• “Create a Simple Class” on page 2-2
• “Developing Classes — Typical Workflow” on page 3-6
• “Representing Structured Data with Classes” on page 3-14
• “Implementing Linked Lists with Classes” on page 3-23
3-5
3 MATLAB Classes Overview
Formulating a Class
This example discusses how to approach the design and implementation of a class. The objective of
this class is to represent a familiar concept (a bank account). However, you can apply the same
approach to most class designs.
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 status (open, closed, etc.)
If the balance is too low and you attempt to withdraw money, the bank account broadcasts a notice.
When this event occurs, the bank account broadcasts a notice to other entities that are designed to
listen for these notices. In this example, a simplified version of an account manager program
performs this task.
In this example, an account manager program determines the status of all bank accounts. This
program monitors the account balance and assigns one of three values:
These features define the requirements of the BankAccount and AccountManager classes. Include
only what functionality is required to meet your specific objectives. Support special types of accounts
by subclassing BankAccount and adding more specific features to the subclasses. Extend the
AccountManager as required to support new account types.
3-6
Developing Classes — Typical Workflow
Class Data
The class defines these properties to store the account number, account balance, and the account
status:
• AccountNumber — A property to store the number identifying the specific account. MATLAB
assigns a value to this property when you create an instance of the class. Only BankAccount class
methods can set this property. The SetAccess attribute is private.
• AccountBalance — A property to store the current balance of the account. The class operation
of depositing and withdrawing money assigns values to this property. Only BankAccount class
methods can set this property. The SetAccess attribute is private.
• AccountStatus — The BankAccount class defines a default value for this property. The
AccountManager class methods change this value whenever the value of the AccountBalance
falls below 0. The Access attribute specifies that only the AccountManager and BankAccount
classes have access to this property.
• AccountListener — Storage for the InsufficentFunds event listener. Saving a BankAccount
object does not save this property because you must recreate the listener when loading the object.
Class Operations
• BankAccount — Accepts an account number and an initial balance to create an object that
represents an account.
• deposit — Updates the AccountBalance property when a deposit transaction occurs
• withdraw — Updates the AccountBalance property when a withdrawal transaction occurs
• getStatement — Displays information about the account
• loadobj — Recreates the account manager listener when you load the object from a MAT-file.
Class Events
The account manager program changes the status of bank accounts that have negative balances. To
implement this action, the BankAccount class triggers an event when a withdrawal results in a
negative balance. Therefore, the triggering of the InsufficientsFunds event occurs from within
the withdraw method.
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 char vector and trigger it with any action.
3-7
3 MATLAB Classes Overview
example, different values for the account balance. Therefore, implement the BankAccount class as a
handle class. All copies of a given handle object refer to the same data.
3-8
Developing Classes — Typical Workflow
End of classdef
3-9
3 MATLAB Classes Overview
end
function deposit(BA,amt)
BA.AccountBalance = BA.AccountBalance + amt;
if BA.AccountBalance > 0
BA.AccountStatus = 'open';
end
end
function withdraw(BA,amt)
if (strcmp(BA.AccountStatus,'closed')&& BA.AccountBalance <= 0)
disp(['Account ',num2str(BA.AccountNumber),' has been closed.'])
return
end
newbal = BA.AccountBalance - amt;
BA.AccountBalance = newbal;
if newbal < 0
notify(BA,'InsufficientFunds')
end
end
function getStatement(BA)
disp('-------------------------')
disp(['Account: ',num2str(BA.AccountNumber)])
ab = sprintf('%0.2f',BA.AccountBalance);
disp(['CurrentBalance: ',ab])
disp(['Account Status: ',BA.AccountStatus])
disp('-------------------------')
end
end
methods (Static)
function obj = loadobj(s)
if isstruct(s)
accNum = s.AccountNumber;
initBal = s.AccountBalance;
obj = BankAccount(accNum,initBal);
else
obj.AccountListener = AccountManager.addAccount(s);
end
end
end
end
The AccountManager class stores no data so it does not need properties. The BankAccount object
stores the handle of the listener object.
Class Components
• assignStatus — Method that assigns a status to a BankAccount object. Serves as the listener
callback.
• addAccount — Method that creates the InsufficientFunds listener.
3-10
Developing Classes — Typical Workflow
• Extend the AccountManager class to support other types of accounts while keeping the
individual account classes simple and specialized.
• Change the criteria for the account status without affecting the compatibility of saved and loaded
BankAccount objects.
• Develop an Account superclass that factors out what is common to all accounts without requiring
each subclass to implement the account management functionality
3-11
3 MATLAB Classes Overview
BA.AccountStatus = 'overdrawn';
end
end
end
function lh = addAccount(BA)
lh = addlistener(BA, 'InsufficientFunds', ...
@(src, ~)AccountManager.assignStatus(src));
end
end
end
BA = BankAccount(1234567,500)
BA =
AccountNumber: 1234567
AccountBalance: 500
AccountListener: [1x1 event.listener]
getStatement(BA)
-------------------------
Account: 1234567
CurrentBalance: 500.00
Account Status: open
-------------------------
withdraw(BA,600)
getStatement(BA)
-------------------------
Account: 1234567
CurrentBalance: -100.00
Account Status: overdrawn
-------------------------
The $600 withdrawal triggered the InsufficientsFunds event. The current criteria defined by the
AccountManager class results in a status of overdrawn.
withdraw(BA,200)
getStatement(BA)
-------------------------
Account: 1234567
CurrentBalance: -300.00
3-12
Developing Classes — Typical Workflow
Now the AccountStatus has been set to closed by the listener and further attempts to make
withdrawals are blocked without triggering the event:
withdraw(BA,100)
deposit(BA,700)
getStatement(BA)
-------------------------
Account: 1234567
CurrentBalance: 400.00
Account Status: open
-------------------------
3-13
3 MATLAB Classes Overview
In this section...
“Objects as Data Structures” on page 3-14
“Structure of the Data” on page 3-14
“The TensileData Class” on page 3-15
“Create an Instance and Assign Data” on page 3-15
“Restrict Properties to Specific Values” on page 3-16
“Simplifying the Interface with a Constructor” on page 3-16
“Calculate Data on Demand” on page 3-17
“Displaying TensileData Objects” on page 3-18
“Method to Plot Stress vs. Strain” on page 3-18
“TensileData Class Synopsis” on page 3-19
For this example, the data represents tensile stress/strain measurements. These data are used to
calculate the elastic modulus of various materials. In simple terms, stress is the force applied to a
material and strain is the resulting deformation. Their ratio defines a characteristic of the material.
While this approach is an over simplification of the process, it suffices for this example.
Data Description
Material char vector identifying the type of material tested
SampleNumber Number of a particular test sample
Stress Vector of numbers representing the stress applied to the
sample during the test.
Strain Vector of numbers representing the strain at the
corresponding values of the applied stress.
Modulus Number defining an elastic modulus of the material under test,
which is calculated from the stress and strain data
3-14
Representing Structured Data with Classes
The first version of the class provides only data storage. The class defines a property for each of the
required data elements.
classdef TensileData
properties
Material
SampleNumber
Stress
Strain
Modulus
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);
Treat the TensileData object (td in the previous statements) much as you would any MATLAB
structure. However, defining a specialized data structure as a class has advantages over using a
general-purpose data structure, like a MATLAB struct:
• Users cannot accidentally misspell a field name without getting an error. For example, typing the
following:
td.Modulis = ...
would simply add a field to a structure. However, it 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.
• 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.
3-15
3 MATLAB Classes Overview
The Material property set method restricts the assignment of the property to one of the following
strings: aluminum, stainless steel, or carbon steel.
classdef TensileData
properties
Material
SampleNumber
Stress
Strain
Modulus
end
methods
function obj = set.Material(obj,material)
if (strcmpi(material,'aluminum') ||...
strcmpi(material,'stainless steel') ||...
strcmpi(material,'carbon steel'))
obj.Material = material;
else
error('Invalid Material')
end
end
end
end
When there is an attempt to set the Material property, MATLAB calls the set.Material method
before setting the property value.
If the value matches the acceptable values, the function set the property to that value. The code
within set method can access the property directly to avoid calling the property set method
recursively.
For example:
td = TensileData;
td.Material = 'brass';
3-16
Representing Structured Data with Classes
methods
function td = TensileData(material,samplenum,stress,strain)
if nargin > 0
td.Material = material;
td.SampleNumber = samplenum;
td.Stress = stress;
td.Strain = strain;
end
end
end
Create a TensileData object fully populated with data using the following statement:
td = TensileData('carbon steel',1,...
[2e4 4e4 6e4 8e4],...
[.12 .20 .31 .40]);
Calculating Modulus
TensileData objects do not store the value of the Modulus property. The constructor does not have
an input argument for the value of the Modulus property. The value of the Modulus:
Therefore, it is better to calculate the value of the Modulus property only when its value is
requested. Use a property get access method to calculate the value of the Modulus.
The Modulus property depends on Stress and Strain, so its Dependent attribute is true. Place
the Modulus property in a separate properties block and set the Dependent attribute.
The get.Modulus method calculates and returns the value of the Modulus property.
properties (Dependent)
Modulus
end
Define the property get method in a methods block using only default attributes.
methods
function modulus = get.Modulus(obj)
ind = find(obj.Strain > 0);
modulus = mean(obj.Stress(ind)./obj.Strain(ind));
end
end
This method calculates the average ratio of stress to strain data after eliminating zeros in the
denominator data.
3-17
3 MATLAB Classes Overview
MATLAB calls the get.Modulus method when the property is queried. For example,
td = TensileData('carbon steel',1,...
[2e4 4e4 6e4 8e4],...
[.12 .20 .31 .40]);
td.Modulus
ans =
1.9005e+005
To set the value of a Dependent property, the class must implement a property set method. There is
no need to allow explicit setting of the Modulus property. However, a set method enables you to
provide a customized error message. The Modulus set method references the current property value
and then returns an error:
methods
function obj = set.Modulus(obj,~)
fprintf('%s%d\n','Modulus is: ',obj.Modulus)
error('You cannot set the Modulus property');
end
end
The disp method displays the value of the Material, SampleNumber, and Modulus properties. It
does not display the Stress and Strain property data. These properties contain raw data that is not
easily viewed in the command window.
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
end
The 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:
methods
function plot(td,varargin)
plot(td.Strain,td.Stress,varargin{:})
title(['Stress/Strain plot for Sample',...
num2str(td.SampleNumber)])
ylabel('Stress (psi)')
3-18
Representing Structured Data with Classes
xlabel('Strain %')
end
end
The first argument to this method is a TensileData object, which contains the data.
The method passes a variable list of arguments (varargin) directly to the built-in plot function. The
TensileData plot method allows you to pass line specifier arguments or property name-value
pairs.
For example:
td = TensileData('carbon steel',1,...
[2e4 4e4 6e4 8e4],[.12 .20 .31 .40]);
plot(td,'-+b','LineWidth',2)
3-19
3 MATLAB Classes Overview
3-20
Representing Structured Data with Classes
classdef TensileData
properties
Material
SampleNumber
Stress
Strain
end
properties (Dependent)
Modulus
end
methods
function td = TensileData(material,samplenum,stress,strain)
if nargin > 0
td.Material = material;
td.SampleNumber = samplenum;
td.Stress = stress;
td.Strain = strain;
end
end
function m = get.Modulus(obj)
ind = find(obj.Strain > 0);
m = mean(obj.Stress(ind)./obj.Strain(ind));
end
3-21
3 MATLAB Classes Overview
function disp(td)
sprintf('Material: %s\nSample Number: %g\nModulus: %1.5g\n',...
td.Material,td.SampleNumber,td.Modulus)
end
function plot(td,varargin)
plot(td.Strain,td.Stress,varargin{:})
title(['Stress/Strain plot for Sample ',...
num2str(td.SampleNumber)])
xlabel('Strain %')
ylabel('Stress (psi)')
end
end
end
See Also
More About
• “Class Components” on page 5-4
3-22
Implementing Linked Lists with Classes
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.
• Data array
• Handle to the next node
• Handle to the previous node
Class Properties
The dlnode class implements each node as a handle object with three properties:
This diagram shows a list with three-nodes n1, n2, and n3. It also shows how the nodes reference the
next and previous nodes.
3-23
3 MATLAB Classes Overview
Class Methods
• dlnode — Construct a node and assign the value passed as an input to the Data property
• insertAfter — Insert this node after the specified node
• insertBefore — Insert this node before the specified node
• removeNode — Remove this node from the list and reconnect the remaining nodes
• clearList — Remove large lists efficiently
• delete — Private method called by MATLAB when deleting the list.
Build these nodes into a doubly linked list using the class methods designed for this purpose:
n2.insertAfter(n1) % Insert n2 after n1
n3.insertAfter(n2) % Insert n3 after n2
ans =
Data: 2
Next: [1x1 dlnode]
Prev: [1x1 dlnode]
ans =
Data: 2
Next: [1x1 dlnode]
Prev: [1x1 dlnode]
n1.Next.Next % Points to n3
ans =
Data: 3
Next: []
Prev: [1x1 dlnode]
3-24
Implementing Linked Lists with Classes
n3.Prev.Prev % Points to n1
ans =
Data: 1
Next: [1x1 dlnode]
Prev: []
For example, a node object, node, contains in its Next property the handle of the next node object,
node.Next. Similarly, the Prev property contains the handle of the previous node, node.Prev.
Using the three-node linked list defined in the previous section, you can demonstrate that the
following statements are true:
n1.Next == n2
n2.Prev == n1
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.
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.
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.
Related Information
For more information on handle classes, see “Comparison of Handle and Value Classes” on page 7-
2.
3-25
3 MATLAB Classes Overview
3-26
Implementing Linked Lists with Classes
methods
function node = dlnode(Data)
% Construct a dlnode object
if nargin > 0
node.Data = Data;
end
end
3-27
3 MATLAB Classes Overview
if ~isempty(nodeAfter.Prev)
nodeAfter.Prev.Next = newNode;
end
nodeAfter.Prev = newNode;
end
function removeNode(node)
% Remove a node from a linked list.
if ~isscalar(node)
error('Input must be scalar')
end
prevNode = node.Prev;
nextNode = node.Next;
if ~isempty(prevNode)
prevNode.Next = nextNode;
end
if ~isempty(nextNode)
nextNode.Prev = prevNode;
end
node.Next = dlnode.empty;
node.Prev = dlnode.empty;
end
function clearList(node)
% Clear the list before
% clearing list variable
prev = node.Prev;
next = node.Next;
removeNode(node)
while ~isempty(next)
node = next;
next = node.Next;
removeNode(node);
end
while ~isempty(prev)
node = prev;
prev = node.Prev;
removeNode(node)
end
end
end
Class Properties
Only dlnode class methods can set the Next and Prev properties because these properties have
private set access (SetAccess = private). Using private set access prevents client code from
performing any incorrect operation with these properties. The dlnode class methods perform all the
operations that are allowed on these nodes.
The Data property has public set and get access, allowing you to query and modify the value of Data
as required.
3-28
Implementing Linked Lists with Classes
properties
Data
end
properties(SetAccess = private)
Next = dlnode.empty;
Prev = dlnode.empty;
end
To create a node object, specify the node's data as an argument to the constructor:
Insert 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.
First, insertAfter calls the removeNode method to ensure that the new node is not connected to
any other nodes. Then, insertAfter assigns the newNode Next and Prev properties to the handles
of the nodes that are after and before the newNode location in the list.
For example, suppose that you want to insert a new node, nnew, after an existing node, n1, in a list
containing n1—n2—n3.
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:
nnew.Next = n1.Next;
3-29
3 MATLAB Classes Overview
• Set nnew.Prev to n1
nnew.Prev = n1;
• If n1.Next is not empty, then n1.Next is still n2, so n1.Next.Prev is n2.Prev, which is set to
nnew
n1.Next.Prev = nnew;
• n1.Next is now set to nnew
n1.Next = nnew;
Remove a Node
The removeNode method removes a node from a list and reconnects the remaining nodes. The
insertBefore and insertAfter methods always call removeNode on the node to insert before
attempting to connect it to a linked list.
Calling removeNode ensures that the node is in a known state before assigning it to the Next or
Prev property:
function removeNode(node)
if ~isscalar(node)
error('Input must be scalar')
end
prevNode = node.Prev;
nextNode = node.Next;
if ~isempty(prevNode)
prevNode.Next = nextNode;
end
if ~isempty(nextNode)
nextNode.Prev = prevNode;
end
node.Next = dlnode.empty;
node.Prev = dlnode.empty;
end
For example, suppose that you remove n2 from a three-node list (n1–n2–n3):
n2.removeNode;
3-30
Implementing Linked Lists with Classes
removeNode removes n2 from the list and reconnects the remaining nodes with the following steps:
n1 = n2.Prev;
n3 = n2.Next;
if n1 exists, then
n1.Next = n3;
if n3 exists, then
n3.Prev = n1
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 (that is, n2 is not connected):
n2.Next = dlnode.empty;
n2.Prev = dlnode.empty;
Suppose that you create a list with 10 nodes and save the handle to the head of the list:
head = dlnode(1);
for i = 10:-1:2
new = dlnode(i);
insertAfter(new,head);
end
Now remove the third node (Data property assigned the value 3):
removeNode(head.Next.Next)
head.Next.Next
ans =
Data: 4
Next: [1x1 dlnode]
Prev: [1x1 dlnode]
head.Next
3-31
3 MATLAB Classes Overview
ans =
Data: 2
Next: [1x1 dlnode]
Prev: [1x1 dlnode]
Delete a Node
To delete a node, call the removeNode method on that node. The removeNode method disconnects
the node and reconnects the list before allowing MATLAB to destroy the removed node. MATLAB
destroys the node once references to it by other nodes are removed and the list is reconnected.
When you create a linked list and assign a variable that contains, for example, the head or tail of the
list, clearing that variable causes the destructor to recurse through the entire list. With large enough
list, clearing the list variable can result in MATLAB exceeding its recursion limit.
The clearList method avoids recursion and improves the performance of deleting large lists by
looping over the list and disconnecting each node. clearList accepts the handle of any node in the
list and removes the remaining nodes.
function clearList(node)
if ~isscalar(node)
error('Input must be scalar')
end
prev = node.Prev;
next = node.Next;
removeNode(node)
while ~isempty(next)
node = next;
next = node.Next;
3-32
Implementing Linked Lists with Classes
removeNode(node);
end
while ~isempty(prev)
node = prev;
prev = node.Prev;
removeNode(node)
end
end
For example, suppose that you create a list with many nodes:
head = dlnode(1);
for k = 100000:-1:2
nextNode = dlnode(k);
insertAfter(nextNode,head)
end
The variable head contains the handle to the node at the head of the list:
head
head =
Data: 1
Next: [1x1 dlnode]
Prev: []
head.Next
ans =
Data: 2
Next: [1x1 dlnode]
Prev: [1x1 dlnode]
The only nodes that have not been deleted by MATLAB are those nodes for which there exists an
explicit reference. In this case, those references are head and nextNode:
head
head =
Data: 1
Next: []
Prev: []
nextNode
nextNode =
3-33
3 MATLAB Classes Overview
Data: 2
Next: []
Prev: []
The delete method has private access to prevent users from calling delete when intending to
delete a single node. MATLAB calls delete implicitly when the list is destroyed.
To delete a single node from the list, use the removeNode method.
Rather than copying the code used to implement the dlnode class, and then expanding upon it, you
can derive a new class from dlnode (that is, subclass dlnode). You can create a class that has all the
features of dlnode and also defines its own additional features. 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 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:
3-34
Implementing Linked Lists with Classes
end
end
end
The NamedNode class adds a Name property to store the node name.
The constructor calls the class constructor for the dlnode class, and then assigns a value to the Name
property.
Use the NamedNode class like the dlnode class, except that you specify a name for each node object.
For example:
Now use the insert methods inherited from dlnode to build the list:
n(2).insertAfter(n(1))
n(3).insertAfter(n(2))
A single node displays its name and data when you query its properties:
n(1).Next
ans =
n(1).Next.Next
ans =
n(3).Prev.Prev
ans =
3-35
3 MATLAB Classes Overview
See Also
More About
• “The Handle Superclass” on page 7-11
3-36
4
Static Data
4 Static Data
Static Data
In this section...
“What Is Static Data” on page 4-2
“Static Variable” on page 4-2
“Static Data Object” on page 4-3
“Constant Data” on page 4-4
Use static data to define counters used by class instances or other data that is shared among all
objects of a class. Unlike instance data, static data does not vary from one object to another. MATLAB
provides several ways to define static data, depending on your requirements.
Static Variable
Classes can use a persistent variable to store static data. Define a static method or local function in
which you create a persistent variable. The method or function provides access to this variable. Use
this technique when you want to store one or two variables.
Saving an object of the class defining the persistent variable does not save the static data associated
with the class. To save your static data in an object, or define more extensive data, use the static data
object technique “Static Data Object” on page 4-3
Implementation
The StoreData class defines a static method that declares a persistent variable Var. The
setgetVar method provides set and get access to the data in the persistent variable. Because the
setgetVar method has public access, you can set and get the data stored in the persistent variable
globally. Control the scope of access by setting the method Access attribute.
classdef StoreData
methods (Static)
function out = setgetVar(data)
persistent Var;
if nargin
Var = data;
end
out = Var;
end
end
end
Set the value of the variable by calling setgetVar with an input argument. The method assigns the
input value to the persistent variable:
StoreData.setgetVar(10);
Get the value of the variable by calling setgetVar with no input argument:
4-2
Static Data
a = StoreData.setgetVar
a =
10
clear StoreData
a = StoreData.setgetVar
a =
[]
Add a method like setgetVar to any class in which you want the behavior of a static property.
Implementation
The SharedData class is a handle class, which enables you to reference the same object data from
multiple handle variables:
The UseData class is the stub of a class that uses the data stored in the SharedData class. The
UseData class stores the handle to a SharedData object in a constant property.
classdef UseData
properties (Constant)
Data = SharedData
end
% Class code here
end
The Data property contains the handle of the SharedData object. MATLAB constructs the
SharedData object when loading the UseData class. All subsequently created instances of the
UseData class refer to the same SharedData object.
To initialize the SharedData object properties, load theUseData class by referencing the constant
property.
h = UseData.Data
4-3
4 Static Data
h =
Data1: []
Data2: []
Use the handle to the SharedData object to assign data to property values:
h.Data1 = 'MyData1';
h.Data2 = 'MyData2';
Each instance of the UseData class refers to the same handle object:
a1 = UseData;
a2 = UseData;
a1.Data.Data1
ans =
MyData1
a1.Data.Data1 = rand(3);
All new and existing objects of the UseData class share the same SharedData object. a2 now has
the rand(3) data that was assigned to a1 in the previous step:
a2.Data.Data1
ans =
To reinitialize the constant property, clear all instances of the UseData class and then clear the class:
clear a1 a2
clear UseData
Constant Data
To store constant values that do not change, assign the data to a constant property. All instances of
the class share the same value for that property. Control the scope of access to constant properties by
setting the property Access attribute.
The only way to change the value of a constant property is to change the class definition. Use
constant properties like public final static fields in Java®.
See Also
clear | persistent
4-4
Static Data
Related Examples
• “Define Class Properties with Constant Values” on page 15-2
• “Static Methods” on page 9-24
More About
• “Method Attributes” on page 9-4
• “Property Attributes” on page 8-7
• “Static Properties” on page 5-52
4-5
5
For information on the code that defines a class, see “Class Components” on page 5-4.
Class folders are not directly on the MATLAB path. The path folder that contains the class folder is on
the MATLAB path.
• Create a single, self-contained class definition file in a path folder or a class folder
• Define a class in multiple files, which requires you to use a class folder inside a path folder
Create a single, self-contained class definition file in a folder on the MATLAB® path. The name of the
file must match the class (and constructor) name and must have the .m extension. Define the class
entirely in this file. You can put other single-file classes in this folder.
The following diagram shows an example of this folder organization. pathfolder is a folder on the
MATLAB path.
5-2
Class Files and Folders
If you use multiple files to define a class, put all the class-definition files (the file containing the
classdef and all class method files) in a single @ClassName folder. That class folder must be inside
a folder that is on the MATLAB path. You can define only one class in a class folder.
A path folder can contain classes defined in both class folders and single files without a class folder.
See Also
More About
• “Folders Containing Class Definitions” on page 6-13
• “Packages Create Namespaces” on page 6-20
• “Methods in Separate Files” on page 9-8
5-3
5 Class Definition—Syntax Reference
Class Components
In this section...
“Class Building Blocks” on page 5-4
“Class Definition Block” on page 5-4
“Properties Block” on page 5-5
“Methods Block” on page 5-5
“Events Block” on page 5-5
“A Complete Class” on page 5-6
“Enumeration Classes” on page 5-6
“Related Information” on page 5-7
properties, methods, events, and enumeration are keywords only within a classdef block.
For example, this classdef defines a class called MyClass that subclasses the handle class, but
cannot be used to derive subclasses:
5-4
Class Components
Properties Block
The 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.
classdef ClassName
properties (PropertyAttributes)
...
end
...
end
For example, this class defines a property called Prop1 that has private access and has a default
value equal to the output of the date function.
classdef MyClass
properties (SetAccess = private)
Prop1 = date
end
...
end
Methods Block
The 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.
classdef ClassName
methods (MethodAttributes)
...
end
...
end
For example:
classdef MyClass
methods (Access = private)
function obj = myMethod(obj)
...
end
end
end
Events Block
The 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.
5-5
5 Class Definition—Syntax Reference
classdef ClassName
events (EventAttributes)
EventName
end
...
end
For example, this class defined an event called StateChange with a ListenAccess set to
protected:
classdef EventSource
events (ListenAccess = protected)
StateChanged
end
...
end
A Complete Class
A complete class definition contains any combination of properties, methods, and events code blocks.
Enumeration Classes
Enumeration classes are specialized classes that define a fixed set of names representing a single
type of value. Enumeration classes use an enumeration block that contains the enumeration
members defined by the class.
The enumeration block starts with the enumeration keyword and terminates with the end keyword.
5-6
Class Components
end
...
end
For example, this class defines two enumeration members that represent logical false and true:
Related Information
“Folders Containing Class Definitions” on page 6-13
5-7
5 Class Definition—Syntax Reference
Classdef Block
In this section...
“How to Specify Attributes and Superclasses” on page 5-8
“Class Attribute Syntax” on page 5-8
“Superclass Syntax” on page 5-8
“Local Functions in Class File” on page 5-9
• Class attributes
• Superclasses
The classdef block contains the properties, methods, and events subblocks.
classdef ClassName
...
end
For example, the TextString class specifies that it cannot be used to derive subclasses:
See “Class Attributes” on page 6-5 for a list of attributes and a discussion of the behaviors they
control.
Superclass Syntax
Derive a class from one or more other classes by specifying the superclasses on the classdef line:
For example, the LinkedList class inherits from classes called Array and handle:
5-8
Classdef Block
classdef ClassName
...
end
function localFunction
...
end
See Also
Related Examples
• “User-Defined Classes” on page 6-2
• “Design Subclass Constructors” on page 12-7
• “Local Functions”
5-9
5 Class Definition—Syntax Reference
Class Properties
In this section...
“The Properties Block” on page 5-10
“Access to Property Values” on page 5-11
classdef ClassName
properties (PropertyAttributes)
PropertyName size class {validation functions} = DefaultValue
end
end
Property attributes apply to all properties defined within the block. To define properties with different
attributes, use multiple properties blocks. All property attributes have default values. For a list of
property attributes, see “Property Attributes” on page 8-7.
Restrict the size, class, and other aspects of values assigned to properties in the property definition.
For more information, see “Validate Property Values” on page 8-20.
Optionally assign default values to the property in the properties block. MATLAB evaluates the
assignment statement when the class is first referenced or when loading a saved object. For more
information, see “Property Definition” on page 8-13.
Note 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 an instance of the class.
For more information on the evaluation of expressions that you assign as property default values, see
“When MATLAB Evaluates Expressions” on page 6-10.
The following class defines three properties. Model and Color use default attribute values, resulting
in public read and write access. SerialNumber has read-only access by object users. Assign the
SerialNumber property value from a class member function, such as the constructor or other class
method.
classdef NewCar
properties
Model
Color
end
properties (SetAccess = private)
SerialNumber
end
methods
...
5-10
Class Properties
end
end
A = NewCar
A =
Model: []
Color: []
SerialNumber: []
A.Model = 'XGT7000';
A.Color = 'Red';
classdef NewCar
properties
Model
Color
end
properties (SetAccess = private)
SerialNumber
end
methods
function obj = NewCar(model,color)
obj.Model = model;
obj.Color = color;
obj.SerialNumber = datenum(datetime('now'));
end
end
end
A = NewCar('XGT7000','Red')
A =
Model: 'XGT7000'
Color: 'Red'
SerialNumber: 7.362456078531134e+05
See Also
Related Examples
• “Ways to Use Properties” on page 8-2
5-11
5 Class Definition—Syntax Reference
5-12
Methods and Functions
In this section...
“The Methods Block” on page 5-13
“Method Calling Syntax” on page 5-13
“Private Methods” on page 5-14
“More Detailed Information on Methods” on page 5-14
“Class-Related Functions” on page 5-14
“How to Overload Functions and Operators” on page 5-15
“Rules for Defining Methods in Separate Files” on page 5-15
Methods must be on the MATLAB path when called. For example, if you create an object and then
change your current folder to a folder from which the method file is not visible, an error occurs when
you call that method.
5-13
5 Class Definition—Syntax Reference
Ordinary Methods
Call ordinary methods using MATLAB function syntax or dot notation. For example, suppose that you
have a class that defines ordinaryMethod. Pass an object of the defining class and whatever
arguments are required.
classdef MyClass
methods
function out = ordinaryMethod(obj,arg1)
...
end
end
end
Call ordinaryMethod using the object obj of the class and either syntax:
obj = MyClass;
r = ordinaryMethod(obj,arg1);
r = obj.ordinaryMethod(arg1);
Static Methods
Static methods do not require an object of the class. To call a static method, prefix the method name
with the class name so that MATLAB can determine what class defines the method.
classdef MyClass
methods (Static)
function out = staticMethod(arg1)
...
end
end
end
r = MyClass.staticMethod(arg1);
See “Static Methods” on page 9-24 for information on methods that do not require objects of their
class.
Private Methods
Use the Access method attribute to create a private method. You do not need to use a private folder.
Class-Related Functions
You can define functions that are not class methods in the file that contains the class definition
(classdef). Define local functions outside of the classdef - end block, but in the same file as the
class definition. Functions defined in classdef files work like local functions. You can call these
5-14
Methods and Functions
functions from anywhere in the same file, but they are not visible outside of the file in which you
define them.
Local functions 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
end % End of classdef
function myUtilityFcn
...
end
You also can create package functions, which require the use of the package name when calling these
functions.
You can overload MATLAB arithmetic, logical, relational, and indexing operators by defining class
methods with the appropriate names.
See the handle class for a list of operations defined for that class. All classes deriving from handle
inherit these methods.
• To specify attributes for a method defined in a separate file, declare this method in a methods
block in the classdef file. Specify the attribute values with the methods block.
• Match the syntax declared in the methods block (if used) to the method's function line.
• The separate file must be in the class (@) folder.
• The class constructor method must be defined in the classdef file. The constructor cannot be in
a separate file.
• Handle class delete methods must be defined in the classdef file. The delete method cannot
be in a separate file.
All functions that use dots in their names must be defined in the classdef file, including:
5-15
5 Class Definition—Syntax Reference
• Converter methods that must use the package name as part of the class name because the
class is contained in packages
• Property set and get access methods
For more information on defining methods in separate files, see “Methods in Separate Files” on page
9-8
See Also
More About
• “Methods in Class Design” on page 9-2
5-16
Events and Listeners
In this section...
“Define and Trigger Events” on page 5-17
“Listen for Events” on page 5-17
• Subclasses handle
• Defines an event named StateChange
• Triggers the event using the inherited notify method in its upDateUI method.
classdef MyClass < handle
events
StateChange
end
...
methods
function upDateUI(obj)
...
notify(obj,'StateChange');
end
end
end
addlistener(event_obj,'StateChange',@myCallback)
To control the lifecycle of the listener, use the event.listener constructor to create the listener
object.
See Also
event.hasListener | event.listener | event.proplistener
Related Examples
• “Overview Events and Listeners” on page 11-2
• “Events and Listeners Syntax” on page 11-18
5-17
5 Class Definition—Syntax Reference
Attribute Specification
In this section...
“Attribute Syntax” on page 5-18
“Attribute Descriptions” on page 5-18
“Attribute Values” on page 5-18
“Simpler Syntax for true/false Attributes” on page 5-19
Attribute Syntax
Attributes modify the behavior of classes and class components (properties, methods, and events).
Attributes enable you to define useful behaviors without writing complicated code. For example, you
can create a read-only property by setting its SetAccess attribute to private, but leaving its
GetAccess attribute set to public:
All class definition blocks (classdef, properties, methods, and events) support specific
attributes. All attributes have default values. Specify attribute values only in cases where you want to
change from the default value to another predefined value.
Note Specify the value of a particular attribute only once in any component block.
Attribute Descriptions
For lists of supported attributes, see:
Attribute Values
When you specify attribute values, those values affect all the components defined within the defining
block. For example, the following property definition blocks set the:
Defining properties with different attribute settings requires multiple properties blocks.
properties (SetObservable = true)
AccountBalance
end
properties (SetAccess = private, Hidden = true)
5-18
Attribute Specification
SSNumber
CreditCardNumber
end
When specifying class attributes, place the attribute list directly after the classdef keyword:
methods (Static)
...
end
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.
See Also
Related Examples
• “Evaluation of Expressions in Class Definitions” on page 6-8
5-19
5 Class Definition—Syntax Reference
For example, a subclass can call a superclass disp method to implement the display of the superclass
part of the object. Then the subclass adds code to display the subclass part of the object:
5-20
Call Superclass Methods on Subclass Objects
constructor from the subclass constructor. The call to the superclass constructor must come before
any other references to the object.
In the following class, the MySub object is initialized by the MySuperClass constructor. The
superclass constructor constructs the MySuperClass part of the object using the specified
arguments.
See Also
Related Examples
• “Modify Inherited Methods” on page 12-13
5-21
5 Class Definition—Syntax Reference
To use the CircleArea class, copy this code into a file named CircleArea.m and save this file in a
folder that is on the MATLAB path.
classdef CircleArea
properties
Radius
end
properties (Constant)
P = pi
end
properties (Dependent)
Area
end
methods
function obj = CircleArea(r)
if nargin > 0
obj.Radius = r;
end
end
function val = get.Area(obj)
val = obj.P*obj.Radius^2;
end
function obj = set.Radius(obj,val)
if val < 0
error('Radius must be positive')
end
obj.Radius = val;
end
function plot(obj)
r = obj.Radius;
d = r*2;
pos = [0 0 d d];
curv = [1 1];
rectangle('Position',pos,'Curvature',curv,...
'FaceColor',[.9 .9 .9])
line([0,r],[r,r])
text(r/2,r+.5,['r = ',num2str(r)])
title(['Area = ',num2str(obj.Area)])
axis equal
end
function disp(obj)
rad = obj.Radius;
disp(['Circle with radius: ',num2str(rad)])
5-22
Representative Class Code
end
end
methods (Static)
function obj = createObj
prompt = {'Enter the Radius'};
dlgTitle = 'Radius';
rad = inputdlg(prompt,dlgTitle);
r = str2double(rad{:});
obj = CircleArea(r);
end
end
end
ca = CircleArea.createObj
ca.Area
ans =
164.2202
plot(ca)
5-23
5 Class Definition—Syntax Reference
5-24
Representative Class Code
5-25
5 Class Definition—Syntax Reference
5-26
MATLAB Code Analyzer Warnings
While the previous function is legal MATLAB code, it results in Code Analyzer warnings for two
reasons:
The Code Analyzer returns only one warning, suggesting that you might actually want to refer to the
EmployeeName property.
While this version of someMethod is legal MATLAB code, it is confusing to give a property the same
name as a function. Therefore, the Code Analyzer provides a warning suggesting that you might have
intended the statement to be:
5-27
5 Class Definition—Syntax Reference
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:
See Also
Related Examples
• “Use of Editor and Debugger with Classes” on page 5-37
5-28
Objects In Conditional Statements
The values returned by the eq method must be of type logical or convertible to logical. MATLAB
attempts to convert the output of eq to a logical value if the output of the eq method is a nonlogical
value.
Note You do not need to define eq methods for enumeration classes. See “Enumerations in Switch
Statements” on page 5-32.
All classes derived from the handle class inherit an eq method. The expression,
h1 == h2
5-29
5 Class Definition—Syntax Reference
end
end
The switch statements work only with scalar objects. For example:
h1(1) = BasicHandle('Handle Object');
h1(2) = BasicHandle('Handle Object');
h1(3) = BasicHandle('Handle Object');
h2 = h1;
switch h1
case h2
disp('h2 is selected')
otherwise
disp('h2 not selected')
end
In this case, h1 is not scalar. Use isscalar to determine if an object is scalar before entering a
switch statement.
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.
Design of eq
Implement the eq method to return a logical array representing the result of the == comparison.
5-30
Objects In Conditional Statements
For example, the SwitchOnVer class implements an eq method that returns true for the ==
operation if the value of the Version property is the same for both objects. In addition, eq works
with arrays the same way as the built-in eq. For the following expression:
obj1 == obj2
Implementation of eq
Here is a class that implements an eq method. Ensure that your implementation contains appropriate
error checking for the intended use.
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
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
5-31
5 Class Definition—Syntax Reference
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
disp('This is version 1.0')
case ov2
disp('This is version 2.0')
case ov3
disp('This is version 3.0')
otherwise
disp('There is no version')
end
else
error('Input object must be scalar')
end
For example, the WeeklyPlanner class defines enumerations for five days of the week. The switch/
case statements in the todaySchedule static method dispatch on the enumeration member
corresponding to the current day of the week. The date and datestr functions return a char vector
with the name of the current day.
classdef WeeklyPlanner
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
end
methods (Static)
function todaySchedule
dayName = datestr(date,'dddd');
dayEnum = WeeklyPlanner.(dayName);
switch dayEnum
case WeeklyPlanner.Monday
disp('Monday schedule')
case WeeklyPlanner.Tuesday
5-32
Objects In Conditional Statements
disp('Tuesday schedule')
case WeeklyPlanner.Wednesday
disp('Wednesday schedule')
case WeeklyPlanner.Thursday
disp('Thursday schedule')
case WeeklyPlanner.Friday
disp('Friday schedule')
end
end
end
end
WeeklyPlanner.todaySchedule
Enumeration classes that derived from built-in types inherit the superclass eq method. For example,
the FlowRate class derives from int32:
The switchEnum function switches on the input argument, which can be a FlowRate enumeration
value.
function switchEnum(inpt)
switch inpt
case 10
disp('Flow = 10 cfm')
case 50
disp('Flow = 50 cfm')
case 100
disp('Flow = 100 cfm')
end
end
switchEnum(FlowRate.Medium)
Flow = 50 cfm
5-33
5 Class Definition—Syntax Reference
Operations on Objects
In this section...
“Object Operations” on page 5-34
“Help on Objects” on page 5-35
“Functions to Test Objects” on page 5-36
“Functions to Query Class Components” on page 5-36
Object Operations
A fundamental purpose of objects is to contain data and facilitate ways to manipulate that data.
Objects often define their own version of ordinary MATLAB functions that work with the object. For
example, you can create a timeseries object and pass the object to plot:
ts = timeseries(rand(100,1),.01:.01:1,'Name','Data1');
plot(ts)
However, MATLAB does not call the standard plot function. MATLAB calls the timeseries plot
method, which can extract the data from the timeseries object and create a customized graph.
5-34
Operations on Objects
Help on Objects
Suppose that you use an audioplayer object to play audio with MATLAB. To play audio, load audio
data into MATLAB and create an audioplayer:
load('handel','Fs','y')
chorus = audioplayer(y,Fs);
The audioplayer function creates an object that you access using the object variable chorus.
MATLAB stores the audio source and other information in the object properties.
Here are the properties and values for the chorus instance of the audioplayer:
chorus
chorus =
The object’s documentation discusses the purpose of the object and describes the properties and
methods that you use when working with objects of that class.
You can also list the methods to see what operations you can perform. Pass the object to the methods
function to see the list:
methods(chorus)
5-35
5 Class Definition—Syntax Reference
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.
a == b (eq) Determine if handle variable a refers to the same object as handle variable b.
isobject Determine whether input is a MATLAB object
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.
See Also
Related Examples
• “Class Syntax Guide”
5-36
Use of Editor and Debugger with Classes
+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 method defined in its own file inside a class folder, use:
edit +PackFld1/+PackFld2/@myclass/myMethod
dbstop in myclass at 14
5-37
5 Class Definition—Syntax Reference
See “Automatic Updates for Modified Classes” on page 5-39 for information about clearing class
after modification.
See Also
dbstop
Related Examples
• “MATLAB Code Analyzer Warnings” on page 5-27
• “Debug a MATLAB Program”
5-38
Automatic Updates for Modified Classes
• The first time the class is referenced, such as creating an instance, accessing a constant property,
or calling a static method of the class.
• Whenever the definition of a loaded class changes and MATLAB returns to the command prompt.
• When you change the MATLAB path and cause a different definition of the class to be used. The
change takes effect after MATLAB returns to the command prompt.
• Whenever you access the class metadata.
MATLAB allows only one definition for a class to exist at any time. Therefore, MATLAB attempts to
update all existing objects of a class automatically to conform to the new class definition. You do not
need to call clear classes to remove existing objects when you change their defining class.
Note Using an editor other than the MATLAB editor or using MATLAB Online™ can result in delays
to automatic updating.
Here is an example of what happens when you create an instance of a concrete class edit the class
definition to make the class abstract.
5-39
5 Class Definition—Syntax Reference
a = MyClass;
% Edit MyClass to make it Abstract
Note MATLAB does not update metaclass instances when you change the definition of a class. You
must get new metaclass data after updating a class definition.
• Value change to handle — Existing objects become independent handles referring to different
objects.
• Enumeration member added — Existing objects preserve the enumeration members they had
previously, even if the underlying values have changed.
• Enumeration member removed — Existing objects that are not using the removed member have
the same enumeration members that they had previously. Existing objects that use the removed
member replace the removed member with the default member of the enumeration.
• Enumeration block removed — Enumeration members are taken out of use.
• Superclass definition changed — Changes applied to all subclasses in the hierarchy of that
superclass.
• Superclass added or removed — Change of superclass applied to all existing objects.
Objects do not update until referenced in a way that exposes the change, such as invoking the object
display or assigning to a property.
5-40
Automatic Updates for Modified Classes
Some class updates cause situations in which MATLAB cannot update existing objects to conform to a
modified class definition. These cases result in errors until you delete the objects:
Change Effect
Make Abstract = true Accessing existing objects returns an error.
Change AllowedSubclasses Newly created objects can inherit from different superclasses
than existing objects.
Change ConstructOnLoad Loading classes obeys the current value of ConstructOnLoad.
Change HandleCompatible Newly created objects can have different class hierarchy than
existing objects.
Change Hidden Appearance of class in list of superclasses and access by help
function can change
5-41
5 Class Definition—Syntax Reference
Change Effect
Change InferiorClasses Method dispatching for existing objects can change.
Make Sealed = true Existing subclass objects return errors when accessed.
Change Effect
Add property Adds the new property to existing objects of the class. Sets the
property values to the default value (which is [] if the class
definition does not specify a default).
Remove property Removes the property from existing objects of the class.
Attempts to access the removed property fail.
Change property default value Does not apply the new default value to existing objects of the
class.
Move property between subclass Does not apply different default value when property definition
and superclass moves between superclass and subclass.
Change property attribute value Applies changes to existing objects of the class.
Change Effect
Add method You can call the new method on existing objects of the class.
5-42
Automatic Updates for Modified Classes
Change Effect
Modify method Modifications are available to existing objects.
Remove method You can on longer call deleted method on existing objects.
Change method attribute value Apply changes to existing objects of the class.
5-43
5 Class Definition—Syntax Reference
Change Effect
Change event attribute value Apply changes to existing objects of the class.
See Also
Related Examples
• “Use of Editor and Debugger with Classes” on page 5-37
5-44
Compatibility with Previous Versions
• The classdef keyword begins a block of class-definitions code. An end statement terminates the
class definition.
• Within the classdef code block, properties, methods, and events are also keywords
delineating where you define the respective class members.
It is not possible to create class hierarchies that mix classes defined before Version 7.6 and current
class definitions that use classdef. Therefore, you cannot subclass an old class to create a version
of the new class.
For classes defined using the new classdef keyword, a class folder shadows all class folders that
occur after it on the MATLAB path. Classes defined in class folders must locate all class files in that
single folder. However, classes defined in class folders continue to take precedence over functions
and scripts having the same name, even those functions and scripts that come before them on the
path.
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.
Compare the following two Stock constructor methods. The Stock class is a subclass of the Asset
class, which requires arguments passed to its constructor.
5-45
5 Class Definition—Syntax Reference
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
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.
5-46
Compatibility with Previous Versions
5-47
5 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 char vector 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
8-39 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 8-7 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.
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 uses the leftmost object
to select the method to call.
However, if the class of an argument is superior to the class of the other arguments, MATLAB
dispatches to the method of the superior argument, regardless of its position within the argument
list.
• In C++, you call a superclass method using the scoping operator: superclass::method
• In Java code, you use: superclass.method
5-48
Comparison of MATLAB and Other OO Languages
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.
MATLAB classes do not support overloading functions using different signatures for the same
function name.
Object Modification
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.
MATLAB passes all variables by value. When you pass an object to a function, MATLAB copies the
value from the caller into the parameter variable in the called function.
However, MATLAB supports two kinds of classes that behave differently when copied:
• Handle classes — a handle class instance variable refers to an object. A copy of a handle class
instance variable refers to the same object as the original variable. If a function modifies a handle
object passed as an input argument, the modification affects the object referenced by both the
original and copied handles.
• Value classes — the property data in an instance of a value class are independent of the property
data in copies of that instance (although, a value class property could contain a handle). A
function can modify a value object that is passed as an input argument, but this modification does
not affect the original object.
See “Comparison of Handle and Value Classes” on page 7-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
5-49
5 Class Definition—Syntax Reference
end
end
end
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.
When you pass a handle to a function, the function makes a copy of the handle variable, just like
when passing a value object. However, because a copy of a handle object refers to the same object as
the original handle, the function can modify the object without having to return the modified object.
For example, suppose that you modify the SimpleClass class definition to make a class derived from
the handle class:
classdef SimpleHandleClass < handle
properties
Color
end
methods
function obj = SimpleHandleClass(c)
if nargin > 0
obj.Color = c;
end
end
5-50
Comparison of MATLAB and Other OO Languages
end
end
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
ans =
blue
ans =
yellow
The function g modified the object referred to by the input argument (obj) and returned a handle to
that object in y.
MATLAB Passes Handles by Value
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
ans =
green
5-51
5 Class Definition—Syntax Reference
obj.Color
ans =
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.
Static Properties
In MATLAB, classes can define constant properties, but not "static" properties in the sense of other
languages like C++. You cannot change constant properties from the initial value specified in the
class definition.
MATLAB has long-standing rules that variables always take precedence over the names of functions
and classes. Assignment statements introduce a variable if one does not exist.
A.B = C
Introduce a new variable, A, that is a struct containing a field B whose value is C. If A.B = C could
refer to a static property of class A, then class A would take precedence over variable A.
This behavior would be a significant incompatibility with prior releases of MATLAB. For example, the
introduction of a class named A on the MATLAB path could change the meaning of an assignment
statement like A.B = C inside a .m code file.
In other languages, classes rarely use static data, except as private data within the class or as public
constants. In MATLAB, you can use constant properties the same way you use public final static
fields in Java. To use data that is internal to a class in MATLAB, create persistent variables in private
or protected methods or local functions used privately by the class.
Avoid static data in MATLAB. If a class has static data, using the same class in multiple applications
causes conflicts among applications. Conflicts are less of an issue in some other languages. These
languages compile applications into executables that run in different processes. Each process has its
own copy of the class static data. MATLAB, frequently runs many different applications in the same
process and environment with a single copy of each class.
For ways to define and use static data in MATLAB, see “Static Data” on page 4-2.
5-52
Comparison of MATLAB and Other OO Languages
5-53
6
User-Defined Classes
In this section...
“What Is a Class Definition” on page 6-2
“Attributes for Class Members” on page 6-2
“Kinds of Classes” on page 6-2
“Constructing Objects” on page 6-3
“Class Hierarchies” on page 6-3
“classdef Syntax” on page 6-3
“Class Code” on page 6-3
Define MATLAB classes in code blocks, with subblocks delineating the definitions of various class
members. For syntax information on these blocks, see “Class Components” on page 5-4.
Class definitions can provide information, such as inheritance relationships or the names of class
members without actually constructing the class. See “Class Metadata” on page 17-2.
Kinds of Classes
There are two kinds of MATLAB classes—handle classes and value classes.
• Value classes represent independent values. Value objects contain the object data and do not
share this data with copies of the object. MATLAB numeric types are value classes. Values objects
passed to and modified by functions must return a modified object to the caller.
• Handle classes create objects that reference the object data. Copies of the instance variable refer
to the same object. Handle objects passed to and modified by functions affect the object in the
caller’s workspace without returning the object.
For more information, see “Comparison of Handle and Value Classes” on page 7-2.
6-2
User-Defined Classes
Constructing Objects
For information on class constructors, see “Class Constructor Methods” on page 9-16.
For information on creating arrays of objects, see “Construct Object Arrays” on page 10-2.
Class Hierarchies
For more information on how to define class hierarchies, see “Hierarchies of Classes — Concepts” on
page 12-2.
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 keyword.
Class Code
Here is a simple class definition with one property and a constructor method that sets the value of the
property when there is an input argument supplied.
classdef MyClass
properties
Prop
end
methods
function obj = MyClass(val)
if nargin > 0
obj.Prop = val;
end
end
6-3
6 Defining and Organizing Classes
end
end
To create an object of MyClass, save the class definition in a .m file having the same name as the
class and call the constructor with any necessary arguments:
d = datestr(now);
o = MyClass(d);
o.Prop
ans =
10-Nov-2005 10:38:14
The constructor should support a no argument syntax so MATLAB can create default objects. For
more information, see “No Input Argument Constructor Requirement” on page 9-19.
For more information on the components of a class definition, see “Class Components” on page 5-4
See Also
Related Examples
• “Create a Simple Class” on page 2-2
• “Developing Classes — Typical Workflow” on page 3-6
• “Representing Structured Data with Classes” on page 3-14
6-4
Class Attributes
Class Attributes
In this section...
“Specifying Class Attributes” on page 6-5
“Specifying Attributes” on page 6-7
“Class-Specific Attributes” on page 6-7
For more information on attribute syntax, see “Attribute Specification” on page 5-18.
6-5
6 Defining and Organizing Classes
Class Attributes
(default =
false)
Framework attributes Classes that use certain framework base classes have framework-specific attributes.
See the documentation for the specific base class you are using for information on
these attributes.
6-6
Class Attributes
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. You can use multiple properties, methods, and events definition blocks to apply
different attribute setting to different class members.
Class attributes settings are not inherited, so superclass attribute values do not affect subclasses.
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 keyword, as shown:
classdef (attribute-name = expression, ...) ClassName
Class-Specific Attributes
Some MATLAB classes define additional attributes that you can use only with the class hierarchies
that define these attributes. See the specific documentation for the classes you are using for
information on any additional attributes supported by those classes.
See Also
More About
• “Expressions in Attribute Specifications” on page 6-9
6-7
6 Defining and Organizing Classes
For information on assign property default values and attribute values, see the following topics:
classdef MyClass
% Some attributes are set to logical values
properties (Constant = true)
CnstProp = 2*pi
end
properties
% Static method of this class
Prop1 = MyClass.setupAccount
% Constant property from this class
Prop2 = MyClass.CnstProp
% Function that returns a value
Prop3 = datestr(now)
% A class constructor
Prop4 = AccountManager
end
methods (Static)
function accNum = setupAccount
accNum = randi(9,[1,12]);
end
end
end
MATLAB does not call property set methods when assigning the result of default value expressions to
properties. (See “Property Access Methods” on page 8-39 for information about these special
methods.)
6-8
Evaluation of Expressions in Class Definitions
Enumerations that derived from MATLAB types can use expression to assign a value:
MATLAB evaluates these expressions only once when enumeration members are first accessed.
For attributes values that are logical true or false, class definitions can specify attribute values
using expressions. For example, this assignment makes MyClass sealed (cannot be subclassed) for
versions of MATLAB before R2014b (verLessThan)
The expression on the right side of the equal sign (=) must evaluate to true or false. You cannot
use any definitions from the class file in this expression, including any constant properties, static
methods, and local functions.
While you can use conditional expression to set attribute values, doing so can cause the class
definition to change based on external conditions. Ensure that this behavior is consistent with your
class design.
See “Attribute Specification” on page 5-18 for more information on attribute syntax.
Property definitions allow you to specify default values for properties using any expression that has
no reference to variables. For example, VectorAngle defines a constant property (Rad2Deg) and
uses it in an expression that defines the default value of another property (Angle). The default value
expression also uses a static method (getAngle) defined by the class:
classdef VectorAngle
properties (Constant)
Rad2Deg = 180/pi
end
properties
Angle = VectorAngle.Rad2Deg*VectorAngle.getAngle([1 0],[0 1])
end
methods
function obj = VectorAngle(vx,vy)
obj.Angle = VectorAngle.getAngle(vx,vy);
end
end
methods (Static)
function r = getAngle(vx,vy)
6-9
6 Defining and Organizing Classes
You cannot use the input variables to the constructor to define the default value of the Angle
property. For example, this definition for the Angle property is not valid:
properties
Angle = VectorAngle.Rad2Deg*VectorAngle.getAngle(vx,vy)
end
Expression in class methods execute like expressions in any function. MATLAB evaluates an
expression within the function workspace when the method executes. Therefore, expressions used in
class methods are not considered part of the class definition and are not discussed in this section.
MATLAB evaluates expressions in the context of the class file, so these expressions can access any
functions, static methods, and constant properties of other classes that are on your path at the time
MATLAB initializes the class. Expressions defining property default values can access constant
properties defined in their own class.
After initialization, the values returned by these expressions are part of the class definition and are
constant for all instances of the class. Each instance of the class uses the results of the initial
evaluation of the expressions without re-evaluation.
If you clear a class, then MATLAB reinitializes the class by reevaluating the expressions that are part
of the class definition. (see “Automatic Updates for Modified Classes” on page 5-39)
6-10
Evaluation of Expressions in Class Definitions
classdef ContClass
properties
% Assign current date and time
TimeProp = datestr(now)
end
end
classdef ClassExp
properties
ObjProp = ContClass
end
end
When you first use the ClassExp class, MATLAB creates an instance of the ContClass class.
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 that you change the value of the TimeProp property
on the object contained by ClassExp objectb:
b.ObjProp.TimeProp = datestr(now)
ans =
08-Oct-2003 17:22:49
a.ObjProp.TimeProp
ans =
08-Oct-2003 17:16:08
6-11
6 Defining and Organizing Classes
Creating two instances of the ClassExp class shows that MATLAB created an object when it
initialized the ContClass. MATLAB used a copy of the object’s handle for each instance of the
ClassExp class. Therefore, 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
ans =
08-Oct-2003 17:46:01
b.ObjProp.TimeProp = datestr(now);
b.ObjProp.TimeProp
ans =
08-Oct-2003 17:47:34
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 Also
More About
• “Comparison of Handle and Value Classes” on page 7-2
6-12
Folders Containing Class Definitions
• Path folders — The folder is on the MATLAB path and the folder name does not begin with an @
character. Use this type of folder when you want multiple classes in one folder. However, the
entire class definition must be contained in one file.
• Class folders — The folder name begins with an @ character followed by the class name. The
folder 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.
See the path function for information about the MATLAB path.
The name of each class definition file must match the name of the class that is specified with the
classdef keyword. Using a path folder eliminates the need to create a separate class folder for each
class. However, the entire class definition, including all methods, must be contained within a single
file.
.../path_folder/MyClass1.m
.../path_folder/MyClass2.m
.../path_folder/MyClass3.m
addpath path_folder
6-13
6 Defining and Organizing Classes
.../parent_folder/@MyClass/MyClass.m
.../parent_folder/@MyClass/myMethod1.m
.../parent_folder/@MyClass/myMethod2.m
Define only one class per folder. All files have a .m extension or, for MATLAB versions R2018a and
later, standalone methods can be live functions with a .mlx extension.
Use a class folder when you want to use more than one file for your class definition. MATLAB treats
any function file in the class folder as a method of the class. Function files can be MATLAB code (.m),
Live Code file format (.mlx), MEX functions (platform dependent extensions), and P-code files (.p).
Class files provide the advantage that MATLAB can explicitly identify any file in the folder as a
method of that class. For more information, see “Changing Path to Update Class Definition” on page
6-16.
The base name of each file must be a valid MATLAB function name. Valid function names begin with
an alphabetic character and can contain letters, numbers, or underscores. For more information, see
“Methods in Separate Files” on page 9-8.
If a class folder contains a private folder, only the class defined in that folder can access functions
defined in the private folder. Subclasses do not have access to superclass private functions. For
more information on private folders, see “Private Functions”.
If you want a subclass to have access to the private functions of the superclass, define the functions
as protected methods of the superclass. Specify the methods with the Access attribute set to
protected.
If a class defines functions in a private folder that is in a class folder, then MATLAB follows these
precedence rules when dispatching to the private functions vs. a local function defined in the
classdef file:
• Using dot notation (obj.methodName), a function in a private folder takes precedence over a
local function defined in the classdef file.
• Using function notation (methodName(obj)), a local function defined in the classdef file takes
precedence over the function in the private folder.
6-14
Folders Containing Class Definitions
You cannot put class definitions (classdef file) in private folders because doing so would not meet
the requirements for class or path folders.
For example, consider a path with the following folders, containing the files indicated.
Here is the logic that MATLAB applies to determine which version of Foo to call:
• The method bar is not recognized as part of the Foo class defined in fldr3/@Foo.
If fldr3/@Foo/Foo.m does not contain a classdef keyword (that is, it is a MATLAB class created
before Version 7.6), then fldr4/@Foo/bar.m becomes a method of the Foo class defined in fldr3/
@Foo
In MATLAB Versions 5 through 7, class folders do not shadow other class folders having the same
name, but residing in later path folders. Instead, the class uses the combination of methods from all
class folders having the same name to define the class. This behavior is no longer supported.
6-15
6 Defining and Organizing Classes
For backward compatibility, classes defined in class folders always take precedence over functions
and scripts having the same name. This precedence applies to functions and scripts that come before
these classes on the path.
Suppose that you define two versions of a class named Foo in two folders, fldA and fldB.
fldA/+FooPkg/@Foo/Foo.m
fldB/+FooPkg/@Foo/Foo.m
addpath fldA
a = FooPkg.Foo;
cd fldB
The current folder is always first on the path. Therefore, MATLAB finds fldB/+FooPkg/@Foo/Foo.m
as the definition for class FooPkg.Foo.
b = FooPkg.Foo;
MATLAB automatically updates the existing instance, a, to use the new class definition in fldB.
Suppose that you define two versions of a class named Foo in two folders, fldA and fldB, but do not
use a class folder.
fldA/+FooPkg/Foo.m
fldB/+FooPkg/Foo.m
addpath fldA
a = FooPkg.Foo;
cd fldB
6-16
Folders Containing Class Definitions
The current folder is effectively the top of the path. However, MATLAB does not identify fldB/
+FooPkg/Foo.m as the definition for class FooPkg.Foo. MATLAB continues to use the original class
definition until you clear the class.
clear FooPkg.Foo
MATLAB automatically updates the existing objects to conform to the class definition in fldB.
Usually, clearing instance variables is unnecessary.
See Also
More About
• “Packages Create Namespaces” on page 6-20
• “Automatic Updates for Modified Classes” on page 5-39
• “Live Code File Format (.mlx)”
• “MEX File Functions”
• “Protect Your Source Code”
6-17
6 Defining and Organizing Classes
Class Precedence
In this section...
“Use of Class Precedence” on page 6-18
“Why Mark Classes as Inferior” on page 6-18
“InferiorClasses Attribute” on page 6-18
The material presented in this topic builds on an understanding of the following information:
InferiorClasses Attribute
Specify the relative precedence of user-defined classes using the class InferiorClasses attribute.
To specify classes that are inferior to the class you are defining, assign a cell array of class
meta.class objects to this attribute.
For example, the following classdef declares that MyClass is dominant over ClassName1 and
ClassName2.
classdef (InferiorClasses = {?ClassName1,?ClassName2}) MyClass
...
end
The ? operator combined with a class name creates a meta.class object. See metaclass.
The following MATLAB classes are always inferior to classes defined using the classdef syntax and
cannot be used in this list.
double, single, int64, uint64, int32, uint32, int16, uint16, int8, uint8, char, string,
logical, cell, struct, and function_handle.
6-18
Class Precedence
Dominant Class
MATLAB uses class dominance when evaluating expressions involving objects of more than one class.
The dominant class determines:
• Which class method to call 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.
No Attribute Inheritance
Subclasses do not inherit a superclass InferiorClasses attribute. Only classes specified in the
subclass InferiorClasses attribute are inferior to subclass objects.
See Also
More About
• “Class Precedence and MATLAB Path” on page 6-15
• “Dominant Argument in Overloaded Graphics Functions” on page 9-38
6-19
6 Defining and Organizing Classes
Package Folders
Packages are special folders that can contain class folders, function, and class definition files, and
other packages. The names of classes and functions are scoped to the package folder. A package is a
namespace within which names must be unique. Function and class names must be unique only
within the package. Using a package provides a means to organize classes and functions. Packages
also enable you to reuse the names of classes and functions in different packages.
Note Packages are not supported for classes created before MATLAB Version 7.6 (that is, classes
that do not use classdef).
The parent of the top-level package folder must be on the MATLAB path.
Internal Packages
MathWorks® reserves the use of packages named internal for utility functions used by internal
MATLAB code. Functions that belong to an internal package are intended for MathWorks use only.
6-20
Packages Create Namespaces
Using functions or classes that belong to an internal package is discouraged. These functions and
classes are not guaranteed to work in a consistent manner from one release to the next. Any of these
functions and classes might be removed from the MATLAB software in any subsequent release
without notice and without documentation in the product release notes.
+mypack/pkfcn.m
z = mypack.pkfcn(x,y);
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)
classdef myClass
obj = mypack.myClass(arg1,arg2,...);
Calling class methods does not require the package name because you have an object of the class.
You can use dot or function notation:
obj.myMethod(arg)
myMethod(obj,arg)
A static method requires the full class name, which includes the package name:
mypack.myClass.stMethod(arg)
obj = mypack.MyClass;
This section shows you how to access various package members from outside a package. Suppose
that you have a package mypack with the following contents:
+mypack
+mypack/myfcn.m
6-21
6 Defining and Organizing Classes
+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);
If mypack.MyFirstClass has a method called myFcn, call it like any method call on an object:
obj = mypack.MyFirstClass;
myFcn(obj,arg);
If mypack.MyFirstClass has a property called MyProp, assign it using dot notation and the object:
obj = mypack.MyFirstClass;
obj.MyProp = x;
Package members remain scoped to the package. Always refer to the package members using the
package name. Alternatively, import the package into the function in which you call the package
member, see “Import Classes” on page 6-24.
Package folders do not shadow other package folders that are positioned later on the path, unlike
classes, which do shadow other classes. If two or more packages have the same name, MATLAB
treats them all as one package. If redundantly named packages in different path folders define the
same function name, then MATLAB finds only one of these functions.
Suppose a package and a class have the same name. For example:
fldr_1/+foo
fldr_2/@foo/foo.m
A call to which foo returns the path to the executable class constructor:
6-22
Packages Create Namespaces
A function and a package can have the same name. However, a package name by itself is not an
identifier. Therefore, if a redundant name occurs alone, it identifies the function. Executing a package
name alone returns an error.
In cases where a package and a class have the same name, a package function takes precedence over
a static method. For example, path folder fldrA contains a package function and path folder fldrB
contains a class static method:
fldrA/+foo/bar.m % bar is a function in package foo
fldrB/@foo/bar.m % bar is a static method of class foo
which foo.bar
In cases where the same path folder contains both package and class folders with the same name, the
package function takes precedence over the static method.
fldr/@foo/bar.m % bar is a static method of class foo
fldr/+foo/bar.m % bar is a function in package foo
which foo.bar
fldr/+foo/bar.m
If a path folder fldr contains a classdef file foo that defines a static method bar and the same
folder contains a package +foo that contains a package function bar.
fldr/foo.m % bar is a static method of class foo
fldr/+foo/bar.m % bar is a function in package foo
which foo.bar
fldr/+foo/bar.m
See Also
More About
• “Folders Containing Class Definitions” on page 6-13
• “Class Precedence” on page 6-18
6-23
6 Defining and Organizing Classes
Import Classes
In this section...
“Syntax for Importing Classes” on page 6-24
“Import Static Methods” on page 6-24
“Import Package Functions” on page 6-24
“Package Function and Class Method Name Conflict” on page 6-25
“Clearing Import List” on page 6-25
function myFunc
import pkg.*
obj1 = MyClass1(arg,...); % call pkg.MyClass1 constructor
obj2 = MyClass2(arg,...); % call pkg.MyClass2 constructor
a = pkgFunction(); % call package function named pkgFunction
end
function myFunc
import pkg.MyClass.MyStaticMethod
MyStaticMethod(arg,...); % call static method
end
function myFunc
import pkg.pkgFunction
pkgFunction(arg,...); % call imported package function
end
6-24
Import Classes
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
See Also
import
More About
• “Packages Create Namespaces” on page 6-20
6-25
7
Basic Difference
A value class constructor returns an object that is associated with the variable to which it is assigned.
If you reassign this variable, MATLAB creates an independent copy of the original object. If you pass
this variable to a function to modify it, the function must return the modified object as an output
argument. For information on value-class behavior, see “Avoid Unnecessary Copies of Data”.
A handle class constructor returns a handle object that is a reference to the object created. You can
assign the handle object to multiple variables or pass it to functions without causing MATLAB to
make a copy of the original object. A function that modifies a handle object passed as an input
argument does not need to return the object.
All handle classes are derived from the abstract handle class.
By default, MATLAB classes are value classes. The following definition creates a value class named
MyValueClass:
classdef MyValueClass
...
end
To create a handle class, derive the class from the handle class.
a = int32(7);
b = a;
a = a^4;
7-2
Comparison of Handle and Value Classes
b
7
MATLAB graphics objects are implemented as handle objects because they represent visual elements.
For example, create a graphics line object and copy its handle to another variable. Both variables
refer to the same line object.
x = 1:10; y = sin(x);
l1 = line(x,y);
l2 = l1;
Set the properties of the line object using either copy of the handle.
set(l2,'Color','red')
set(l1,'Color','green')
get(l2,'Color')
ans =
0 1 0
Calling the delete function on the l2 handle destroys the line object. If you attempt to set the
Color property on the line l1, the set function returns an error.
delete(l2)
set(l1,'Color','blue')
If you delete the object by deleting any one of the existing handles, all copies are now invalid because
you deleted the single object to which all handles refer.
Deleting a handle object is not the same as clearing the handle variable. In the graphics object
hierarchy, the parent of the object holds a reference to the object. For example, the parent axes hold
a reference to the line object referred to by l1 and l2. If you clear both variables from the
workspace, the object still exists.
For more information on the behavior of handle objects, see “Handle Object Behavior” on page 1-7.
Value objects are always associated with one workspace or temporary variable. Value objects go out
of scope when their variable goes out of scope or is cleared. There are no references to value objects,
only copies that are independent objects.
Here is a value class that stores a value in its Number property. The default property value is the
number 1.
7-3
7 Value or Handle Class — Which to Use
classdef NumValue
properties
Number = 1
end
end
a =
Number: 1
b =
Number: 1
The variables a and b are independent. Changing the value of the Number property of a does not
affect the Number property of b.
a.Number = 7
a =
Number: 7
b =
Number: 1
When you pass a value object to a function, MATLAB creates a copy of that object in the function
workspace. Because copies of value objects are independent, the function does not modify the object
in the caller’s workspace. Therefore, functions that modify value objects must return the modified
object to be reassigned in the caller’s workspace.
7-4
Comparison of Handle and Value Classes
object properties. The copy refers to the same object as the original handle. If you change a property
value on the original object, the copied handle references the same change.
Here is a handle class that stores a value in its Number property. The default property value is the
number 1.
a = NumHandle
a =
Number: 1
b = a
b =
Number: 1
The variables a and b refer to the same underlying object. Changing the value of the Number
property of a also changes the Number property of b. That is, a and b refer to the same object.
a.Number = 7
a =
Number: 7
b =
Number: 7
When you pass a handle object to a function, MATLAB creates a copy of the handle in the function
workspace. Because copies of handles reference the same underlying object, functions that modify
the handle object effectively modify the object in the caller’s workspace as well. Therefore, it is not
7-5
7 Value or Handle Class — Which to Use
necessary for functions that modify handle objects passed as input arguments to return the modified
object to the caller.
Deleting Handles
You can destroy handle objects by explicitly calling the handle delete method. Deleting the handle of
a handle class object makes all handles invalid. For example:
a = NumHandle;
b = a;
delete(a)
b.Number
Calling delete on a handle object invokes the destructor function or functions for that object. See
“Handle Class Destructor” on page 7-13 for more information.
For information on the differences between initializing properties to default values in the properties
block and initializing properties from within the constructor, see “Initialize Property Values” on page
8-13 and “Initialize Arrays of Handle Objects” on page 10-9.
Equality for handle objects means that the handle variables refer to the same object. You also can
identify handle variables that refer to different objects of the same class that have the same state.
To determine if value objects are the same size and their contents are of equal value, use isequal.
For example, use the previously defined NumValue class to create two instances and test for equality:
a = NumValue;
b = NumValue;
isequal(a,b)
ans =
a and b are independent and therefore are not the same object. However each represents the same
value.
If you change the value represented by a value object, the objects are no longer equal.
a = NumValue;
b = NumValue;
b.Number = 7;
isequal(a,b)
7-6
Comparison of Handle and Value Classes
ans =
Handle objects inherit an eq method from the handle base class. You can use == and isequal to
test for two different relationships among handle objects:
• The handles refer to the same object: == and isequal return true.
• The handles refer to objects of the same class that have the same values, but are not the same
objects — only isequal returns true.
Use the previously defined NumHandle class to create an object and copy the handle.
a = NumHandle;
b = a;
a == b
ans =
isequal(a,b)
ans =
Create two instances of the NumHandle class using the default values.
a = NumHandle;
b = NumHandle;
a == b
ans =
isequal(a,b)
ans =
7-7
7 Value or Handle Class — Which to Use
See “The Handle Superclass” on page 7-11 for more information on the handle class and its
methods.
See Also
Related Examples
• “Which Kind of Class to Use” on page 7-9
• “Implement Copy for Handle Classes” on page 7-30
• “Handle Object Behavior” on page 1-7
7-8
Which Kind of Class to Use
“Representing Polynomials with Classes” on page 20-2 and “Representing Structured Data with
Classes” on page 3-14 provides examples of value classes.
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.
“Implementing Linked Lists with Classes” on page 3-23 and “Developing Classes — Typical Workflow”
on page 3-6 provides examples of a handle class.
A value class is suitable because you can copy a polynomial object and have two objects that are
identical representations of the same polynomial. For an example of value classes, see “Subclasses of
MATLAB Built-In Types” on page 12-41.
For information on MATLAB pass-by-value semantics, see “Avoid Unnecessary Copies of Data”.
• 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.
7-9
7 Value or Handle Class — Which to Use
• Nodes in lists or trees having specific connectivity to other nodes — no two nodes can have the
same connectivity.
• The class represents physical and unique objects like serial ports and printers.
• The class represents visible objects like graphics components.
• 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 matlab.mixin.SetGet class (a subclass of handle) so that it can
implement a graphics object style set/get interface to access property values.
• You want to create a singleton class or a class in which you track the number of instances from
within the constructor.
• Instances of a class cannot share state, such as nodes in a linked list.
See Also
Related Examples
• “Handle Compatible Classes” on page 12-32
7-10
The Handle Superclass
To add both handle behavior and specific functionality to your class, derive your class from these
handle classes:
For information on how to define subclasses, see “Design Subclass Constructors” on page 12-7 .
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
7-11
7 Value or Handle Class — Which to Use
Relational Methods
TF = eq(H1,H2)
TF = ne(H1,H2)
TF = lt(H1,H2)
TF = le(H1,H2)
TF = gt(H1,H2)
TF = ge(H1,H2)
The handle class overloads these functions to support 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
element-wise equality or comparison test result. The input arrays must be the same size or one (or
both) can be scalar. The method performs scalar expansion as required. For more information on
handle class relational methods, see relationaloperators.
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.
When MATLAB destroys an object, it also destroys values stored in the properties of the object.
MATLAB frees computer memory associated with the object for use by MATLAB or the operating
system.
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. Define a delete method in your handle subclass for
these purposes.
See Also
Related Examples
• “Comparison of Handle and Value Classes” on page 7-2
7-12
Handle Class Destructor
Basic Knowledge
Class destructor – a method named delete that MATLAB calls implicitly before destroying an object
of a handle class. Also, user-defined code can call delete explicitly to destroy an object.
Nondestructor – a method named delete that does not meet the syntax requirements of a valid
destructor. Therefore, MATLAB does not call this method implicitly when destroying handle objects. A
method named delete in a value class is not a destructor. A method named delete in a value class
that sets the HandleCompatible attribute to true is not a destructor.
• Must define one, scalar input argument, which is an object of the class.
• Must not define output arguments
• Cannot be Sealed, Static, or Abstract
• Cannot use arguments blocks for input argument validation.
7-13
7 Value or Handle Class — Which to Use
MATLAB does not call a noncompliant delete method when destroying objects of the class. A
noncompliant delete method can prevent the destruction of the object by shadowing the handle
class delete method.
A delete method defined by a value class that is handle compatible is not a destructor, even if the
delete method is inherited by a handle subclass. For information on handle compatible classes, see
“Handle Compatible Classes” on page 12-32.
methods
function delete(obj)
% obj is always scalar
...
end
end
MATLAB calls the delete method separately for each element in an array. Therefore, a delete
method is passed only one scalar argument with each invocation.
Calling delete on a deleted handle should not error and can take no action. This design enables
delete to work on object arrays containing a mix of valid and invalid objects.
A delete method can access properties of the object being deleted. MATLAB does not destroy these
properties until after the delete methods for the class of the object and all superclasses finish
executing.
If a delete method creates new variables that contain a handle to the object being deleted, those
handles are invalid. After the delete method finishes execution, handles to the deleted object in any
variables in any workspace are invalid.
The isvalid method returns false for the handle object within the delete method because object
destruction begins when the method is called.
MATLAB calls delete methods in the inverse of the construction order. That is, MATLAB invokes
subclass delete methods before superclass delete methods.
If a superclass expects a property to be managed by subclasses, then the superclass should not
access that property in its delete method. For example, if a subclass uses an inherited abstract
property to store an object handle, then the subclass should destroy this object in its delete method,
but the superclass should not access that property in its delete method.
7-14
Handle Class Destructor
For example, the PartialObject class delete method determines if the Data property is empty
before accessing the data this property contains. If an error occurs while assigning the constructor
argument to the Name property, MATLAB passes the partially constructed object to delete.
An error occurs if you call the constructor with a char vector, instead of the required cell array:
obj = PartialObject('Test')
MATLAB passes the partially constructed object to the delete method. The constructor did not set
the value of the Data property because the error occurred when setting the Name property.
Data is empty
Error setting 'Name' property of 'PartialObject' class:
...
If an error occurs during the construction of a handle class, MATLAB calls the class destructor on the
object along with the destructors for any objects contained in properties and any initialized base
classes.
7-15
7 Value or Handle Class — Which to Use
For example, suppose that a method opens a file for writing and you want to close the file in your
delete method. The delete method can call fclose on a file identifier that the object stores in its
FileID property:
function delete(obj)
fclose(obj.FileID);
end
Classes cannot define a valid destructor that is Sealed. MATLAB returns an error when you attempt
to instantiate a class that defines a Sealed delete method.
Normally, declaring a method as Sealed prevents subclasses from overriding that method. However,
a Sealed method named delete that is not a valid destructor does not prevent a subclass from
defining its own destructor.
For example, if a superclass defines a method named delete that is not a valid destructor, but is
Sealed, then subclasses:
Heterogeneous class hierarchies require that all methods to which heterogeneous arrays are passed
must be sealed. However, the rule does not apply to class destructor methods. Because destructor
methods cannot be sealed, you can define a valid destructor in a heterogeneous hierarchy that is not
sealed, but does function as a destructor.
Object Lifecycle
MATLAB invokes the delete method when the lifecycle of an object ends. The lifecycle of an object
ends when the object is:
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 in any handle array.
7-16
Handle Class Destructor
A variable goes out of scope when you explicitly clear it or when its function ends. When a variable
goes out of scope and 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.
MATLAB invokes the delete methods in the following sequence when destroying an object:
MATLAB invokes the delete methods of superclasses at the same level in the hierarchy in the order
specified in the class definition. For example, the following class definition specifies supclass1
before supclass2. MATLAB calls the delete method of supclass1 before the delete method of
supclass2.
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 a call the delete methods for those objects when there are no other references to those
objects.
Superclass delete methods cannot call methods or access properties belonging to a subclass.
Consider a set of objects that reference other objects of the set such that the references form a cyclic
graph. In this case, MATLAB:
• 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
MATLAB destroys the objects in the reverse of the order of construction. for more information, see
“Handle Object During delete Method Execution” on page 7-14.
delete(obj)
A class can prevent explicit destruction of an object by setting its delete method Access attribute
to private. However, a method of the class can call the private delete method.
If the class delete method Access attribute is protected, only methods of the class and of
subclasses can explicitly delete objects of that class.
However, when an object lifecycle ends, MATLAB calls the object’s delete method when destroying
the object regardless of the method’s Access attribute.
7-17
7 Value or Handle Class — Which to Use
Class destructor behavior differs from the normal behavior of an overridden method. MATLAB
executes each delete method of each superclass upon destruction, even if that delete method is
not public.
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. A superclass with a
private delete method cannot prevent the destruction of subclass objects.
Declaring a private delete method makes most sense for sealed classes. In the case where classes are
not sealed, subclasses can define their own delete methods with public access. MATLAB calls a
private superclass delete method as a result of an explicit call to a public subclass delete method.
For example, if the superclass implements a Sealed method named delete that is not a valid
destructor, then MATLAB does not allow subclasses to override this method.
Java objects that hold references to MATLAB objects can prevent deletion of the MATLAB objects. In
these cases, MATLAB does not call the handle object delete method even when there is no handle
variable referring to that object. To ensure your delete method executes, call delete on the object
explicitly before the handle variable goes out of scope.
Problems can occur when you define callbacks for Java objects that reference MATLAB objects.
7-18
Handle Class Destructor
end
end
end
function testDestructor
cwj = CallbackWithJava
...
end
testDestructor
cwj =
The handle variable, cwj, exists only in the function workspace. However, MATLAB does not call the
class delete method when the function ends. The com.mathworks.jmi.Callback object still
exists and holds a reference to the object of the CallbackWithJava class, which prevents
destruction of the MATLAB object.
clear classes
Warning: Objects of 'CallbackWithJava' class exist. Cannot clear this class or
any of its superclasses.
To avoid causing inaccessible objects, call delete explicitly before losing the handle to the MATLAB
object.
function testDestructor
cwj = CallbackWithJava
...
delete(cwj)
end
MATLAB applications that use Java objects should manage the lifecycle of the objects involved. A
typical user interface application references Java objects from MATLAB objects and creates callbacks
on Java objects that reference MATLAB objects.
• Explicitly call delete on the MATLAB objects when they are no longer needed
• Unregister the Java object callbacks that reference MATLAB objects
• Use intermediate handle objects that reference both the Java callbacks and the MATLAB objects.
7-19
7 Value or Handle Class — Which to Use
See Also
More About
• “Handle Object Behavior” on page 1-7
7-20
Find Handle Objects and Properties
function HM = findobj(H,<conditions>)
The findobj method returns an array of handles matching the conditions specified. You can use
regular expressions with findobj. For more information, see regexp.
function mp = findprop(h,'PropertyName')
The property can also be a dynamic property created by the addprop method of the dynamicprops
class.
Use the returned meta.property object to obtain information about the property, such as the
settings of any of its attributes. For example, the following statements determine that the setting of
the AccountStatus property Dependent attribute is false.
ba = BankAccount(007,50,'open');
mp = findprop(ba,'AccountStatus');
mp.Dependent
ans =
0
See Also
handle
Related Examples
• “Class Metadata” on page 17-2
7-21
7 Value or Handle Class — Which to Use
You can add set and get functionality to your class by deriving from one of these classes:
• matlab.mixin.SetGet — use when you want support for case-insensitive, partial property name
matching. Deriving from matlab.mixin.SetGet does not affect the exact property name
required by the use of dot notation reference to properties.
• matlab.mixin.SetGetExactNames — use when you want to support only case-sensitive full
property name matching.
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 8-39 for information on
property access methods.
Subclass Syntax
Use the abstract class matlab.mixin.SetGet or matlab.mixin.SetGetExactNames as a
superclass:
classdef MyClass < matlab.mixin.SetGet
...
end
If you specify an array of handles with a single property name, get returns the property value for
each object as a cell array of values:
7-22
Implement Set/Get Interface for Properties
CV = get(H,'PropertyName');
If you specify a cell array of char vector property names and an array of handles, get returns a cell
array of property values. Each row in the cell corresponds to an object in the handle array. Each
column in the cell corresponds to a property name.
props = {'PropertyName1','PropertyName2'};
CV = get(H,props);
If you specify a handle array, but no property names, get returns an array of type struct in which
each structure in the array corresponds to an object in H. Each field in each structure corresponds to
a property defined by the class of H. The value of each field is the value of the corresponding property.
SV = get(H);
For an example, see “Using get with Arrays of Handles” on page 7-25.
set(H,'PropertyName',PropertyValue)
You can pass a cell array of property names and a cell array of property values to set:
props = {'PropertyName1','PropertyName2'};
vals = {Property1Value,Property2Value};
set(H,props,vals)
If length(H) is greater than one, then the property value cell array (vals) can have values for each
property in each object. For example, suppose length(H) is 2 (two object handles). You want to
assign two property values on each object:
props = {'PropertyName1','PropertyName2'};
vals = {Property11Value,Property12Value;Property21Value,Property22Value};
set(H,props,vals))
If you specify a scalar handle, but no property names, set returns a struct with one field for each
property in the class of H. Each field contains an empty cell array.
SV = set(h);
7-23
7 Value or Handle Class — Which to Use
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')
MATLAB calls property access methods (set.Style or set.Marker in the LineType class) when
you use the set and get methods.
set(h,'Style','-.-')
For more information on property access methods, see “Property Access Methods” on page 8-39
7-24
Implement Set/Get Interface for Properties
Return a struct containing object properties and their current values using get:
h = LineType('--','*');
SV = get(h)
SV =
Style: '--'
Marker: '*'
Units: 'points'
Return a struct containing the properties that have public SetAccess using set:
S = set(h)
S =
Style: {}
Marker: {}
The LineType class defines the Units property with SetAccess = protected. Therefore, S =
set(h) does not create a field for Units in S.
set cannot return possible values for properties that have nonpublic set access.
H = [LineType('..','z'),LineType('--','q')]
H =
Style
Marker
Units
When H is an array of handles, get returns a (length(H)-by-1) cell array of property values:
CV = get(H,'Style')
CV =
'..'
'--'
When H is an array of handles and you do not specify a property name, get returns a struct array
containing fields with names corresponding to property-names. Assign the output of get to a variable
when H is not scalar.
SV = get(H)
SV =
7-25
7 Value or Handle Class — Which to Use
Style
Marker
Units
Get the value of the Marker property from the second array element in the SV array of structures:
SV(2).Marker
ans =
You can pass an array of handles, a cell array of property names, and a cell array of property values
to set. The property value cell array must have one row of property values for each object in H. Each
row must have a value for each property in the property name array:
H = [LineType('..','z'),LineType('--','q')];
set(H,{'Style','Marker'},{'..','o';'--','x'})
H(1)
ans =
Style: '..'
Marker: 'o'
Units: 'points
H(2)
ans =
Style: '--'
Marker: 'x'
Units: 'points'
Customize the way property lists display by redefining the following methods in your subclass:
• setdisp — When you call set with no output argument and a single scalar handle input, set
calls setdisp to determine how to display the property list.
• getdisp — When you call get with no output argument and a single scalar handle input, get
calls getdisp to determine how to display the property list.
7-26
Implement Set/Get Interface for Properties
The inherited set and get methods can resolve inexact property names when there are no
ambiguities resulting from inexact name strings. When a partial property name is ambiguous because
the name matches more than one property, the PartialMatchPriority attribute value can
determine which property MATLAB matches.
For example, in this class the Verbosity property has a higher priority for name matching than the
Version property.
Calling the set method with the potentially ambiguous inexact name Ver sets the Verbosity
property because of its higher relative priority. Without setting the PartialMatchPriority
attribute, the ambiguous name would cause an error.
a = MyClass;
set(a,"Ver",10)
disp(a)
Verbosity: 10
Version: []
v = get(a,"Ver")
v =
10
A full name match with nonmatching case takes precedence over a partial match with a higher
priority property. For example, this class defines the BaseLine property with a priority of 1 (the
default) and a Base property with a priority of 2 (lower than 1).
7-27
7 Value or Handle Class — Which to Use
Calling the set method with the string base sets the Base property. BaseLine has a higher priority,
but the full name match with incorrect case takes precedence.
a = MyClass;
set(a,"base",-2)
disp(a)
BaseLine: []
Base: -2
You can use the PartialMatchPriority attribute to avoid introducing code incompatibilities when
adding a new property. For example, this class enables the set and get methods to refer to the
Distance property with the string Dis because the DiscreteSamples property has a lower
priority.
Version 2.0 of the class introduces a property named Discontinuities. To prevent the possibility of
causing an ambiguous partial property name in existing code, use PartialMatchPriority to set
the priority of Discontinuities lower than that of previously existing properties.
For version 1.0 of the Planet class, this call to the set method was not ambiguous.
p = Planet;
set(p,"Disc",true)
However, with the introduction of the Discontinuities property, the string Disc becomes
ambiguous. By giving the Discontinuities property a lower priority, the string Disc continues to
match the DiscreteSamples property.
7-28
Implement Set/Get Interface for Properties
Note When writing reusable code, using complete, case-sensitive property names avoids
ambiguities, prevents incompatibilities with subsequent software releases, and produces more
readable code.
See Also
get | matlab.mixin.SetGet | matlab.mixin.SetGetExactNames | set
More About
• “Ways to Use Properties” on page 8-2
7-29
7 Value or Handle Class — Which to Use
In this section...
“Copy Method for Handle Classes” on page 7-30
“Customize Copy Operation” on page 7-31
“Copy Properties That Contain Handles” on page 7-32
“Exclude Properties from Copy” on page 7-33
Create an object of the CopyObj class and assign the handle of a line object to the property Prop.
a = CopyObj;
a.Prop = line;
b = copy(a);
a == b
ans =
logical
However, the line object referred to by a.Prop has not been copied. The handle contained in
a.Prop refers to the same object as the handle contained in b.Prop.
a.Prop == b.Prop
ans =
logical
For more detailed information on the behavior of the copy operation, see copy.
7-30
Implement Copy for Handle Classes
• copy — Sealed method that defines the interface for copying objects
• copyElement — Protected method that subclasses can override to customize object copy
operations for the subclass
The matlab.mixin.Copyable copy method, calls the copyElement method. Your subclass
customizes the copy operation by defining its own version of copyElement.
The default implementation of copyElement makes shallow copies of all the nondependent
properties. copyElement copies each property value and assigns it to the new (copied) property. If a
property value is a handle object, copyElement copies the handle, but not the underlying data.
To implement different copy behavior for different properties, override copyElement. For example,
the copyElement method of the SpecializedCopy class:
a = SpecializedCopy;
a.Prop1 = 7
a =
Prop1: 7
Prop2: '17-Feb-2015 17:51:23'
b = copy(a)
b =
7-31
7 Value or Handle Class — Which to Use
Prop1: 7
Prop2: '17-Feb-2015 17:51:58'
The copy (object b) has the same value for Prop1, but the subclass copyElement method assigned a
new value to Prop2. Notice the different timestamp.
Suppose that you define a class that stores a handle in an object property. You want to be able to copy
objects of the class and want each copy of an object to refer to a new handle object. Customize the
class copy behavior using these steps:
The “HandleCopy” on page 7-32 class customizes copy operations for the property that contains a
handle object. The “ColorProp” on page 7-33 class defines the handle object to assign to Prop2:
Make a copy of the object using the copy method inherited from matlab.mixin.Copyable:
b = copy(a);
Demonstrate that the handle objects contained by objects a and b are independent. Changing the
value on object a does not affect object b:
a.Prop2.Color = 'red';
b.Prop2.Color
ans =
blue
HandleCopy
The HandleCopy class customizes the copy operation for objects of this class.
classdef HandleCopy < matlab.mixin.Copyable
properties
7-32
Implement Copy for Handle Classes
ColorProp
The ColorProp class defines a color by assigning an RGB value to its Color property.
classdef ColorProp < handle
properties
Color = 'blue';
end
end
For classes that derive from matlab.mixin.Copyable, the default implementation of copyElement
honors the NonCopyable attribute. Therefore, if a property has its NonCopyable attribute set to
true, then copyElement does not copy the value of that property. If you override copyElement in
your subclass, you can choose how to use the NonCopyable attribute.
7-33
7 Value or Handle Class — Which to Use
Default Values
If a property that is not copyable has a default value assigned in the class definition, the copy
operation assigns the default value to the property. For example, the CopiedClass assigns a default
value to Prop2.
a = CopiedClass;
a.Prop1 = 7
a =
Prop1: 7
Prop2: '17-Feb-2015 15:19:34'
b = copy(a)
b =
Prop1: []
Prop2: '17-Feb-2015 15:19:34'
In the copy b, the value of Prop1 is not copied. The value of Prop2 is set to its default value, which
MATLAB determined when first loading the class. The timestamp does not change.
Subclasses of the dynamicprops class allow you to add properties to an object of the class. When a
class derived from dynamicprops is also a subclass of matlab.mixin.Copyable, the default
implementation of copyElement does not copy dynamic properties. The default value of
NonCopyable is true for dynamic properties.
The default implementation of copyElement honors the value of a dynamic property NonCopyable
attribute. If you want to allow copying of a dynamic property, set its NonCopyable attribute to
false. Copying a dynamic property copies the property value and the values of the property
attributes.
For example, this copy operation copies the dynamic property, DynoProp, because its NonCopyable
attribute is set to false. The object obj must be an instance of a class that derives from both
dynamicprops and matlab.mixin.Copyable:
obj = MyDynamicClass;
p = addprop(obj,'DynoProp');
7-34
Implement Copy for Handle Classes
p.NonCopyable = false;
obj2 = copy(obj);
See Also
matlab.mixin.Copyable
Related Examples
• “Dynamic Properties — Adding Properties to an Instance” on page 8-54
7-35
8
In some ways, properties are like fields of a struct object. However, storing data in an object
property provides more flexibility. Properties can:
• Define a constant value that you cannot change outside the class definition. See “Define Class
Properties with Constant Values” on page 15-2.
• Calculate its value based on the current value of other data. See “Property Get Methods” on page
8-47.
• Execute a function to determine if an attempt to assign a value meets a certain criteria. See
“Property Set Methods” on page 8-44.
• Trigger an event notification when any attempt is made to get or set its value. See “Property-Set
and Query Events” on page 11-14.
• Control access by code to the property values. See the SetAccess and GetAccess attributes
“Property Attributes” on page 8-7.
• Control whether its value is saved with the object in a MAT-file. See “Save and Load Objects” on
page 13-2.
For an example of a class that defines and uses a class, see “Create a Simple Class” on page 2-2.
Types of Properties
There are two types of properties:
8-2
Ways to Use Properties
• Can use a set access method to control possible values when set
Dependent properties save memory because property values that depend on other values are
calculated only when needed.
• 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).
For examples of classes that use dependent properties, see “Calculate Data on Demand” on page 3-17
and “A Class Hierarchy for Heterogeneous Arrays” on page 21-2.
See Also
Related Examples
• “Property Attributes” on page 8-7
• “Validate Property Values” on page 8-20
• “Property Access Methods” on page 8-39
• “Static Properties” on page 5-52
8-3
8 Properties — Storing Class Data
Property Syntax
In this section...
“Property Definition Block” on page 8-4
“Access Property Values” on page 8-5
“Inheritance of Properties” on page 8-5
“Specify Property Attributes” on page 8-5
The preceding example shows the Coefficients property specified as having a default value of [0
0 1].
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 “Property Default Values” on page 8-14 for more information about
how MATLAB evaluates default value expressions.
8-4
Property Syntax
Property names must be listed on separate lines. MATLAB interprets a name following a property
name as the name of a class.
You can restrict property values by associating a class with the property in the property definition.
For example, the definition of MyData requires that values assigned to this property must be of type
int32 or types that are compatible with int32.
properties
MyData int32
end
val = obj.PropertyName
Assign values to properties by putting the property reference on the left side of the equal sign:
obj.PropertyName = val
When you access a property, MATLAB executes any property set or get access method and triggering
any enabled property 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 are used by more than one subclass.
For example, the following code shows the SetAccess attribute set to private for the
IndependentVar and Order properties, but not for the Coefficients property:
8-5
8 Properties — Storing Class Data
For information about the properties of a specific class, use the properties function.
See Also
Related Examples
• “Validate Property Values” on page 8-20
• “Property Definition” on page 8-13
• “Property Attributes” on page 8-7
8-6
Property Attributes
Property Attributes
In this section...
“Purpose of Property Attributes” on page 8-7
“Specifying Property Attributes” on page 8-7
“Table of Property Attributes” on page 8-7
For more information on attribute syntax, see “Attribute Specification” on page 5-18.
8-7
8 Properties — Storing Class Data
Property Attributes
8-8
Property Attributes
8-9
8 Properties — Storing Class Data
8-10
Property Attributes
8-11
8 Properties — Storing Class Data
See Also
Related Examples
• “Property Definition” on page 8-13
8-12
Property Definition
Property Definition
In this section...
“What You Can Define” on page 8-13
“Initialize Property Values” on page 8-13
“Property Default Values” on page 8-14
“Initializing Properties to Handle Objects” on page 8-14
“Assign Property Values in Constructor” on page 8-15
“Property Attributes” on page 8-16
“Methods to Set and Get Property Values” on page 8-16
“Reference Object Properties Using Variables” on page 8-17
• Specify a default value for each property individually, see “Property Default Values” on page 8-
14.
• Assign property values in a class constructor, see “Assign Property Values in Constructor” on page
8-15.
• Define properties with constant values, see “Named Values” on page 14-2.
• Assign property attribute values on a per block basis, see “Property Attributes” on page 8-16.
• Define methods that execute when the property is set or queried, see “Methods to Set and Get
Property Values” on page 8-16.
• Define the class and size of property values, see “Validate Property Values” on page 8-20.
• Define properties that do not store values, but whose values depend on other properties, see
“Types of Properties” on page 8-2.
• In the property definition — MATLAB evaluates the expression only once and assigns the same
value to the property of every instance.
• In a class constructor — MATLAB evaluates the assignment expression for each instance, which
ensures that each instance has a unique value.
For more information on the evaluation of expressions that you assign as property default values, see
“When MATLAB Evaluates Expressions” on page 6-10.
8-13
8 Properties — Storing Class Data
classdef ClassName
properties
Prop1
Prop2 = 'some text'
Prop3 = sin(pi/12)
Prop4 = containers.Map
Prop5 (1,1) double {mustBePositive} = 1
end
end
If the class definition does not specify a default property value, MATLAB initializes the property value
to empty double ([]). If the class specifies any class, size, or validation function restrictions on the
property value, then the class must ensure that the default value satisfies those restrictions by
assigning a valid value when an empty value is invalid.
Note 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 an instance of the class.
For more information on the evaluation of expressions that you assign as property default values, see
“Evaluation of Expressions in Class Definitions” on page 6-8 and “Properties Containing Objects” on
page 8-52.
For information on class, size, and validation functions used in property definitions, see “Validate
Property Values” on page 8-20.
If you want a property value to be initialized to a new instance of a handle object each time you
create an object of your class, assign the property value in the constructor.
8-14
Property Definition
classdef MyClass
properties
Prop1
end
methods
function obj = MyClass(intval)
% Initialize Prop1 for each instance
obj.Prop1 = intval;
end
end
end
When you assign a property in the class constructor, MATLAB evaluates the assignment statement for
each object you create. Assign property values in the constructor if you want each object to contain a
unique value for that property.
For example, suppose that you want to assign a unique handle object to the property of another
object each time you create one of the other objects. Assign the handle object to the property in the
constructor. Call the handle object constructor to create a unique handle object with each instance of
your class.
classdef ContainsHandle
properties
Prop1
end
methods
function obj = ContainsHandle(keySet,valueSet)
obj.Prop1 = MyHandleClass(keySet,valueSet);
end
end
end
For more information on constructor methods, see “Referencing the Object in a Constructor” on page
9-19.
MATLAB validates property default values before the assignment of values in the constructor. It is
necessary for the default value assigned in the properties block and the property value set in a
class constructor to satisfy the specified validation. For example, this class restricts Prop to a scalar
positive double, but does not assign a valid default value. By default, MATLAB assigns a default value
of empty double, which causes a run-time error.
classdef PropInit
properties
% Error without valid default value
Prop (1,1) double {mustBePositive}
% Empty default fails mustBePositive
end
methods
function obj = PropInit(positiveInput)
obj.Prop = positiveInput;
end
end
end
8-15
8 Properties — Storing Class Data
Calling the class constructor with a valid value for Prop results in an error from the validation
function mustBePositive.
obj = PropInit(2);
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 ClassName
properties (PropertyAttribute = value)
Prop1
Prop2
end
end
For example, only methods in the same class definition can modify and query the Salary and
Password properties.
classdef EmployeeInfo
properties (Access = private)
Salary
Password
end
end
This restriction exists because the class defines these properties in a properties block with the
Access attribute set to private.
Property Attributes
For a description of property attributes you can specify, see, “Property Attributes” on page 8-7.
methods
end
For specific information on access method syntax, see “Property Get Methods” on page 8-47 and
“Property Set Methods” on page 8-44.
8-16
Property Definition
MATLAB does not call the property set access method when assigning the default value specified in
the property's definition block.
For example, the set.Password method tests the length of the character array assigned to a
property named Password. If there are fewer than seven characters in the value assigned to the
property, MATLAB returns the error. Otherwise, MATLAB assigns the specified value to the property.
For more information on property access methods, see “Property Access Methods” on page 8-39.
object.(PropertyNameVar)
where PropertyNameVar is a variable containing the name of a valid object property. Use this
syntax when passing property names as arguments. For example, the getPropValue function returns
the value of the KeyType property:
PropName = 'KeyType';
function o = getPropValue(obj,PropName)
o = obj.(PropName);
end
See Also
Related Examples
• “Evaluation of Expressions in Class Definitions” on page 6-8
• “Ways to Use Properties” on page 8-2
• “Validate Property Values” on page 8-20
8-17
8 Properties — Storing Class Data
In this section...
“Set Access to Property Values” on page 8-18
“Define Immutable Property” on page 8-18
• SetAccess = public — 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.
• SetAccess = protected — 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.
• SetAccess = private — Only the defining class can set property values. You can change the
value of an object property only if the class defines a method that sets the property.
• SetAccess = immutable — Property value is set during construction. You cannot change the
value of an immutable property after the object is created. Set the value of the property as a
default or in the class constructor. You cannot define a property set method (set.PropertyName)
for an immutable property.
classdef Immute
properties (SetAccess = immutable)
CurrentDate
end
methods
function obj = Immute
obj.CurrentDate = date;
end
end
end
a = Immute
a =
CurrentDate: '19-Oct-2005'
8-18
Mutable and Immutable Properties
See Also
Related Examples
• “Property Attributes” on page 8-7
• “Object Modification” on page 5-49
8-19
8 Properties — Storing Class Data
For more information on property validation, see “Property Class and Size Validation” on page 8-25,
“Property Validation Functions” on page 8-31, and “Metadata Interface to Property Validation” on
page 8-37.
Validation Syntax
The highlighted area in the following code shows the syntax for property validation.
• Size — The length of each dimension, specified as a positive integer or a colon. A colon indicates
that any length is allowed in that dimension. The value assigned to the property must conform to
the specified size or be compatible with the specified size. For more information, see “Property
Size Validation” on page 8-25.
• Class — The name of a single MATLAB class. The value assigned to the property must be of the
specified class or convertible to the specified class. Use any MATLAB class or externally defined
class that is supported by MATLAB, except for Java and COM classes. For more information, see
“Property Class Validation” on page 8-26.
8-20
Validate Property Values
• Functions — A comma-separated list of validation function names. MATLAB passes the value
assigned to the property to each the validation functions after applying any possible class and size
conversions. Validator functions throw errors if the validation fails, but do not return values. For
more information, see “Property Validation Functions” on page 8-31.
For a list of MATLAB validation functions, see “MATLAB Validation Functions” on page 8-33.
Use property validation for public properties to control the values user code assigns to the properties.
If you want to restrict property values to a fixed set of identifiers, create an enumeration class for
these identifiers and constrain the property to this class. For information on enumeration classes, see
“Define Enumeration Classes” on page 14-4.
MATLAB type conversion rules apply to property validation. For example, MATLAB can coerce from
one to another numeric type. Therefore, restricting a property value to a specific numeric type, such
as double does not prevent the assignment of other numeric types to the property.
To ensure that a property can be assigned only a specific type of value, restrict the property to a type
that supports only the desired type conversions or use a validation function to specify the exact class
allowed for the property instead of specifying the property type. MATLAB evaluates the type
specification before executing any validation functions. For more information, see “Order of
Validation” on page 8-22.
Ensure that any default value assigned to the property meets the restrictions imposed by the
specified validation. If you do not specify a default value, MATLAB creates a default value by
assigning an empty object of the specified class or by calling the default constructor if size restriction
does not allow the use of an empty default value. The default constructor must return an object of the
correct size.
• Location must be a 1-by-3 array of class double whose values are real, finite numbers.
• Label must be a char vector that is either 'High', 'Medium', or 'Low'.
• State must be an enumeration member of the matlab.lang.OnOffSwitchState class (off or
on).
Validation at Instantiation
Creating an object of the ValidateProps class performs the validation on implicit and explicit
default values:
a = ValidateProps
8-21
8 Properties — Storing Class Data
a =
Location: [0 0 0]
Label: 'Low'
State: off
• Initializes the Location property value to [0 0 0] to satisfy the size and class requirements.
• Sets the Label property to its default value, 'Low'. The default value must be a member of the
allowed set of values. The empty char implicit default value would cause an error.
• Sets the State property to the off enumeration member defined by the
matlab.lang.OnOffSwitchState class.
For information on how MATLAB selects default values, see “Default Values Per Size and Class” on
page 8-30.
Order of Validation
When a value is assigned to the property, including default values that are specified in the class
definition, MATLAB performs validation in this order:
• Class validation — This validation can cause conversion to a different class, such as conversion of
a char to string. Assignment to properties follows MATLAB coercion rules for arrays.
• Size validation — This validation can cause size conversion, such as scalar expansion or
conversion of a column vector to a row vector. Assignment to a property that specifies a size
validation behaves the same as assignment to any MATLAB array. For information on indexed
assignment, see “Array Indexing”.
• Validator functions — MATLAB passes the result of the class and size validation to each validation
function, in left to right order. An error can occur before all validation functions have been called,
which ends the validation process.
• Set method — MATLAB performs property validation before calling a property set method, if one
is defined for that property. Assignment to the property within a property set or get method does
not apply the validation again. Often, you can replace property set methods using property
validation.
The ValueProp class uses size, class, and function validation to ensure that an assignment to the
Value property is a double scalar that is not negative.
classdef ValueProp
properties
Value(1,1) double {mustBeNonnegative} = 0
end
end
This statement attempts to assign a cell array to the property. This assignment violates the class
validation.
a.Value = {10,20};
8-22
Validate Property Values
This statement attempts to assign a 1-by-2 double array to the property. This assignment violates the
size validation.
a.Value = [10 20];
This statement attempts to assign a scalar double to the property. This assignment fails the function
validation, which requires a nonnegative number.
a.Value = -10;
If a class definition changes the property validation such that the loaded property value is no longer
valid, MATLAB substitutes the currently defined default value for that property. However, the load
function suppresses the validation errors that occur before assigning the default value from the
current class definition. Therefore, validation errors are silently ignored during load operations.
To illustrate this behavior, this example creates, saves, and loads an object of the MonthTemp class.
This class restricts the AveTemp property to a cell array.
classdef MonthTemp
properties
AveTemp cell
end
end
8-23
8 Properties — Storing Class Data
a = MonthTemp;
a.AveTemp = {'May',70};
save TemperatureFile a
Edit the property definition to change the validation class for the AveTemp property from cell array to
containers.Map.
classdef MonthTemp
properties
AveTemp containers.Map
end
end
Load the saved object with the new class definition on the MATLAB path. MATLAB cannot assign the
saved value to the AveTemp property because the cell array, {'May',70}, is not compatible with the
current requirement that the property value be a containers.Map object. MATLAB cannot convert
a cell array to a containers.Map.
To address the incompatibility, MATLAB sets the AveTemp property of the loaded object to the
current default value, which is an empty containers.Map object.
load TemperatureFile a
a.AveTemp
ans =
Count: 0
KeyType: char
ValueType: any
The loaded object has a different value assigned to the AveTemp property because the saved value is
now invalid. However, the load process suppresses the validation error.
To prevent loss of data when changing class definitions and reloading objects, implement a loadobj
method or class converter method that enables the saved values to satisfy the current property
validation.
For more information on saving and loading objects, see “Save and Load Process for Objects” on page
13-2.
See Also
Related Examples
• “Property Class and Size Validation” on page 8-25
• “Property Validation Functions” on page 8-31
8-24
Property Class and Size Validation
For more information, see “Order of Validation” on page 8-22 and “Property Validation Functions” on
page 8-31.
classdef MyClass
properties
Prop(dim1,dim2,...) = defaultValue
end
end
This class defines the size of the Location property as 1-by-3. Any value assigned to this property
must conform to that size or must be convertible to that size.
classdef ValidateProps
properties
Location(1,3)
end
end
The implicit default value assigned by MATLAB, [0 0 0], conforms to the specified size:
a = ValidateProps
a =
Location: [0 0 0]
MATLAB applies scalar expansion when you assign a scalar the Location property.
a = ValidateProps;
a.Location = 1
8-25
8 Properties — Storing Class Data
a =
Location: [1 1 1]
col = [1;1;1]
col =
1
1
1
a.Location = col
a =
Location: [1 1 1]
A colon in the size specification indicates that the corresponding dimension can have any length. For
example, you can assign a value of any length to the Label property in this class.
classdef ValidateProps
properties
Label(1,:)
end
end
a = ValidateProps;
a.Label = 'Click to Start'
a =
Assignment to a property that defines size validation follows the same rules as the equivalent indexed
array assignment. For information on indexing behavior of multidimensional arrays, see “Compatible
Array Sizes for Basic Operations”.
You can specify only one class per property. Use validation functions like mustBeNumeric or
mustBeInteger to restrict properties to a broader category of classes. For more information on
validation functions, see “Property Validation Functions” on page 8-31.
8-26
Property Class and Size Validation
You can use any MATLAB class or externally defined class that is supported by MATLAB, except Java
and COM classes.
Place the name of the class in the property definition block following the property name and optional
size specification.
classdef MyClass
properties
Prop ClassName = defaultValue
end
end
If you do not specify a default value, MATLAB assigns an empty object of the specified class to the
property. If you define a size and a class, MATLAB attempts to create a default value for the property
that satisfies both the size and class requirement.
MATLAB creates the default value by calling the class constructor with no arguments. The class must
have a constructor that returns an object of the specified size when called with no input arguments or
you must specify a default value for the property that satisfies the property size restriction. For more
information, see “Default Values Per Size and Class” on page 8-30.
classdef PropsWithClass
properties
Number double
Today char = date
end
end
p = PropsWithClass
p =
Number: []
Today: '10-Sep-2016'
MATLAB performs conversions from any compatible class to the property class. For example, assign a
datetime array to the Today property.
p.Today = [datetime('now'),datetime('tomorrow')];
disp(class(p.Today))
ans =
char
8-27
8 Properties — Storing Class Data
Because the datetime class has a char converter, you can assign a datetime array to the Today
property.
Assigning an incompatible value to a property that uses class validation causes an error.
p.Number = datetime('now');
You can define a class to control the values assigned to a property. Enumeration classes enable users
to set property values to character vectors or string scalars with inexact name matching.
For example, suppose that there is a class that represents a three-speed mechanical pump. You can
define an enumeration class to represent the three flow rates.
classdef FlowRate < int32
enumeration
Low (10)
Medium (50)
High (100)
end
end
The Pump class has a method to return the current flow rate in gallons per minute. Define the Speed
property as a FlowRate class.
classdef Pump
properties
Speed FlowRate
end
methods
function getGPM(p)
if isempty(p.Speed)
gpm = 0;
else
gpm = int32(p.Speed);
end
fprintf('Flow rate is: %i GPM\n',gpm);
end
end
end
p =
Speed: Medium
8-28
Property Class and Size Validation
For information about enumeration classes, see “Define Enumeration Classes” on page 14-4.
MATLAB supports several integer classes (see “Integers”). However, restricting a property to an
integer class can result in integer overflow. The resulting value can saturate at the maximum or
minimum value in the integer’s range.
When integer overflow occurs, the value that is assigned to a property can be a value that is different
from the value from the right side of the assignment statement.
For example, suppose that you want to restrict a property value to a scalar uint8.
classdef IntProperty
properties
Value(1,1) uint8
end
end
Assigning a numeric value to the Value property effectively casts the numeric value to uint8, but
does not result in an error for out-of-range values.
a = IntProperty;
a.Value = -10;
disp(a.Value)
Assignment to the Value property is equivalent to indexed assignment of an array. If the assigned
value is out of the range of values that uint8 can represent, MATLAB sets the value to the closest
value that it can represent using uint8.
a = uint8.empty;
a(1) = -10
a =
uint8
To avoid the potential for integer overflow, use a combination of validation functions that restrict the
value to the intended range instead of an integer class.
classdef IntProperty
properties
Value(1,1) {mustBeInteger, mustBeNonnegative,...
mustBeLessThan(Value,256)}
end
end
Because there is no conversion of the assigned value by the uint8 class, the validators catch out of
range values and throw an appropriate error.
a = IntProperty;
a.Value = -10;
8-29
8 Properties — Storing Class Data
MATLAB defines a default value implicitly if you do not specify a default value in the class definition.
This table shows how size and class determine the implicit default value of MATLAB classes.
To determine the implicit default value for nonzero and explicit size specifications, MATLAB calls the
default class constructor and builds an array of the specified size using the instance returned by the
constructor call. If the class does not support a default constructor (that is, a constructor called with
no arguments), then MATLAB throws an error when instantiating the class containing the validation.
If the specified size has any zero or unrestricted (:) dimensions, MATLAB creates a default value that
is an empty array with the unrestricted dimension set to zero.
For heterogeneous arrays, MATLAB calls the getDefaultScalarElement method to get the default
object.
See Also
Related Examples
• “Validate Property Values” on page 8-20
• “Property Validation Functions” on page 8-31
• “Enumerations for Property Values” on page 14-14
8-30
Property Validation Functions
During the validation process, MATLAB passes the value to each validation function listed in the class
definition. MATLAB calls each function from left to right and throws the first error encountered. The
value passed to the validation functions is the result of any conversion applied by the class and size
specifications. For more information on class and size validation, see “Property Class and Size
Validation” on page 8-25.
For a list of MATLAB validation functions, see “MATLAB Validation Functions” on page 8-33
Specify validation functions as a comma-separated list of function names or function calls with
arguments, enclosed in braces.
classdef MyClass
properties
Prop {fcn1,fcn2,...} = defaultValue
end
end
MATLAB passes the potential property value to the validation function implicitly. However, if the
validation function requires input arguments in addition to the potential property value, then you
must include both the property and the additional arguments. Additional arguments must be literal
values and cannot reference variables. Literal values are nonsymbolic representations, such as
numbers and text.
For example, consider the function mustBeGreaterThan. It requires a limiting value as an input
parameter. This validation function requires that a property value must be greater than this limiting
value.
Pass the property as the first argument. Use the property name, but do not enclose the name in
quotation marks. This property definition restricts Prop to values greater than 10.
properties
Prop {mustBeGreaterThan(Prop,10)}
end
8-31
8 Properties — Storing Class Data
a = ValidatorFunction
a =
Data: []
Interp: 'linear'
a.Data = 'cubic'
Because the Data property validation does not include a numeric class, there is no conversion of the
char vector to a numeric value. If you change the validation of the Data property to specify the class
as double, MATLAB converts the char vector to a double array.
properties
Data double {mustBeNumeric, mustBeFinite}
end
The assignment to the char vector does not produce an error because MATLAB converts the char
vector to class double.
a.Data = 'cubic'
a =
a = ValidatorFunction;
a.Interp = 'cu'
8-32
Property Validation Functions
For example, suppose that you define the InterpMethod enumeration class for the Interp property
validation.
classdef InterpMethod
enumeration
linear
cubic
spline
end
end
classdef ValidatorFunction
properties
Data {mustBeNumeric, mustBeFinite}
Interp InterpMethod
end
end
a = ValidatorFunction;
a.Interp = 'cu'
a =
Data: []
Interp: cubic
8-33
8 Properties — Storing Class Data
8-34
Property Validation Functions
Creating your own validation function is useful when you want to provide specific validation that is
not available using the MATLAB validation functions. You can create local functions within the class
file or place the function on the MATLAB path to be available for use in any class.
For example, the ImData class uses a local function to define a validator that restricts the Data
property to a specific range of numeric values.
classdef ImData
properties
Data {mustBeNumeric, mustBeInRange(Data,[0,255])} = 0
end
end
function mustBeInRange(a,b)
if any(a(:) < b(1)) || any(a(:) > b(2))
error(['Value assigned to Data property is not in range ',...
num2str(b(1)),'...',num2str(b(2))])
end
end
When you create an instance of the ImData class, MATLAB validates that the default value is
numeric, in the range 0...255, and not empty.
a = ImData
a =
Data: 0
Property assignment invokes the validators in left-to-right order. Assigning a char vector to the Data
property causes an error thrown by mustBeNumeric.
a.Data = 'red'
Assigning a numeric value that is out of range causes an error thrown by mustBeInRange.
a.Data = -1
8-35
8 Properties — Storing Class Data
the validation function reference pages listed in this table “MATLAB Validation Functions” on page 8-
33.
For example, suppose that you want your class to support the mustBeGreaterThan validation
function. Overload these MATLAB functions as methods in your class:
• isreal — Always return logical true because mustBeGreaterThan does not support complex
numbers.
• gt — The second object in the comparison must be scalar, as required by mustBeGreaterThan.
classdef SupportmBGT
properties
Prop(1,1) double {mustBeReal}
end
methods
function obj = SupportmBGT(data)
if nargin > 0
obj.Prop = data;
end
end
function tf = isreal(obj)
tf = true;
end
function tf = gt(obj1, obj2)
tf = [obj1(:).Prop] > obj2.Prop;
end
end
end
a = SupportmBGT(10);
b = SupportmBGT(12);
mustBeGreaterThan(a,b)
See Also
Related Examples
• “Validate Property Values” on page 8-20
• “Property Class and Size Validation” on page 8-25
8-36
Metadata Interface to Property Validation
You can determine what validation applies to a property by accessing the validation metadata.
Instances of the meta.Validation class provide the following information about property
validation.
For example, the ValidationExample class defines a property that must be an array of doubles that
is 1-by-any number of elements and must be a real number that is greater than 10.
classdef ValidationExample
properties
Prop (1,:) double {mustBeReal, mustBeGreaterThan(Prop, 10)} = 200;
end
end
Access the meta.Validation object from the property's meta.property object. Get the validation
information from the meta.Validation object properties. Collection this information into a cell
array.
mc = ?ValidationExample;
mp = findobj(mc.PropertyList,'Name','Prop');
sz = mp.Validation.Size;
len = length(sz);
dim = cell(1:len);
for k = 1:len
switch class(sz(k))
case 'meta.FixedDimension'
dim{k} = sz(k).Length;
case 'meta.UnrestrictedDimension'
dim{k} = ':';
end
end
dim{end+1} = mp.Validation.Class.Name;
dim{end+1} = mp.Validation.ValidatorFunctions;
See Also
meta.Validation | meta.property
8-37
8 Properties — Storing Class Data
Related Examples
• “Validate Property Values” on page 8-20
• “Property Class and Size Validation” on page 8-25
• “Property Validation Functions” on page 8-31
8-38
Property Access Methods
Use property access methods to provide error checking or to implement side effects resulting from
property access. Examples of access methods include functions that update other property values
when setting the property or translate the format of a property value before returning the value.
For specific information on access method syntax, see “Property Get Methods” on page 8-47 and
“Property Set Methods” on page 8-44.
You can use property validation to restrict the size, class, and other aspects of property values. For
information on property validation, see “Validate Property Values” on page 8-20.
Property access methods do add the overhead of a function call whenever accessing property values.
If performance-critical access to properties occurs inside methods of the class, define private
properties to store values. Use these values inside methods without any error checking. For less
frequent access from outside the class, define public Dependent properties that use access methods
for error checking.
For information on access methods used with Dependent properties, see “Set and Get Methods for
Dependent Properties” on page 8-49.
• Execute code before assigning property values to perform actions such as:
• Calculate the value of properties that do not store values (see “Calculate Data on Demand” on
page 3-17)
8-39
8 Properties — Storing Class Data
To control what code can access properties, see “Property Attributes” on page 8-7.
Note You cannot call property access methods directly. MATLAB calls these methods when you
access property values.
Property access methods execute automatically whenever you set or query the corresponding
property values from outside the access method. MATLAB does not call access methods recursively.
That is, MATLAB does not call the set method when setting the property from within its set method.
Similarly, MATLAB does not call the get method when querying the property value from within its get
method.
Obtain the function handle for the set and get access methods from the property meta.property
object. The meta.property SetMethod and GetMethod properties contain the function handles
that refer to these 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 “When
Set Method Is Called” on page 8-45 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 set and query property values from an instance of the class. See “Implement Set/Get
Interface for Properties” on page 7-22 for information on user-callable set and get methods.
You can set and get property values only from within your property set or get access method. You
cannot call another function from the set or get method and attempt to access the property value
from that function.
For example, an anonymous function that calls another function to do the actual work cannot access
the property value. Similarly, an access function cannot call another function to access the property
value.
8-40
Property Access Methods
Access methods have special names that include the property name. Therefore, get.PropertyName
executes whenever PropertyName is referenced and set.PropertyName executes whenever
PropertyName is assigned a value.
Define property access methods in a methods block that specifies no attributes. You cannot call these
methods directly. MATLAB calls these methods when any code accesses the properties.
Property access methods do not appear in the list of class methods returned by the methods
command and are not included in the meta.class object Methods property.
The property meta.property object contains function handles to the property set and get methods.
SetMethod contains a function handle to the set method. GetMethod contains a function handle to
the get method.
For example, if the class MyClass defines a get method for its Text property, you can obtain a
function handle to this function from the meta.class object:
mc = ?MyClass;
mp = findobj(mc.PropertyList,'Name','Text');
fh = mp.GetMethod;
The returned value, fh, contains a function handle to the get method defined for the specified
property name for the specified class.
If a class computes a property value (Dependent = true), then the behaviors of its set events are
like the get events:
If a property is not computed (Dependent = false, the default), then the assignment statement
with the set method generates the events:
• PreSet — Triggered before assigning the new property value within the set method
8-41
8 Properties — Storing Class Data
• PostSet — Triggered after assigning the new property value within the set method
For information about using property events, see “Create Property Listeners” on page 11-32.
val = obj.PropName(n);
obj.PropName(n) = val;
MATLAB:
The property get methods applies a scale factor before returning its current value:
classdef Testpoint
properties
expectedResult = []
end
properties(Constant)
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
8-42
Property Access Methods
end
function er = get.expectedResult(obj)
er = obj.expectedResult/obj.scalingFactor;
end
end
end
See Also
More About
• “Property Set Methods” on page 8-44
• “Property Get Methods” on page 8-47
• “Properties Containing Objects” on page 8-52
8-43
8 Properties — Storing Class Data
Note You cannot call property access methods directly. MATLAB calls these methods when you
access property values.
Property set methods have the following syntax, where PropertyName is the name of the property.
methods
function obj = set.PropertyName(obj,value)
...
end
Value class set functions must return the modified object to the calling function. Handle classes do
not need to return the modified object.
methods
function set.PropertyName(obj,value)
...
end
Use default method attributes for property set methods. The methods block defining the set method
cannot specify attributes.
8-44
Property Set Methods
classdef MyClass
properties
Prop1
end
methods
function obj = set.Prop1(obj,value)
if (value > 0)
obj.Prop1 = value;
else
error('Property value must be positive')
end
end
end
end
For an example of a property set method, see “Restrict Properties to Specific Values” on page 3-16 .
• A value is assigned to a property from within its own property set method, to prevent recursive
calling of the set method. However, property assignments made from functions called by a set
method do call the set method.
• MATLAB assigns a default value to the property during initialization of an object before calling
object constructor functions.
• When MATLAB copies a value object (any object that is not a handle), MATLAB does not call the
set or get method when copying property values from one object to another.
• Any assignment made to a property value that is the same as the current value when the
property’s AbortSet attribute is true. See “Assignment When Property Value Is Unchanged” on
page 11-35 for more information on this attribute.
Setting a property value in the constructor causes the property set method to be called. For example,
the PropertySetMethod class defines a property set method for the Prop1 property.
classdef PropertySetMethod
properties
Prop1 = "Default String"
end
methods
function obj = PropertySetMethod( str )
if nargin > 0
obj.Prop1 = str;
end
end
8-45
8 Properties — Storing Class Data
end
end
If you call the class constructor with no input arguments, MATLAB does not call the set.Prop1
method.
>> o = PropertySetMethod
o =
Setting the property value in the constructor results in a call to the property set method.
o =
If you copy the object to another variable, MATLAB does not call the property set method even
though the right side object in the assignment uses a nondefault value for the property:
a = o;
a.Prop1
a.Prop1
ans =
"New String"
See Also
Related Examples
• “Property Get Methods” on page 8-47
• “Methods to Set and Get Property Values” on page 8-16
• “Validate Property Values” on page 8-20
8-46
Property Get Methods
Note You cannot call property access methods directly. MATLAB calls these methods when you
access property values.
Property get methods have the following syntax, where PropertyName is the name of the property.
The function must return the property value.
methods
function value = get.PropertyName(obj)
...
end
classdef SquareArea
properties
Width
Height
end
properties (Dependent)
Area
end
methods
function a = get.Area(obj)
a = obj.Width * obj.Height;
end
end
end
8-47
8 Properties — Storing Class Data
Use the property set method to validate the property value. Validating the value when setting a
property ensures that the object is in a valid state. Use the property get method only to return the
value that the set method has validated.
• Getting a property value from within its own property get method, which prevents recursive
calling of the get method
• Copying a value object (that is, not derived from the handle class). The set or get method is not
called when copying property values from one object to another.
See Also
Related Examples
• “Set and Get Methods for Dependent Properties” on page 8-49
8-48
Set and Get Methods for Dependent Properties
Dependent properties do not store data. The value of a dependent property depends on some other
value, such as the value of a nondependent property.
The values returned by dependent property get methods are not considered when testing for object
equality using isequal and isequaln.
To be able to set the value of a dependent property, the property must define a set access method
(set.PropertyName). The property set access method usually assigns the value to another,
nondependent property for storage of the value.
For example, the Account class returns a value for the dependent Balance property that depends
on the value of the Currency property. The get.Balance method queries the Currency property
before calculating a value for the Balance property.
MATLAB calls the get.Balance method when the Balance property is queried. You cannot call
get.Balance explicitly.
Here is a partial listing of the class showing a dependent property and its get method:
classdef Account
properties
Currency
DollarAmount
end
properties (Dependent)
Balance
end
...
methods
function value = get.Balance(obj)
c = obj.Currency;
switch c
case 'E'
v = obj.DollarAmount / 1.1;
case 'P'
v = obj.DollarAmount / 1.5;
otherwise
v = obj.DollarAmount;
end
format bank
value = v;
end
end
end
8-49
8 Properties — Storing Class Data
The get method for the Prop property determines the value of that property and assigns it to the
object from within the method:
This get method calls a function or static method called calculateValue to calculate the property
value and returns value as a result. The property get method can take whatever action is necessary
within the method to produce the output value.
For an example of a property get method, see “Calculate Data on Demand” on page 3-17.
For example, suppose that you have a class that changes the name of a property from OldPropName
to NewPropName. You can continue to allow the use of the old name without exposing it to new users.
To support the old property name, define OldPropName a dependent property with set and get
methods:
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. Code that accesses
OldPropName continues to work as expected. Setting the Hidden attribute of OldPropName
prevents new users from seeing the property.
Assignments made from property set methods cause the execution of any set methods defined for
properties being set. See “Calculate Data on Demand” on page 3-17 for an example.
8-50
Set and Get Methods for Dependent Properties
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:
See Also
Related Examples
• “Property Attributes” on page 8-7
8-51
8 Properties — Storing Class Data
Note 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 an instance of the class.
For more information on the evaluation of expressions that you assign as property default values, see
“When MATLAB Evaluates Expressions” on page 6-10.
• Handle object – you can set properties on handle objects contained in read-only properties
• Value object – you cannot set properties on value object contained in read-only properties.
Assignment Behavior
These classes illustrate the assignment behavior:
• ReadOnlyProps – class with two read-only properties. The class constructor assigns a handle
object of type HanClass to the PropHandle property and a value object of type ValClass to the
PropValue property.
• HanClass – handle class with public property
• ValClass – value class with public property
classdef ReadOnlyProps
properties(SetAccess = private)
PropHandle
PropValue
end
methods
function obj = ReadOnlyProps
obj.PropHandle = HanClass;
8-52
Properties Containing Objects
obj.PropValue = ValClass;
end
end
end
classdef ValClass
properties
Vprop
end
end
a = ReadOnlyProps
a =
Use the private PropHandle property to set the property of the HanClass object it contains:
class(a.PropHandle.Hprop)
ans =
double
a.PropHandle.Hprop = 7;
Attempting to make an assignment to the value class object property is not allowed:
a.PropValue.Vprop = 11;
See Also
More About
• “Mutable and Immutable Properties” on page 8-18
8-53
8 Properties — Storing Class Data
It is possible for more than one program to define dynamic properties on the same object. In these
cases, avoid name conflicts. Dynamic property names must be valid MATLAB identifiers (see
“Variable Names”) and cannot be the same name as a method of the class.
• Set and query the values of dynamic properties using dot notation. (See “Assign Data to the
Dynamic Property” on page 8-55.)
• MATLAB saves and loads dynamic properties when you save and load the objects to which they
are attached. (See “Dynamic Properties and ConstructOnLoad” on page 8-63.)
• Define attributes for dynamic property. (See “Set Dynamic Property Attributes” on page 8-55).
• By default, dynamic properties have their NonCopyable attribute set to true. If you copy an
object containing a dynamic property, the dynamic property is not copied. (See “Objects with
Dynamic Properties” on page 7-34)
• Add property set and get access methods. (See “Set and Get Methods for Dependent Properties”
on page 8-49.)
• Listen for dynamic property events. (See “Dynamic Property Events” on page 8-59.)
• Access dynamic property values from object arrays, with restricted syntax. (See “Accessing
Dynamic Properties in Arrays” on page 10-11.)
• The isequal function always returns false when comparing objects that have dynamic
properties, even if the properties have the same name and value. To compare objects that contain
dynamic properties, overload isequal for your class.
P = addprop(H,'PropertyName')
where:
8-54
Dynamic Properties — Adding Properties to an Instance
H is an array of handles
PropertyName is the name of the dynamic property you are adding to each object
Use only valid names when naming dynamic properties (see “Variable Names”). In addition, do not
use names that:
To set property attributes, use the meta.DynamicProperty object associated with the dynamic
property. For example, if P is the object returned by addprop, this statement sets the property’s
Hidden attribute to true:
P.Hidden = true;
The property attributes Constant and Abstract have no meaning for dynamic properties. Setting
the value of these attributes to true has no effect.
Suppose, you are using a predefined set of user interface widget classes (buttons, sliders, check
boxes, etc.). You want to store the location of each instance of the widget class. Assume that the
widget classes are not designed to store location data for your particular layout scheme. You want to
avoid creating a map or hash table to maintain this information separately.
Assuming the button class is a subclass of dynamicprops, add a dynamic property to store your
layout data. Here is a simple class to create a uicontrol button:
classdef button < dynamicprops
properties
UiHandle
end
methods
function obj = button(pos)
if nargin > 0
if length(pos) == 4
obj.UiHandle = uicontrol('Position',pos,...
'Style','pushbutton');
else
error('Improper position')
end
end
8-55
8 Properties — Storing Class Data
end
end
end
Create an instance of the button class, add a dynamic property, and set its value:
b1 = button([20 40 80 20]);
b1.addprop('myCoord');
b1.myCoord = [2,3];
Access the dynamic property just like any other property, but only on the object on which you defined
it:
b1.myCoord
ans =
2 3
Using nonpublic Access with dynamic properties is not recommended because these properties
belong to specific instances that are often created outside of class methods. The Access attribute of a
dynamic property applies to the class of the instance that contains the dynamic property. The
dynamic property Access attribute does not necessarily apply to the class whose method adds the
dynamic property.
For example, if a base class method adds a dynamic property with private access to an instance, the
private access applies only to the class of the instance.
For more information on dynamic property attributes, see meta.DynamicProperty. Use the handle
findprop method to get the meta.DynamicProperty object.
See Also
Related Examples
• “Set and Get Methods for Dynamic Properties” on page 8-57
• “Dynamic Property Events” on page 8-59
• “Dynamic Properties and ConstructOnLoad” on page 8-63
8-56
Set and Get Methods for Dynamic Properties
You can define property set access or get access methods for dynamic properties without creating
additional class methods. For general information on the use of access methods, see “Property Access
Methods” on page 8-39.
• Define a function that implements the operations you want to perform before the property set or
get occurs. These methods must have the following signatures: mySet(obj,val) or val =
myGet(obj)
• Obtain the dynamic property's corresponding meta.DynamicProperty object.
• Assign a function handle referencing your set or get property function to the
meta.DynamicProperty object's GetMethod or SetMethod property. This function does not
need to be a method of the class. You cannot use a naming scheme like set.PropertyName.
Instead, use any other valid function name.
Suppose that you want to create a property set function for the myCoord dynamic property of the
button class created in “Define Dynamic Properties” on page 8-54.
function set_myCoord(obj,val)
if ~(length(val) == 2)
error('myCoords require two values')
end
obj.myCoord = val;
end
Because button is a handle class, the property set function does not need to return the object as an
output argument.
To get the meta.DynamicProperty object, use the handle class findprop method:
mb1 = b1.findprop('myCoord');
mb1.SetMethod = @set_myCoord;
MATLAB calls the property set function whenever you set this property:
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 then attempt to access the property value from
that function.
8-57
8 Properties — Storing Class Data
Reference or assignment to a property from within its set or get method does not invoke the set or
get method again. Therefore, if you use a handle to the same function for multiple dynamic
properties, that function is not invoked when accessing any of those properties from within that
function.
See Also
Related Examples
• “Dynamic Properties — Adding Properties to an Instance” on page 8-54
8-58
Dynamic Property Events
In this section...
“Dynamic Properties and Ordinary Property Events” on page 8-59
“Dynamic-Property Events” on page 8-59
“Listen for a Specific Property Name” on page 8-60
“PropertyAdded Event Callback Execution” on page 8-61
“PropertyRemoved Event Callback Execution” on page 8-61
“How to Find meta.DynamicProperty Objects” on page 8-61
If you delete a dynamic property, and then create another dynamic property with the same name, the
listeners do not respond to events generated by the new property. A listener defined for a dynamic
property that has been deleted does not cause an error, but the listener callback is never executed.
“Property-Set and Query Events” on page 11-14 provides more information on how to define
listeners for these events.
Dynamic-Property Events
To respond to the addition and removal of dynamic properties, attach listeners to objects containing
the dynamic properties. The dynamicprops class defines events for this purpose:
• PropertyAdded — Triggered when you add a dynamic property to an object derived from the
dynamicprops class.
• PropertyRemoved — Triggered when you delete the object or the meta.DynamicProperty
object associated with a dynamic property.
• ObjectBeingDestroyed — Triggered when the object is destroyed. This event is inherited from
the handle class.
These events have public listen access (ListenAccess attribute) and private notify access
(NotifyAccess attribute).
8-59
8 Properties — Storing Class Data
• Set the value of a hidden property to true when a property named SpecialProp is added.
• Set the value of the hidden property to false when SpecialProp is removed.
Use the event.DynamicPropertyEvent event data to determine the name of the property and
whether it is added or deleted.
The DynamTest class derives from dynamicprops. It defines a hidden property, HiddenProp.
Define a callback function that uses the EventName property of the event data to determine if a
property is added or removed. Obtain the name of the property from the PropertyName property of
the event data. If a dynamic property is named SpecialProp, change the value of the hidden
property.
function DyPropEvtCb(src,evt)
switch evt.EventName
case 'PropertyAdded'
switch evt.PropertyName
case 'SpecialProp'
% Take action based on the addition of this property
%...
%...
src.HiddenProp = true;
disp('SpecialProp added')
otherwise
% Other property added
% ...
disp([evt.PropertyName,' added'])
end
case 'PropertyRemoved'
switch evt.PropertyName
case 'SpecialProp'
% Take action based on the removal of this property
%...
%...
src.HiddenProp = false;
disp('SpecialProp removed')
otherwise
% Other property removed
% ...
disp([evt.PropertyName,' removed'])
end
end
end
8-60
Dynamic Property Events
dt = DynamTest;
lad = addlistener(dt,'PropertyAdded',@DyPropEvtCb);
lrm = addlistener(dt,'PropertyRemoved',@DyPropEvtCb);
ad = addprop(dt,'SpecialProp');
The addition of the dynamic property causes the listener to execute its callback function,
DyPropEvtCb. The callback function assigns a value of true to the HiddenProp property.
dt.HiddenProp
ans =
Delete the meta.DynamicProperty object returned when adding the dynamic property
SpecialProp.
delete(ad)
SpecialProp removed
dt.HiddenProp
ans =
ad = findprop(dt,'SpecialProp');
8-61
8 Properties — Storing Class Data
See Also
Related Examples
• “Dynamic Properties — Adding Properties to an Instance” on page 8-54
8-62
Dynamic Properties and ConstructOnLoad
If you create dynamic properties from the class constructor, you can cause a conflict if you also set
the class ConstructOnLoad attribute to true. Here is the sequence:
• 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 “Save and Load
Objects” on page 13-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.
If you use ConstructOnLoad, add dynamic properties from the class constructor, and want the
constructor to call addprop at load time, then set the dynamic property Transient attribute to
true. This setting prevents the property from being saved. For example:
See Also
Related Examples
• “Dynamic Properties — Adding Properties to an Instance” on page 8-54
8-63
9
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 design 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.
Methods have access to private members of their class including other methods and properties. This
encapsulation enables you to hide data and create special interfaces that must be used to access the
data stored in objects.
For sample code and syntax, see “Methods and Functions” on page 5-13
For a discussion of how to create classes that modify standard MATLAB behavior, see “Methods That
Modify Default Behavior” on page 18-2 .
For information on the use of @ and path directors and packages to organize your class files, see
“Class Files and Folders” on page 5-2
For the syntax to use when defining classes in more than one file, see “Methods in Separate Files” on
page 9-8
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
computational functions. These methods require an object of the class on which to operate. See
“Ordinary Methods” on page 9-6.
• Constructor methods are specialized methods that create objects of the class. A constructor
method must have the same name as the class and typically initializes property values with data
obtained from input arguments. The class constructor method must declare at least one output
argument, which is the object being constructed. The first output is always the object being
constructed. See “Class Constructor Methods” on page 9-16
9-2
Methods in Class Design
• Destructor methods are called automatically when the object is destroyed, for example if you call
delete(object) or there are no longer any references to the object. See “Handle Class
Destructor” on page 7-13
• Property access methods enable a class to define code to execute whenever a property value is
queried or set. See “Property Access Methods” on page 8-39
• Static methods are functions that are associated with a class, but do not necessarily operate on
class objects. These methods do not require an instance of the class to be referenced during
invocation of the method, but typically perform operations in a way specific to the class. See
“Static Methods” on page 9-24
• Conversion methods are overloaded constructor methods from other classes that enable your class
to convert its own objects to the class of the overloaded constructor. For example, if your class
implements a double method, then this method is called instead of the double class constructor
to convert your class object to a MATLAB double object. See “Object Converters” on page 18-10
for more information.
• Abstract methods define a class that cannot be instantiated itself, but serves as a way to define a
common interface used by numerous subclasses. Classes that contain abstract methods are often
referred to as interfaces. See “Abstract Classes and Class Members” on page 12-72 for more
information and examples.
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:
• Property set/get access method (see “Property Access Methods” on page 8-39)
• Conversion method that converts to a package-qualified class, which requires the use of the
package name (see “Packages Create Namespaces” on page 6-20)
You cannot define property access or conversion methods as local functions, nested functions, or
separately in their own files. Class constructors and package-scoped functions must use the
unqualified name in the function definition; do not include the package name in the function
definition statement.
See Also
Related Examples
• “Method Attributes” on page 9-4
• “Rules for Naming to Avoid Conflicts” on page 9-28
9-3
9 Methods — Defining Class Operations
Method Attributes
In this section...
“Purpose of Method Attributes” on page 9-4
“Specifying Method Attributes” on page 9-4
“Table of Method Attributes” on page 9-4
For more information on attribute syntax, see “Attribute Specification” on page 5-18.
Attribute values apply to all methods defined within the methods...end code block that specifies
the nondefault values.
9-4
Method Attributes
Method Attributes
See Also
meta.method | metaclass
More About
• “Methods”
9-5
9 Methods — Defining Class Operations
Ordinary Methods
In this section...
“Ordinary Methods Operate on Objects” on page 9-6
“Methods Inside classdef Block” on page 9-6
“Method Files” on page 9-7
Method attributes apply only to that particular methods block, which is terminated by the end
statement.
Note Nonstatic methods must include an explicit object variable as a function argument. The
MATLAB language does not support an implicit reference in the method function definition.
Example of a Method
The addData method adds a value to the Data property of MyData objects. The mustBeNumeric
function restricts the value of the Data property to numeric values. The property has a default value
of 0.
The addData method returns the modified object, which you can reassign to the same variable.
classdef MyData
properties
Data {mustBeNumeric} = 0
end
methods
function obj = addData(obj,val)
if isnumeric(val)
9-6
Ordinary Methods
a = MyData;
a = addData(a,75)
a =
Data: 75
Calling Methods
Either of the following statements is correct syntax for calling a method, where obj is an object of
the class defining the methodName method:
obj.methodName(arg)
methodName(obj,arg)
Method Files
You can define methods:
For more information on class folders, see “Folders Containing Class Definitions” on page 6-13.
See Also
More About
• “Methods in Separate Files” on page 9-8
• “Determining Which Method Is Invoked” on page 9-11
• “Operator Overloading” on page 18-38
9-7
9 Methods — Defining Class Operations
Class Folders
You can define class methods in files that are separate from the class definition file, with certain
exceptions (see “Methods You Must Define in the classdef File” on page 9-10).
To use multiple files for class definitions, put the class files in a folder having a name beginning with
the @ character followed by the name of the class (this is called a class folder). Ensure that the parent
folder of the class folder is on the MATLAB path.
If the class folder is contained in one or more package folders, then the top-level package folder must
be on the MATLAB path.
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. The folder
@MyClass can contain a number of files:
@MyClass/MyClass.m
@MyClass/subsref.m
@MyClass/subsasgn.m
@MyClass/horzcat.m
@MyClass/vertcat.m
@MyClass/myFunc.m
MATLAB treats any function file in the class folder as a method of the class. Function files can be
MATLAB code (.m), Live Code file format (.mlx), MEX functions (platform dependent extensions),
and P-code files (.p). The base name of the file must be a valid MATLAB function name. Valid function
names begin with an alphabetic character, and can contain letters, numbers, or underscores.
It is a good practice to declare the function signature in the classdef file in a methods block:
classdef MyClass
methods
9-8
Methods in Separate Files
output = myFunc(obj,arg1,arg2)
end
...
end
For example, the following code shows a method with Access set to private in the methods block.
The method implementation resides in a separate file. Do not include the function or end keywords
in the methods block. Include only the function signature showing input and output arguments.
classdef MyClass
methods (Access = private)
output = myFunc(obj,arg1,arg2)
end
end
To create a static method, set the method Static attribute to true and list the function signature in
a static methods block in the classdef file. Include the input and output arguments with the
function name. For example:
classdef MyClass
...
methods (Static)
output = staticFunc1(arg1,arg2)
staticFunc2
end
...
end
Define the functions in separate files using the same function signature. For example, in the file
@MyClass/staticFunc1.m:
and in @Myclass/staticFunc2.m:
function staticFunc2
...
end
9-9
9 Methods — Defining Class Operations
• Class constructor
• All functions that use dots in their names, including:
• Converter methods that must use the package name as part of the class name because the
class is contained in packages
• Property set and get access methods
Related Information
See Also
Related Examples
• “Folders Containing Class Definitions” on page 6-13
• “Live Code File Format (.mlx)”
• “MEX File Functions”
• “Protect Your Source Code”
9-10
Method Invocation
Method Invocation
In this section...
“Determining Which Method Is Invoked” on page 9-11
“Referencing Names with Expressions—Dynamic Reference” on page 9-13
“Index into Result of Method Call” on page 9-14
“Controlling Access to Methods” on page 9-14
“Invoking Superclass Methods in Subclass Methods” on page 9-15
“Invoking Built-In Functions” on page 9-15
• The class of the leftmost 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 called method, then a function with that name that is 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
MATLAB uses dominant argument dispatching to determine which version of a method to call. During
method dispatching, MATLAB determines the dominant class from among the arguments in the call.
In general, all MATLAB classes defined using the classdef syntax have equal precedence for
purposes of method dispatching.
Classes defined using the classdef syntax take precedence over these MATLAB classes:
double, single, int64, uint64, int32, uint32, int16, uint16, int8, uint8, char, string,
logical, cell, struct, and function_handle.
In general, when two or more objects are part of the argument list, the method defined for the class
of the left-most object is invoked. However, user-defined classes can specify the relative dominance of
specific classes. For information, see “Class Precedence” on page 6-18.
For example, suppose classA defines classB as inferior and suppose that both classes define a
method called combine.
combine(B,A)
actually calls the combine method of classA because A is the dominant argument.
9-11
9 Methods — Defining Class Operations
MATLAB classes support both function and dot notation syntax for calling methods. For example, if
setColor is a method of the class of object X, then calling setColor with function notation would
be:
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:
• If there is an overloaded subsref, it is invoked whenever using dot notation. That is, the
statement is first tested to see if it is subscripted assignment.
• If there is no overloaded subsref, then setColor must be a method of X. An ordinary function or
a class constructor is never called using this notation.
• Only the argument X (to the left of the dot) is used for dispatching. No other arguments, even if
dominant, are considered. Therefore dot notation can call only methods of X; methods of other
argument are never called.
Here is an example of a case where dot and function notation can give different results. Suppose that
you have the following classes:
• classA defines a method called methodA that requires an object of classB as one of its
arguments
• classB defines classA as inferior to classB
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 MATLAB 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:
9-12
Method Invocation
obj = classA(...);
obj.methodA(obj_classB)
The expression must evaluate to a char vector that is the name of a property or a method. For
example, the following statements are equivalent:
obj.Property1
obj.('Property1')
In this case, obj is an object of a class that defines a property called Property1. Therefore, you can
pass a char variable in the parentheses to reference to property:
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.
As an example, suppose that an object has methods corresponding to each day of the week. These
methods have the same names as the days of the week (Monday, Tuesday, and so on). Also, the
methods take as char vector input arguments, the current day of the month (the date). Now suppose
that you write a function in which you want to call the correct method for the current day.
The expression datestr(date,'dddd') returns the current day as a char vector. For example:
datestr(date,'dddd')
ans =
Tuesday
The expression datestr(date,'dd') returns the current date as a char vector. For example:
datestr(date,'dd')
ans =
11
Therefore, the expression using dot-parentheses (called on Tuesday the 11th) is the equivalent of:
obj.Tuesday('11')
9-13
9 Methods — Defining Class Operations
classdef polyEval
properties
Result
end
methods
function obj = polyEval(x)
if nargin
obj.Result = 2*x.^3 + 7*x.^2 + 2*x + 7;
end
end
end
end
You can index into the result of a call the constructor method to access the value of the property. For
example, this call to polyEval() returns the value that is assigned to the property. The instance of
the polyEval class is created as a temporary variable and is not saved in the workspace.
polyEval(-3.5).Result
ans =
In this case, the expression, polyEval(-3.5).Result represents the value 0 (the value -3.5 is a
root of the polynomial). You can assign the result of evaluating this expression to a variable or use it
in other expressions.
You can dot index into the result of any method that returns a result for which dot indexing is defined,
such as an object or structure which can be indexed using a property or field name. You must include
the parentheses in all indexing expressions even if there are no arguments. For example, to index into
the result of a call to the polyEval() constructor with no inputs, use this expression.
polyEval().Result
For more information on indexing into the result of function calls, see “Indexing into Function Call
Results”.
• 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.
9-14
Method Invocation
• Access list — Restricts method access to classes in access list. For more information, see “Class
Members Access” on page 12-23
Local and nested functions inside the method files have the same access as the method. Local
functions inside a class-definition file have private access to the class defined in the same file.
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:
classdef Stock < Asset
methods
function disp(s)
disp@Asset(s) % Call base class disp method first
fprintf(1,'Number of shares: %g\nShare price: %3.2f\n',...
s.NumShares,s.SharePrice);
end % disp
end
end
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
See Also
More About
• “Object Precedence in Method Invocation” on page 9-36
• “Class Precedence” on page 6-18
9-15
9 Methods — Defining Class Operations
All MATLAB classes have a default constructor method. This method returns an object of the class
that is created with no input arguments. A class can define a constructor method that overrides the
default constructor. An explicitly defined constructor can accept input arguments, initialize property
values, call other methods, and perform other operations necessary to create objects of the class.
%% Pre Initialization %%
9-16
Class Constructor Methods
%% Object Initialization %%
% Call superclass constructor before accessing object
% You cannot conditionalize this statement
obj = obj@BaseClass1(args{:});
%% Post Initialization %%
% Any code, including access to object
obj.classMethod(arg);
obj.ComputedValue = compvalue;
...
end
...
end
...
end
Call the constructor like any function, passing arguments and returning an object of the class.
obj = ConstructorDesign(a,b,c);
Default Constructor
If a class does not define a constructor, MATLAB supplies a default constructor that takes no
arguments and returns a scalar object whose properties are initialized to property default values. The
9-17
9 Methods — Defining Class Operations
default constructor supplied by MATLAB also calls all superclass constructors with no arguments or
with any argument passed to the default subclass constructor.
When a subclass does not define a constructor, the default constructor passes its inputs to the direct
superclass constructor. This behavior is useful when there is no need for a subclass to define a
constructor, but the superclass constructor does require input arguments.
• Input arguments
• Initializing object state, such as property values, for each instance of the class
• Calling the superclass constructor with values that are determined by the subclass constructor
Related Information
For information specific to constructing enumerations, see “Enumeration Class Constructor Calling
Sequence” on page 14-6.
For information on creating object arrays in the constructor, see “Construct Object Arrays” on page
10-2.
If the class being created is a subclass, MATLAB calls the constructor of each superclass class to
initialize the object. Implicit calls to the superclass constructor are made with no arguments. If
superclass constructors require arguments, call them from the subclass constructor explicitly. See
“Control Sequence of Constructor Calls” on page 12-11
For example, the following constructor 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.
For example, this constructor operates on the input arguments to assign the value of the Value
property.
9-18
Class Constructor Methods
...
end
When initializing the object, for example, by assigning values to properties, use the name of the
output argument to refer to the object within the constructor. For example, in the following code the
output argument is obj and the object is reference as obj:
% obj is the object being constructed
function obj = MyClass(arg)
obj.propert1 = arg*10;
obj.method1;
...
end
For more information on defining default property values, see “Property Default Values” on page 8-
14.
• When loading objects into the workspace, if the class ConstructOnLoad attribute is set to true,
the load function calls the class constructor with no arguments.
• When creating or expanding an object array such that not all elements are given specific values,
the class constructor is called with no arguments to fill in unspecified elements (for example,
x(10,1) = MyClass(a,b,c);). In this case, the constructor is called once with no arguments
to populate the empty array elements (x(1:9,1)) with copies of this one object.
If there are no input arguments, the constructor creates an object using only default properties
values. A good practice is to add a check for zero arguments to the class constructor to prevent an
error if either of these two cases occur:
function obj = MyClass(a,b,c)
if nargin > 0
obj.A = a;
obj.B = b;
obj.C = c;
...
end
end
For ways to handle superclass constructors, see “Basic Structure of Constructor Methods” on page 9-
16.
Subclass Constructors
Subclass constructors can call superclass constructors explicitly to pass arguments to the superclass
constructor. The subclass constructor must specify these arguments in the call to the superclass
constructor and must use the constructor output argument to form the call. Here is the syntax:
classdef MyClass < SuperClass
methods
function obj = MyClass(a,b,c,d)
9-19
9 Methods — Defining Class Operations
obj@SuperClass(a,b);
...
end
end
end
The subclass constructor must make all calls to superclass constructors before any other references
to the object (obj). This restriction includes assigning property values or calling ordinary class
methods. Also, a subclass constructor can call a superclass constructor only once.
If the classdef does not specify the class as a superclass, the constructor cannot call a superclass
constructor with this syntax. That is, subclass constructor can call only direct superclass constructors
listed in the classdef line.
MATLAB calls any uncalled constructors in the left-to-right order in which they are specified in the
classdef line. MATLAB passes no arguments with these calls.
Calls to superclass constructors must be unconditional. There can be only one call for a given
superclass. Initialize the superclass portion of the object by calling the superclass constructors before
using the object (for example, to assign property values or call class methods).
To call a superclass constructor with different arguments that depend on some condition, build a cell
array of arguments and provide one call to the constructor.
For example, the Cube class constructor calls the superclass Shape constructor using default values
when the Cube constructor is called with no arguments. If the Cube constructor is called with four
input arguments, then pass upvector and viewangle to the superclass constructor:
9-20
Class Constructor Methods
cubeObj.SideLength = length;
cubeObj.Color = color;
end
...
end
...
end
end
To support a syntax that calls the superclass constructor with no arguments, provide this syntax
explicitly.
Suppose in the case of the Cube class example, all property values in the Shape superclass and the
Cube subclass have default values specified in the class definitions. Then you can create an instance
of Cube without specifying any arguments for the superclass or subclass constructors.
Here is how you can implement this behavior in the Cube constructor:
methods
function cubeObj = Cube(length,color,upvector,viewangle)
% Assemble superclass constructor arguments
if nargin == 0
super_args = {};
elseif nargin == 4
super_args{1} = upvector;
super_args{2} = viewangle;
else
error('Wrong number of input arguments')
end
More on Subclasses
See “Design Subclass Constructors” on page 12-7 for information on creating subclasses.
For example, the following class constructor requires one input argument (a datetime object), which
the constructor assigns to the CurrentDate property.
9-21
9 Methods — Defining Class Operations
classdef BaseClassWithConstr
properties
CurrentDate datetime
end
methods
function obj = BaseClassWithConstr(dt)
obj.CurrentDate = dt;
end
end
end
Suppose that you create a subclass of BaseClassWithConstr, but your subclass does not require an
explicit constructor method.
classdef SubclassDefaultConstr < BaseClassWithConstr
...
end
You can construct an object of the SubclassDefaultConstr by calling its default constructor with
the superclass argument:
obj = SubclassDefaultConstr(datetime);
For information on subclass constructors, see “Subclass Constructors” on page 9-19 and “Default
Constructor” on page 9-17.
MATLAB calls the delete method on the object, the delete methods for any objects contained in
properties, and the delete methods for any initialized base classes.
Depending on when the error occurs, MATLAB can call the class destructor before the object is fully
constructed. Therefore class delete methods must be able to operate on partially constructed
objects that might not have values for all properties. For more information, see “Support Destruction
of Partially Constructed Objects” on page 7-15.
For information on how objects are destroyed, see “Handle Class Destructor” on page 7-13.
Use nargout to determine if the constructor has been called with an output argument. For example,
the class constructor for the MyApp class clears the object variable, obj, if called with no output
assigned:
classdef MyApp
methods
9-22
Class Constructor Methods
When a class constructor does not return an object, MATLAB does not trigger the meta.class
InstanceCreated event.
See Also
Related Examples
• “Simplifying the Interface with a Constructor” on page 3-16
• “Subclass Constructor Implementation” on page 12-8
9-23
9 Methods — Defining Class Operations
Static Methods
In this section...
“What Are Static Methods” on page 9-24
“Why Define Static Methods” on page 9-24
“Defining Static Methods” on page 9-24
“Calling Static Methods” on page 9-24
“Inheriting Static Methods” on page 9-25
Suppose that a class needs a value for pi calculated to particular tolerances. The class could define its
own version of the built-in pi function for use within the class. This approach maintains the
encapsulation of the class's internal workings, but does not require an instance of the class to return
a value.
classdef MyClass
methods(Static)
function p = pi(tol)
[n d] = rat(pi,tol);
p = n/d;
end
end
end
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:
9-24
Static Methods
obj = MyClass;
value = obj.pi(.001);
See Also
Related Examples
• “Implementing the AccountManager Class” on page 3-11
9-25
9 Methods — Defining Class Operations
In this section...
“Why Overload Functions” on page 9-26
“Implementing Overloaded MATLAB Functions” on page 9-26
“Rules for Naming to Avoid Conflicts” on page 9-28
You can also modify default behaviors by implementing specific functions that control these
behaviors. For more information on functions that modify default behaviors, see “Methods That
Modify Default Behavior” on page 18-2.
MATLAB uses the dominant argument to determine which version of a function to call. If the
dominant argument is an object, then MATLAB calls the method defined by the object's class, if one
exists.
In cases where a class defines a method with the same name as a global function, the class's
implementation of the function is said to overload the original global implementation.
• Define a method with the same name as the function you want to overload.
• Ensure that the method argument list accepts an object of the class, which MATLAB uses to
determine which version to call.
• Perform the necessary steps in the method to implement the function. For example, access the
object properties to manipulate data.
Generally, the method that overloads a function produces results similar to the MATLAB function.
However, there are no requirements regarding how you implement the overloading method. The
overloading method does not need to match the signature of the overloaded function.
Note MATLAB does not support overloading functions using different signatures for the same
function name.
9-26
Overload Functions in Class Definitions
It is convenient to overload commonly used functions to work with objects of your class. For example,
suppose that a class defines a property that stores data that you often graph. The MyData class
overrides the bar function and adds a title to the graph:
classdef MyData
properties
Data
end
methods
function obj = MyData(d)
if nargin > 0
obj.Data = d;
end
end
function bar(obj)
y = obj.Data;
bar(y,'EdgeColor','r');
title('My Data Graph')
end
end
end
The MyData bar method has the same name as the MATLAB bar function. However, the MyData bar
method requires a MyData object as input. Because the method is specialized for MyData objects, it
can extract the data from the Data property and create a specialized graph.
y = rand(1,10);
md = MyData(y);
bar(md)
md.bar
Classes designed to implement new MATLAB data types typically define certain operators, such as
addition, subtraction, or equality.
For example, standard MATLAB addition (+) 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
9-27
9 Methods — Defining Class Operations
• 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 local function 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.
See Also
Related Examples
• “Dominant Argument in Overloaded Graphics Functions” on page 9-38
• “Class Support for Array-Creation Functions” on page 9-29
9-28
Class Support for Array-Creation Functions
Class support for any of the array-creation functions enables you to develop code that you can share
with built-in and user-defined data types. For example, the class of the variable x in the following
code can be a built-in type during initial development, and then be replaced by a user-defined class
that transparently overloads zeros:
cls = class(x);
zArray = zeros(m,n,cls);
• Class name syntax — Specify class name that determines the type of array elements.
• Prototype object syntax — Provide a prototype object that the function uses to determine the type
and other characteristics of the array elements.
For example:
zArray = zeros(2,3,'uint8');
p = uint8([1 3 5 ; 2 4 6]);
zArray = zeros(2,3,'like',p);
After adding support for these functions to a class named MyClass, you can use similar syntax with
that class:
zArray = zeros(2,3,'MyClass');
p = MyClass(...);
zArray = zeros(size(p),'like',p);
MATLAB uses these arguments to dispatch to the appropriate method in your class.
Array-Creation Functions
ones
9-29
9 Methods — Defining Class Operations
Array-Creation Functions
zeros
eye
nan (lowercase)
inf
true
false
cast
rand
randn
randi
To create an array of objects with specific property values or if the constructor needs other inputs,
use the prototype object to provide this information.
Classes can support both the class name and the prototype object syntax.
You can implement a class name syntax with the true and false functions even though these
functions do not support that syntax by default.
If your class implements a class name syntax, but does not implement a prototype object syntax for a
particular function, you can still call both syntaxes. For example, if you implement a static zeros
method only, you can call:
zeros(...,'like',MyClass(...))
In the case in which you call the prototype object syntax, MATLAB first searches for a method named
zerosLike. If MATLAB cannot find this method, it calls for the zeros static method.
This feature is useful if you only need the class name to create the array. You do not need to
implement both methods to support the complete array-creation function syntax. When you
implement only the class name syntax, a call to a prototype object syntax is the same as the call to the
class name syntax.
9-30
Class Support for Array-Creation Functions
zeros(...,'ClassName')
As a Static method:
methods (Static)
function z = zeros(varargin)
...
end
end
• Implement the prototype object syntax:
zeros(...,'like',obj)
As a Hidden method with the char vector 'Like' appended to the name.
methods (Hidden)
function z = zerosLike(obj,varargin)
...
end
end
The special support for array-creation functions results from the interpretation of the syntax.
zeros(...,'ClassName')
ClassName.zeros(varargin{1:end-1})
• A call to the zeros function of this form:
zeros(...,'like',obj)
zerosLike(obj,varargin{1:end-2})
The input arguments to an array-creation function can include the dimensions of the array the
function returns and possibly other arguments. In general, there are three cases that your methods
must support:
z = zeros('MyClass');
• One or more dimensions equal to or less than zero, resulting in an empty array. For example:
z = zeros(2,0,'MyClass');
• Any number of valid array dimensions specifying the size of the array. For example:
z = zeros(2,3,5,'MyClass');
9-31
9 Methods — Defining Class Operations
When the array-creation function calls your class method, it passes the input arguments, excluding
the class name or the literal 'like' and the object variable to your method. You can implement your
methods with these signatures:
Sample Class
The Color class represents a color in a specific color space, such as, RGB, HSV, and so on. The
discussions in “Class Name Method Implementations” on page 9-32 and “Prototype Object Method
Implementation” on page 9-33 use this class as a basis for the overloaded method implementations.
classdef Color
properties
ColorValues = [0,0,0]
ColorSpace = 'RGB'
end
methods
function obj = Color(cSpace,values)
if nargin > 0
obj.ColorSpace = cSpace;
obj.ColorValues = values;
end
end
end
end
The zeros function strips the final ClassName char vector and uses it to form the call to the static
method in the Color class. The arguments passed to the static method are the array dimension
arguments.
Here is an implementation of a zeros method for the Color class. This implementation:
classdef Color
...
methods (Static)
function z = zeros(varargin)
if (nargin == 0)
% For zeros('Color')
z = Color;
elseif any([varargin{:}] <= 0)
% For zeros with any dimension <= 0
z = Color.empty(varargin{:});
else
% For zeros(m,n,...,'Color')
% Use property default values
9-32
Class Support for Array-Creation Functions
z = repmat(Color,varargin{:});
end
end
end
end
The zeros method uses default values for the ColorValues property because these values are
appropriate for this application. An implementation of a ones method can set the ColorValues
property to [1,1,1], for example.
Suppose that you want to overload the randi function to achieve the following objectives:
• Define each ColorValue property as a 1-by-3 array in the range of 1 to a specified maximum
value (for example, 1–255).
• Accommodate scalar, empty, and multidimensional array sizes.
• Return an array of Color objects of the specified dimensions, each with random ColorValues.
classdef Color
...
methods (Static)
function r = randi(varargin)
if (nargin == 0)
% For randi('ClassName')
r = Color('RGB',randi(255,[1,3]));
elseif any([varargin{2:end}] <= 0)
% For randi with any dimension <= 0
r = Color.empty(varargin{2:end});
else
% For randi(max,m,n,...,'ClassName')
if numel([varargin{:}]) < 2
error('Not enough input arguments')
end
dims = [varargin{2:end}];
r = zeros(dims,'Color');
for k = 1:prod(dims)
r(k) = Color('RGB',randi(varargin{1},[1,3]));
end
end
end
end
end
The objective of a method that returns an array of objects that are “like a prototype object” depends
on the requirements of the class. For the Color class, the zeroLike method creates objects that
have the ColorSpace property value of the prototype object, but the ColorValues are all zero.
Here is an implementation of a zerosLike method for the Color class. This implementation:
9-33
9 Methods — Defining Class Operations
classdef Color
...
methods (Hidden)
function z = zerosLike(obj,varargin)
if nargin == 1
% For zeros('like',obj)
cSpace = obj.ColorSpace;
z = Color;
z.ColorSpace = cSpace;
elseif any([varargin{:}] <= 0)
% For zeros with any dimension <= 0
z = Color.empty(varargin{:});
else
% For zeros(m,n,...,'like',obj)
if ~isscalar(obj)
error('Prototype object must be scalar')
end
obj = Color(obj.ColorSpace,zeros(1,3,'like',obj.ColorValues));
z = repmat(obj,varargin{:});
end
end
end
end
Note In actual practice, the Color class requires error checking, color space conversions, and so on.
This overly simplified version illustrates the implementation of the overloaded methods.
classdef Color
properties
ColorValues = [0,0,0]
ColorSpace = 'RGB'
end
methods
function obj = Color(cSpace,values)
if nargin > 0
obj.ColorSpace = cSpace;
obj.ColorValues = values;
end
end
end
methods (Static)
function z = zeros(varargin)
if (nargin == 0)
% For zeros('ClassName')
z = Color;
elseif any([varargin{:}] <= 0)
% For zeros with any dimension <= 0
z = Color.empty(varargin{:});
else
% For zeros(m,n,...,'ClassName')
% Use property default values
z = repmat(Color,varargin{:});
end
end
function r = randi(varargin)
if (nargin == 0)
% For randi('ClassName')
r = Color('RGB',randi(255,[1,3]));
elseif any([varargin{2:end}] <= 0)
% For randi with any dimension <= 0
r = Color.empty(varargin{2:end});
else
% For randi(max,m,n,...,'ClassName')
if numel([varargin{:}]) < 2
9-34
Class Support for Array-Creation Functions
See Also
Related Examples
• “Construct Object Arrays” on page 10-2
9-35
9 Methods — Defining Class Operations
Object Precedence
Establishing an object precedence enables MATLAB to determine which of possibly many versions of
an operator or function to call in a given situation.
objectA + objectB
Ordinarily, objects have equal precedence and the method associated with the leftmost object is
called. However, there are two exceptions:
• Classes defined with the classdef syntax have precedence over these MATLAB classes:
double, single, int64, uint64, int32, uint32, int16, uint16, int8, uint8, char, string,
logical, cell, struct, and function_handle.
• Classes defined with the classdef syntax can specify their relative precedence with respect to
other classes using the InferiorClasses attribute.
Consider the example in “Representing Polynomials with Classes” on page 20-2. The DocPolynom
class defines a plus method that enables the addition of DocPolynom objects. Given the object p:
p = DocPolynom([1 0 -2 -5])
p =
x^3-2*x-5
the expression:
1 + p
ans =
x^3-2*x-4
calls the DocPolynom plus method (which converts the double, 1, to a DocPolynom object and
then implements the addition of two polynomials). The DocPolynom class has precedence over the
built-in double class.
Defining Precedence
You can specify the relative precedence of classes defined with the classdef syntax by listing
inferior classes in a class attribute. The InferiorClasses property places a class below other
classes in the precedence hierarchy. Define the InferiorClasses property in the classdef
statement:
classdef (InferiorClasses = {?class1,?class2}) myClass
This attribute establishes a relative priority of the class being defined with the order of the classes
listed.
9-36
Object Precedence in Method Invocation
objectA + objectB
calls @classA/plus.m. Conversely, if objectB is above objectA in the precedence hierarchy, then
MATLAB calls @classB/plus.m.
See Also
More About
• “Dominant Argument in Overloaded Graphics Functions” on page 9-38
• “Class Precedence” on page 6-18
9-37
9 Methods — Defining Class Operations
Dominant Argument
When evaluating expression involving objects of more than one class, MATLAB uses the dominant
argument to determine which method or function to call.
The following definition of the TemperatureData class implements a specialized version of plot to
graph temperature data. The class plot method supports a variable number of input arguments to
allow an axes handle as the first argument:
plot(obj)
plot(ax,obj)
MATLAB calls the plot method in both cases because the TemperatureData class specifies the
matlab.graphics.axis.Axes as inferior.
classdef (InferiorClasses = {?matlab.graphics.axis.Axes}) TemperatureData
properties
Time
Temperature
9-38
Dominant Argument in Overloaded Graphics Functions
end
methods
function obj = TemperatureData(x,y)
obj.Time = x;
obj.Temperature = y;
end
function plot(varargin)
if nargin == 1
obj = varargin{1};
plot(obj.Time,obj.Temperature)
elseif nargin == 2
ax = varargin{1};
obj = varargin{2};
plot(ax,obj.Time,obj.Temperature)
elseif nargin > 2
ax = varargin{1};
obj = varargin{2};
plot(ax,obj.Time,obj.Temperature,varargin{3:end})
end
datetick('x')
xlabel('Time')
ylabel('Temperature')
end
end
end
The following call to plot dispatches to the TemperatureData plot method, not the built-in plot
function, because the TemperatureData object is dominant over the axes object.
x = 1:10;
y = rand(1,10)*100;
ax = axes;
td = TemperatureData(x,y);
plot(ax,td)
Suppose the TemperatureData class that is described in the previous section defines a set method.
If you attempt to assign an object of the TemperatureData class to the UserData property of an
axes object:
td = TemperatureData(x,y);
set(gca,'UserData',td)
The results is a call to the TemperatureData set method. MATLAB does not call the built-in set
function.
To support the use of a set function with inferior classes, implement a set method in your class that
calls the built-in set function when the first argument is an object of the inferior class.
function set(varargin)
if isa(varargin{1},'matlab.graphics.axis.Axes')
builtin('set',varargin{:})
else
...
end
9-39
9 Methods — Defining Class Operations
See Also
More About
• “Object Precedence in Method Invocation” on page 9-36
9-40
Class Methods for Graphics Callbacks
uicontrol('Style','slider','Callback',@obj.sliderCallback)
Where your class defines a method called sliderCallback and obj is an instance of your class.
To use a static method as a callback, specify the callback property as a function handle that includes
the class name that is required to refer to a static method:
uicontrol('Style','slider','Callback',@MyClass.sliderCallback)
@obj.methodName
function methodName(obj,src,eventData)
...
end
For static methods, the required class name ensures MATLAB dispatches to the method of the
specified class:
@MyClass.methodName
Define the static callback method with two input arguments — the event source handle and the event
data
function methodName(src,eventData)
9-41
9 Methods — Defining Class Operations
If you want to pass arguments to your callback in addition to the source and event data arguments
passed by MATLAB, you can use an anonymous function. The basic syntax for an anonymous function
that you assign to the graphic object's Callback property includes the object as the first argument:
@(src,event)callbackMethod(object,src,eventData,arg1,...argn)
function methodName(obj,src,eventData,varargin)
...
end
The SeaLevelSlider class creates a slider that varies the color limits of an indexed image to give
the illusion of varying the sea level.
Class Definition
• The class properties store figure and axes handles and the calculated color limits.
• The class constructor creates the graphics objects and assigns the slider callback.
• The callback function for the slider accepts the three required arguments — a class instance, the
handle of the event source, and the event data. The event data argument is empty and not used.
• The uicontrol callback uses dot notation to reference the callback
method: ...'Callback',@obj.sliderCallback.
methods
function obj = SeaLevelSlider(x,map)
obj.Figure = figure('Colormap',map,...
'Position',[100,100,560,580],...
'Resize','off');
obj.Axes = axes('DataAspectRatio',[1,1,1],...
'XLimMode','manual','YLimMode','manual',...
'Parent',obj.Figure);
image(x,'CDataMapping','scaled',...
'Parent',obj.Axes);
obj.CLimit = get(obj.Axes,'CLim');
uicontrol('Style','slider',...
'Parent',obj.Figure,...
'Max',obj.CLimit(2)-10,...
'Min',obj.CLimit(1)-1,...
'Value',obj.CLimit(1),...
9-42
Class Methods for Graphics Callbacks
'Units','normalized',...
'Position',[0.9286,0.1724,0.0357,0.6897],...
'SliderStep',[0.003,0.005],...
'Callback',@obj.sliderCallback);
end
function sliderCallback(obj,src,~)
minVal = get(src,'Value');
maxVal = obj.CLimit(2);
obj.Axes.CLim = [minVal maxVal];
end
end
end
The class uses the cape image that is included with the MATLAB product. To obtain the image data,
use the load command:
After loading the data, create a SeaLevelSlider object for the image:
slaObj = SeaLevelSlider(X,map);
Move the slider to change the color mapping and visualize a rise in sea level.
9-43
9 Methods — Defining Class Operations
See Also
More About
• “Listener Callback Syntax” on page 11-24
9-44
10
Object Arrays
For example, the ObjectArray class creates an object array that is the same size as the input array.
Then it initializes the Value property of each object to the corresponding input array value.
classdef ObjectArray
properties
Value
end
methods
function obj = ObjectArray(F)
if nargin ~= 0
m = size(F,1);
n = size(F,2);
obj(m,n) = obj;
for i = 1:m
for j = 1:n
obj(i,j).Value = F(i,j);
end
end
end
end
end
end
To preallocate the object array, assign the last element of the array first. MATLAB fills the first to
penultimate array elements with the ObjectArray object.
After preallocating the array, assign each object Value property to the corresponding value in the
input array F. To use the class:
10-2
Construct Object Arrays
objArray(ix).PropName
• Reference all values of the same property in an object array using dot notation. MATLAB returns a
comma-separated list of property values.
objArray.PropName
• To assign the comma-separated list to a variable, enclose the right-side expression in brackets:
values = [objArray.PropName]
classdef ObjProp
properties
RegProp
end
methods
function obj = ObjProp
obj.RegProp = randi(100);
end
end
end
for k = 1:5
objArray(k) = ObjProp;
end
Access the RegProp property of the second element of the object array using array indexing:
objArray(2).RegProp
ans =
91
propValues = [objArray.RegProp]
propValues =
82 91 13 92 64
Use standard indexing operations to access the values of the numeric array. For more information on
numeric arrays, see “Matrices and Arrays”.
See Also
Related Examples
• “Initialize Object Arrays” on page 10-5
• “Initialize Arrays of Handle Objects” on page 10-9
10-3
10 Object Arrays
10-4
Initialize Object Arrays
Calls to Constructor
During the creation of object arrays, MATLAB can call the class constructor with no arguments, even
if the constructor does not build an object array. For example, suppose that you define the following
class:
classdef SimpleValue
properties
Value
end
methods
function obj = SimpleValue(v)
obj.Value = v;
end
end
end
a(1,7) = SimpleValue(7)
This error occurs because MATLAB calls the constructor with no arguments to initialize elements 1
through 6 in the array.
Your class must support the no input argument constructor syntax. A simple solution is to test
nargin and let the case when nargin == 0 execute no code, but not error:
classdef SimpleValue
properties
Value
end
methods
function obj = SimpleValue(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) = SimpleValue(7)
a =
10-5
10 Object Arrays
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 =
SimpleValue with properties:
Value: 7
MATLAB created the objects contained in elements a(1,1:6) with no input argument. The default
value for properties empty []. For example:
a(1,1)
ans =
SimpleValue with properties:
Value: []
MATLAB calls the SimpleValue constructor once and copies the returned object to each element of
the array.
See Also
Related Examples
• “Initialize Arrays of Handle Objects” on page 10-9
10-6
Empty Arrays
Empty Arrays
In this section...
“Creating Empty Arrays” on page 10-7
“Assigning Values to an Empty Array” on page 10-7
classdef SimpleValue
properties
Value
end
methods
function obj = SimpleValue(v)
if nargin > 0
obj.Value = v;
end
end
end
end
ary = SimpleValue.empty(5,0)
ary =
Value
For example, using the SimpleValue defined in the “Initialize Object Arrays” on page 10-5 section,
create an empty array:
ary = SimpleValue.empty(5,0);
class(ary)
10-7
10 Object Arrays
ans =
SimpleValue
ary(1)
If you make an assignment to a property value, MATLAB calls the SimpleClass constructor to grow
the array to the require size:
ary(5).Value = 7;
ary(5).Value
ans =
ary(1).Value
ans =
[]
MATLAB populates array elements one through five with SimpleValue objects created by calling the
class constructor with no arguments. Then MATLAB assigns the property value 7 to the object at
ary(5).
See Also
Related Examples
• “Initialize Arrays of Handle Objects” on page 10-9
10-8
Initialize Arrays of Handle Objects
The property RandNumb contains a random number that the InitHandleArray constructor assigns.
Consider what happens when MATLAB initialize an array created by assigning to the last element in
the array. (The last element is the one with the highest index values). Suppose the value of the
RandNumb property of the InitHandleArray object assigned to the element A(4,5) is 59:
A(4,5) = InitHandleArray;
A(4,5).RandNumb
ans =
59
The element in the index location A(4,5) is an instance of the InitHandleArray class. The default
object used for element A(1,1) is also an instance of the InitHandleArray class, but its RandNumb
property is set to a different random number.
To fill in the preceding array elements, MATLAB calls the class constructor to create a single object.
MATLAB copies this object to all the remaining array elements. Calling the constructor to create the
default object resulted in another call to the randi function, which returns a new random number:
A(1,1).RandNumb
ans =
10
ans =
10
10-9
10 Object Arrays
A(2,3).RandNumb
ans =
10
When initializing an object array, MATLAB assigns a copy of a single object to the empty elements in
the array. MATLAB gives each object a unique handle so that later you can assign different property
values to each object. The objects are not equivalent:
A(1,1) == A(2,2)
ans =
That is, the handle A(1,1) does not refer to the same object as A(2,2). The creation of an array
with a statement such as:
A(4,5) = InitHandleArray;
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 that MATLAB copies to all remaining empty array elements.
Related Information
For information on array manipulation, see “Multidimensional Arrays”
See “Initializing Properties to Handle Objects” on page 8-14 for information on assigning values to
properties.
See “Object Array Indexing” on page 18-12 for information on implementing subsasgn methods for
your class.
10-10
Accessing Dynamic Properties in Arrays
You can add dynamic properties to objects of the ObjectArrayDynamic class. Create an object
array and add dynamic properties to each member of the array. Define elements 1 and 2 as
ObjectArrayDynamic objects:
a(1) = ObjectArrayDynamic;
a(2) = ObjectArrayDynamic;
a(1).addprop('DynoProp');
a(1).DynoProp = 1;
a(2).addprop('DynoProp');
a(2).DynoProp = 2;
a.RegProp
ans =
ans =
85
However, MATLAB returns an error if you try to access the dynamic properties of all array elements
using this syntax.
a.DynoProp
a(1).DynoProp
ans =
10-11
10 Object Arrays
a(2).DynoProp
ans =
For information about classes that can define dynamic properties, see “Dynamic Properties — Adding
Properties to an Instance” on page 8-54 .
10-12
Implicit Class Conversion
In this section...
“Class Conversion Mechanism” on page 10-13
“Concatenation” on page 10-13
“Subscripted Assignment” on page 10-13
To perform the conversion, MATLAB attempts to call a converter method defined by the class to be
converted. A converter method has the same name as the destination class. For example, if a class
defines a method named double, this method converts an object of the class to an object of class
double.
If no converter exists in the source object's class, then this call resolves to a call to the constructor of
the destination class.
Both concatenation and subscripted assignment can cause MATLAB to apply this class conversion
mechanism. The conversion can be successful or can result in an error if the conversion is not
possible.
Concatenation
In concatenation operations, the dominant object determines the class of the resulting array. MATLAB
determines the dominant object as follows:
For example, in the statement C = [A,B], if A is the dominant object, MATLAB attempts to convert B
to the class of A.
Subscripted Assignment
In subscripted assignment, the left side of the assignment statement defines the class of the array. If
you assign array elements when the right side is a different class than the left side, MATLAB attempts
to convert to the class of the left side.
A = ClassA;
B = ClassB;
A(2) = B;
10-13
10 Object Arrays
MATLAB first looks for a converter method defined by the class of the source object B. This converter
method must have the name ClassA in this case. The subscripted assignment is effectively a call to
the converter defined by ClassB:
If no converter method exists, this call resolves to a call to the destination class constructor:
See Also
Related Examples
• “Valid Combinations of Unlike Classes”
• “Concatenating Objects of Different Classes” on page 10-15
• “Object Converters” on page 18-10
• “Function Argument Validation”
10-14
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.
It is possible for the dominant class to define horzcat, vertcat, or cat methods that modify the
default concatenation process.
Note MATLAB does not convert objects to a common superclass unless those objects are part of a
heterogeneous hierarchy. For more information, see “Designing Heterogeneous Class Hierarchies” on
page 10-20.
Concatenating Objects
Concatenation combines objects into arrays:
ary = [obj1,obj2,obj3,...,objn];
10-15
10 Object Arrays
The class of the arrays is the same as the class of the objects being concatenated. Concatenating
objects of different classes is possible if MATLAB can convert objects to the dominant class. MATLAB
attempts to convert unlike objects by:
If conversion of the inferior object is successful, MATLAB returns an array that is of the dominant
class. If conversion is not possible, MATLAB returns an error.
If the constructor simply assigns this argument to a property, the result is an object of the dominant
class with an object of an inferior class stored in a property. If this assignment is not a desired result,
then ensure that class constructors include adequate error checking.
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.
classdef RGBColor < ColorClass
methods
function obj = RGBColor(rgb)
if nargin > 0
obj.Color = rgb;
end
end
end
end
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.
classdef HSVColor < ColorClass
methods
function obj = HSVColor(hsv)
if nargin > 0
obj.Color = hsv;
end
end
end
end
10-16
Concatenating Objects of Different Classes
Create an instance of each class and concatenate them into an array. The RGBColor object is
dominant because it is the leftmost object and neither class defines a dominance relationship:
crgb = RGBColor([1 0 0]);
chsv = HSVColor([0 1 1]);
ary = [crgb,chsv];
class(ary)
ans =
RGBColor
You can combine these objects into an array because MATLAB 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 =
Color: [0 1 1]
Converter Methods
If your class design requires object conversion, implement converter methods for this purpose.
The ColorClass class defines converter methods for RGBColor and HSVColor objects:
classdef ColorClass
properties
Color
end
methods
function rgbObj = RGBColor(obj)
if isa(obj,'HSVColor')
rgbObj = RGBColor(hsv2rgb(obj.Color));
end
end
function hsvObj = HSVColor(obj)
if isa(obj,'RGBColor')
hsvObj = HSVColor(rgb2hsv(obj.Color));
end
end
end
end
Create an array of RGBColor and HSVColor objects with the revised superclass:
crgb = RGBColor([1 0 0]);
chsv = HSVColor([0 1 1]);
10-17
10 Object Arrays
ary = [crgb,chsv];
class(ary)
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)
ans =
Color: [1 0 0]
ary(2).Color
ans =
1 0 0
If the leftmost object is of class HSVColor, the array ary is also of class HSVColor, and MATLAB
converts the Color property data to HSV color specification.
ary =
1x2 HSVColor
Properties:
Color
ary(2).Color
ans =
0 1 1
Defining a converter method in the superclass and adding better argument checking in the subclass
constructors produces more predicable results. Here is the RGBColor class constructor with
argument checking:
10-18
Concatenating Objects of Different Classes
obj.Color = rgb;
end
end
end
Your applications can require additional error checking and other coding techniques. The classes in
these examples are designed only to demonstrate concepts.
See Also
More About
• “Implicit Class Conversion” on page 10-13
• “Object Converters” on page 18-10
• “Hierarchies of Classes — Concepts” on page 12-2
10-19
10 Object Arrays
For an example that uses heterogeneous arrays, see “A Class Hierarchy for Heterogeneous Arrays” on
page 21-2.
MATLAB Arrays
MATLAB determines the class of an array by the class of the objects contained in the array. MATLAB
is unlike some languages in which you define an array of object pointers or references. In these other
languages, the type of the array is different from the type of an object in the array. You can access the
elements of the array and dispatch to methods on those elements, but you cannot call an object
method on the whole array, as you can in MATLAB.
Object arrays in MATLAB are homogeneous in class. Because of this homogeneity, you can perform
operations on whole arrays, such as multiplying numeric matrices. You can form heterogeneous
arrays by defining a hierarchy of classes that derive from a common superclass. Cell arrays provide
option for an array type that can hold different kinds of unrelated objects.
Heterogeneous Hierarchies
You can form arrays of objects that are subclasses of a common superclass when these classes are
part of a heterogeneous hierarchy. A MATLAB heterogeneous class hierarchy:
10-20
Designing Heterogeneous Class Hierarchies
For example, in the following diagram, Shape is the root of the heterogeneous hierarchy.
Heterogeneous Arrays
A heterogeneous array is an array of objects that differ in their specific class, but all objects derive
from or are instances of a common superclass. The common superclass forms the root of the
hierarchy of classes that you can combine into heterogeneous arrays.
The common superclass must derive from matlab.mixin.Heterogeneous. Methods that you can
call on the array as a whole must have the same definitions for all subclasses.
• Create arrays of objects that are of different classes, but part of a related hierarchy.
• Call methods of the most specific common superclass on the array as a whole
• Access properties of the most specific common superclass using dot notation with the array
• Use common operators that are supported for object arrays
• Support array indexing (scalar or nonscalar) that returns arrays of the most specific class
10-21
10 Object Arrays
• Array class
• Property access
• Method invocation
The class of a heterogeneous array is that of the most specific superclass shared by the objects of the
array.
If the following conditions are true, the concatenation and subscripted assignment operations return
a heterogeneous array:
• The objects on the right side of the assignment statement are of different classes
• All objects on the right side of the assignment statement derive from a common subclass of
matlab.mixin.Heterogeneous
For example, form an array by concatenating objects of these classes. The class of a1 is ClassA:
a1 = [SpecificA,SpecificB];
class(a1)
10-22
Designing Heterogeneous Class Hierarchies
ans =
ClassA
If the array includes an object of the class SpecificC, the class of a2 is RootSuperclass:
a2 = [SpecificA,SpecificB,SpecificC];
class(a2)
ans =
RootSuperclass
If you assigned an object of the class SpecificC to array a1 using indexing, the class of a1 becomes
RootSuperclass:
a1(3) = SpecificC;
class(a1)
ans =
RootSuperclass
If the array contains objects of only one class, then the array is not heterogeneous. For example, the
class of a is SpecificA.
a = [SpecificA,SpecificA];
class(a)
ans =
SpecificA
Property Access
Access array properties with dot notation when the class of the array defines the properties. The
class of the array is the most specific common superclass, which ensures all objects inherit the same
properties.
Referring to Prop1 using dot notation returns the value of Prop1 for each object in the array.
Method Invocation
To invoke a method on a heterogeneous array, the class of the array must define or inherit the method
as Sealed. For example, suppose RootSuperclass defines a Sealed method called superMethod.
Sealing the method (so that it cannot be overridden in a subclass) ensures that the same method
definition exists for all elements of the array. Calling that method on a single element of the array
invokes the same method implementation as calling the method on the whole array.
10-23
10 Object Arrays
Unsupported Hierarchies
Heterogeneous hierarchies cannot have ambiguities when obtaining default objects, determining the
class of the array, and converting class objects to other types. Members of the hierarchy can derive
from only one root superclass (that is, from only one direct subclass of
matlab.mixin.Heterogeneous).
The next diagram shows two separate heterogeneous hierarchies. ClassA has only one root
superclass (called OtherBaseClass). The heterogeneous hierarchy is no longer ambiguous:
10-24
Designing Heterogeneous Class Hierarchies
Default Object
A default object is the object returned by calling the class constructor with no arguments. MATLAB
uses default objects in these situations:
• Indexed assignment creates an array with gaps in array elements. For example, assign the first
element of array h to index 5:
h(5) = ClassA(arg1,arg2);
Heterogeneous hierarchies enable you to define the default object for that hierarchy. The
matlab.mixin.Heterogeneous class provides a default implementation of a method called
getDefaultScalarElement. This method returns an instance of the root class of the
heterogeneous hierarchy, unless the root superclass is abstract.
If the root superclass is abstract or is not appropriate for a default object, override the
getDefaultScalarElement method. Implement the getDefaultScalarElement override in the
root superclass, which derives directly from matlab.mixin.Heterogeneous.
getDefaultScalarElement must return a scalar object that is derived from the root superclass.
For specific information on how to implement this method, see getDefaultScalarElement.
10-25
10 Object Arrays
To support the formation of heterogeneous arrays using objects that are not part of the
heterogeneous hierarchy, implement a convertObject method in the root superclass. The
convertObject method must convert the nonmember object to a valid member of the
heterogeneous hierarchy.
For example, suppose RootSuperclass is an abstract class that is the root of a heterogeneous
hierarchy. Initialize an array using the empty static method:
ary = RootSuperclass.empty;
See Also
Related Examples
• “A Class Hierarchy for Heterogeneous Arrays” on page 21-2
• “Handle-Compatible Classes and Heterogeneous Arrays” on page 12-39
10-26
Heterogeneous Array Constructors
• The root superclass is not abstract and does not implement a getDefaultScalarElement
method.
• The root superclass implements a getDefaultScalarElement method that returns an object
that is not the same class as the subclass.
When assigning to object arrays, MATLAB uses the default object to fill in unassigned array elements.
In a heterogeneous hierarchy, the default object can be the superclass that is called by the subclass
constructor. Therefore, building an array in the superclass constructor can create a heterogeneous
array.
10-27
10 Object Arrays
In this code, the superclass constructor creates one object for each element in the input argument,
arg:
method
function obj = SuperClass(arg)
...
n = numel(arg);
obj = repelem(obj,1,n);
for k = 1:n
obj(k).SuperProp = arg(k);
end
...
end
end
The subclass constructor calls the superclass constructor to pass the required argument array, a:
method
function obj = SubClass(a)
obj = obj@SuperClass(a);
for k = 1:numel(a)
obj(k).SubProp = a(k);
end
end
end
Sample Implementation
The following class hierarchy defines a subclass that builds object arrays in its constructor. The root
superclass of the hierarchy initializes the superclass part of the objects in the array.
This class hierarchy represents members of an engineering team. The classes in the hierarchy
include:
10-28
Heterogeneous Array Constructors
The TeamMembers class is the root of the heterogeneous hierarchy and is a concrete class. Before
assigning values to the Name and PhoneX properties, the constructor initializes an array of subclass
(ProjectEngineer) objects.
The ProjectEngineer constructor provides the obj argument for the call to repelem with this
statement:
obj = obj@TeamMembers(varargin{1:2});
10-29
10 Object Arrays
The ProjectEngineer class represents one type of team member. This class supports array inputs
and returns an array of objects.
The ProjectEngineer class requires a cell array of names, a numeric array of phone extensions,
and a cell array of billing rates for each engineer in the team.
nm = {'Fred','Nancy','Claudette'};
px = [8112,8113,8114];
rt = {'C2','B1','A2'};
tm = ProjectEngineer(nm,px,rt)
tm =
Rate
Name
PhoneX
Potential Error
The TeamMembers constructor initializes the object array with this statement:
obj = repelem(obj,1,n);
Because the obj argument to repelem is a ProjectEngineer object, the array returned is of the
same class.
Without this statement, the TeamMembers constructor would create default objects to fill in array
elements in the for loop. The resulting heterogeneous array would be of the class of the common
superclass (TeamMembers in this case). If the superclass returns this heterogeneous array to the
subclass constructor, it is a violation of the rule that class constructors must preserve the class of the
returned object.
10-30
Heterogeneous Array Constructors
See Also
More About
• “Designing Heterogeneous Class Hierarchies” on page 10-20
10-31
11
For more information, see “Event and Listener Concepts” on page 11-12.
Predefined Events
MATLAB Defines events for listening to property sets and queries. For more information, see “Listen
for Changes to Property Values” on page 11-32.
All handle objects define an event named ObjectBeingDestroyed. MATLAB triggers this event
before calling the class destructor.
Event Syntax
Define an event name in the events code block:
11-2
Overview Events and Listeners
Any function or method can trigger the event for a specific instance of the class defining the event.
For example, the triggerEvent method calls notify to trigger the StateChange event:
obj = MyClass;
obj.triggerEvent
For more information, see “Events and Listeners Syntax” on page 11-18.
Create Listener
Define a listener using the handle class addlisteneror listener method. Pass a function handle
for the listener callback function using one of these syntaxes:
11-3
11 Events — Sending and Responding to Messages
• SourceOfEvent — An object of the class that defines the event. The event is triggered on this
object.
• EventName — The name of the event defined in the class events code block.
• @listenerCallback — a function handle referencing the function that executes in response to
the event.
function lh = createListener(src)
lh = addlistener(src,'StateChange',@handleStateChange)
end
Define the callback function for the listener. The callback function must accept as the first two
arguments the event source object and an event data object: Use the event source argument to
access the object that triggered the event. Find information about the event using the event data
object.
function handleStateChange(src,eventData)
% src - handle to object that triggered the event
% eventData - event.EventData object containing
% information about the event.
...
end
See Also
event.EventData | handle
Related Examples
• “Listener Lifecycle” on page 11-23
• “Implement Property Set Listener” on page 11-10
11-4
Define Custom Event Data
Events provide information to listener callback functions by passing an event data argument to the
specified function. By default, MATLAB passes an event.EventData object to the listener callback.
This object has two properties:
Provide additional information to the listener callback by subclassing the event.EventData class.
11-5
11 Events — Sending and Responding to Messages
obj.Prop1 = value;
if (obj.Prop1 > 10)
% Trigger the event using custom event data
notify(obj,'Overflow',SpecialEventDataClass(orgvalue));
end
end
end
end
The function setupSEC instantiates the SimpleEventClass class and adds a listener to the object.
In this example, the listener callback function displays information that is contained in the
eventData argument (which is a SpecialEventDataClass object).
sec = setupSEC;
sec.Prop1 = 5;
sec.Prop1 = 15; % listener triggers callback
11-6
Define Custom Event Data
See Also
Related Examples
• “Observe Changes to Property Values” on page 11-8
11-7
11 Events — Sending and Responding to Messages
The PropLis class uses an ordinary method (attachListener) to add the listener for the
ObservedProp property. If the PropLis class defines a constructor, the constructor can contain the
call to addlistener.
The listener callback is a static method (propChange). MATLAB passes two arguments when calling
this function:
These arguments provide information about the property and the event.
Use the PropLis class by creating an instance and calling its attachListener method:
plObj = PropLis;
plObj.ObservedProp
ans =
plObj.attachListener
plObj.ObservedProp = 2;
11-8
Observe Changes to Property Values
See Also
addlistener | event.proplistener | listener
Related Examples
• “Listener Lifecycle” on page 11-23
• “Implement Property Set Listener” on page 11-10
11-9
11 Events — Sending and Responding to Messages
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.
2 Attempting to set the value of the ResultNumber property triggers the PreSet event, which
executes the listener callback before setting the property value.
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.
11-10
Implement Property Set Listener
scatter(obj.AxHandle,randn(1,20),randn(1,20),'p')
obj.ResultNumber = obj.ResultNumber + 1;
end
end
methods (Static)
function updateTitle(~,eventData)
h = eventData.AffectedObject;
set(get(h.AxHandle,'Title'),'String',['Result Number: ',...
num2str(h.ResultNumber)])
end
end
end
The scatter graph looks similar to this graph after three push-button clicks.
buttonObj = PushButton;
See Also
Related Examples
• “Listen for Changes to Property Values” on page 11-32
11-11
11 Events — Sending and Responding to Messages
Basically, any activity that you can detect programmatically can generate an event and communicate
information to other objects.
MATLAB classes define a process that communicates the occurrence of events to other objects that
respond to the events. The event model works this way:
• A handle class declares a name used to represent an event. “Name Events” on page 11-18
• After creating an object of the event-declaring class, attach listener to that object. “Control
Listener Lifecycle” on page 11-23
• A call to the handle class notify method broadcasts a notice of the event to listeners. The class
user determines when to trigger the event. “Trigger Events” on page 11-18
• Listeners execute a callback function when notified that the event has occurred. “Specifying
Listener Callbacks” on page 11-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. “Control Listener Lifecycle” on page 11-23
11-12
Event and Listener Concepts
Limitations
There are certain limitations to the use of events:
• The event source cannot guarantee that listeners exist when triggering the event.
• A listener cannot prevent other listeners from being notified that the event occurred.
• The order in which listeners execute is not defined.
• Listeners should not modify the event data object passed to the listener callback, because other
listeners are passed this same handle object.
11-13
11 Events — Sending and Responding to Messages
MATLAB passes the source object to the listener callback in the required event data argument. Use
the source object to access any of the object's public properties from within your listener callback
function.
You can create a subclass of the event.EventData class to provide additional information to
listener callback functions. The subclass would define properties to contain the additional data and
provide a method to construct the derived event data object so it can be passed to the notify
method.
“Define Event-Specific Data” on page 11-21 provides an example showing how to customize this
data.
“Comparison of Handle and Value Classes” on page 7-2 provides general information on handle
classes.
“Events and Listeners Syntax” on page 11-18 shows the syntax for defining a handle class and
events.
• 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.
When a property event occurs, the callback is passed an event.PropertyEvent object. This object
has three properties:
You can define your own property-change event data by subclassing the event.EventData class.
The event.PropertyEvent class is a sealed subclass of event.EventData.
11-14
Event and Listener Concepts
See “Listen for Changes to Property Values” on page 11-32 for a description of the process for
creating property listeners.
See “Property Access Methods” on page 8-39 for information on methods that control access to
property values.
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 when an enabled listener receives event notification
• Enabled — Callback function executes only when Enabled is true. See “Enable and Disable
Listeners” on page 11-49 for an example.
• Recursive — Allow listener to trigger the same event that caused execution of the callback.
Recursive is false by default. If the callback triggers the event for which it is defined as the
callback, the listener cannot execute recursively. Therefore, set Recursive to false if the
callback must trigger its own event. Setting the Recursive property to true can create a
situation where infinite recursion reaches the recursion limit and triggers an error.
11-15
11 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.
11-16
Event Attributes
Event Attributes
See Also
Related Examples
• “Events and Listeners Syntax” on page 11-18
11-17
11 Events — Sending and Responding to Messages
Components to Implement
Implementation of events and listeners involves these components:
• Specification of the name of an event in a handle class — “Name Events” on page 11-18.
• A function or method to trigger the event when the action occurs — “Trigger Events” on page 11-
18.
• Listener objects to execute callback functions in response to the triggered event — “Listen to
Events” on page 11-19.
• Default or custom event data that the event passes to the callback functions — “Define Event-
Specific Data” on page 11-21.
Name Events
Define an event by declaring an event name inside an events block. For example, this class creates
an event called ToggledState:
Trigger Events
The OnStateChange method calls notify to trigger the ToggledState event. Pass the handle of
the object that is the source of the event and the name of the event to notify.
11-18
Events and Listeners Syntax
obj.State = newState;
notify(obj,'ToggledState');
end
end
end
end
Listen to Events
After the call to notify triggers an event, MATLAB broadcasts a message to all listeners that are
defined for that event and source object. There are two ways to create listeners: using the handle
class addlistener or listener method.
If you want the listener to persist beyond the normal variable scope, use addlistener to create it.
The event source object holds a reference to the listener object. When the event source object is
destroyed, MATLAB destroys the listener.
Use the listener method to create listeners when you want to manage the lifecycle of the listener
and do not want a coupling between the event source and listener object. MATLAB does not destroy
listeners created with listener when the event source is destroyed. However, your code must keep
the listener object handle in scope when creating listeners using listener.
The listener method requires the same arguments as addlistener: the event-naming object, the
event name, and a function handle to the callback. listener returns the handle to the listener
object.
lh = listener(obj,'EventName',@callbackFunction)
For example, this code uses the ToggleState event discussed previously:
lh = listener(obj,'ToggleState',@RespondToToggle.handleEvnt)
Callback Function
The listener callback function must accept a minimum of two arguments, which MATLAB
automatically passes to the callback. Here are the required arguments:
• The source of the event — that is, obj in the call to addlistener or event.listener.
• An event.EventData object or a subclass of event.EventData, such as the
ToggleEventData object described in, “Define Event-Specific Data” on page 11-21.
11-19
11 Events — Sending and Responding to Messages
Define the callback function to accept the source object and event data arguments.
function callbackFunction(src,evtdata)
...
end
For more information on callback syntax, see “Listener Callback Syntax” on page 11-24.
Define Listener
The RespondToToggle class defines objects that listen for the ToggleState event defined in the
ToggleButton class.
classdef RespondToToggle < handle
methods
function obj = RespondToToggle(toggle_button_obj)
addlistener(toggle_button_obj,'ToggledState',@RespondToToggle.handleEvnt);
end
end
methods (Static)
function handleEvnt(src,~)
if src.State
disp('ToggledState is true')
else
disp('ToggledState is false')
end
end
end
end
The class RespondToToggle adds the listener in its constructor. In this case, the class defines the
callback (handleEvnt) as a static method that accepts the two required arguments:
• src — The handle of the object triggering the event (that is, a ToggleButton object)
• evtdata — An event.EventData object
tb = ToggleButton;
rtt = RespondToToggle(tb);
Whenever you call the OnStateChange method of the ToggleButton object, notify triggers the
event. For this example, the callback displays the value of the State property:
tb.OnStateChange(true)
ToggledState is true
tb.OnStateChange(false)
ToggledState is false
Remove Listeners
Remove a listener object by calling delete on its handle. For example, if the class
RespondToToggle saved the listener handle as a property, you could delete the listener.
classdef RespondToToggle < handle
properties
ListenerHandle % Property for listener handle
end
methods
function obj = RespondToToggle(toggle_button_obj)
11-20
Events and Listeners Syntax
hl = addlistener(toggle_button_obj,'ToggledState',@RespondToToggle.handleEvnt);
obj.ListenerHandle = hl; % Save listener handle
end
end
methods (Static)
function handleEvnt(src,~)
if src.State
disp('ToggledState is true')
else
disp('ToggledState is false')
end
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);
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)
Note To save and load objects that are subclasses of event.EventData, such as
ToggleEventData, enable the ConstructOnLoad class attribute for the subclass.
methods
function data = ToggleEventData(newState)
data.NewState = newState;
end
end
end
The call to notify can use the ToggleEventData constructor to create the necessary argument.
evtdata = ToggleEventData(newState);
notify(obj,'ToggledState',evtdata);
11-21
11 Events — Sending and Responding to Messages
See Also
Related Examples
• “Listener Callback Syntax” on page 11-24
• “Listen for Changes to Property Values” on page 11-32
• “Techniques for Using Events and Listeners” on page 11-39
11-22
Listener Lifecycle
Listener Lifecycle
In this section...
“Control Listener Lifecycle” on page 11-23
“Temporarily Deactivate Listeners” on page 11-23
“Permanently Delete Listeners” on page 11-23
• addlistener creates a coupling between the listener and event source object. The listener object
persists until you delete it or until the event object is destroyed. When the event source object is
destroyed, MATLAB automatically destroys the listener object.
• listener constructs listener objects that are not coupled to the lifecycle of the event source
object. The listener is active as long as the listener object remains in scope and is not explicitly
deleted. Therefore, your application must maintain a reference to the listener object by storing the
listener handle. The advantage of uncoupling the listener and event objects is that you can define
and destroy each independently.
For more information, see “Events and Listeners Syntax” on page 11-18.
ListenerHandle.Enabled = false;
ListenerHandle.Enabled = true;
delete(ListenerHandle)
Note Do not use the pack command with objects that define events and listeners. The pack
command causes the destruction of any listeners defined for the objects in the workspace. For
information on restoring listeners when saving objects, see “Restore Listeners” on page 13-26.
See Also
Related Examples
• “Enable and Disable Listeners” on page 11-49
11-23
11 Events — Sending and Responding to Messages
If you do not use the event source and event data arguments, you can define the function to ignore
these inputs:
function callbackFunction(~,~)
...
end
For a method:
function callbackMethod(obj,src,evnt)
...
end
11-24
Listener Callback Syntax
Here is the syntax for an ordinary method. The input arguments (arg1,...argn) must be defined in
the context in which you call addlistener.
lh = addlistener(src,'EventName',@(src,evnt)obj.callbackMethod(src,evnt,arg1,...argn)
The TestAnonyFcn class shows the use of an anonymous function with an additional argument. The
listener callback displays the inputs arguments to show how MATLAB calls the callback method.
classdef TestAnonyFcn < handle
events
Update
end
methods
function obj = TestAnonyFcn
t = datestr(now);
addlistener(obj,'Update',@(src,evnt)obj.evntCb(src,evnt,t));
end
function triggerEvnt(obj)
notify(obj,'Update')
end
end
methods (Access = private)
function evntCb(~,~,evnt,varargin)
disp(['Number of inputs: ',num2str(nargin)])
disp(evnt.EventName)
disp(varargin{:})
end
end
end
Create an object and trigger the event by calling the triggerEvt method:
obj = TestAnonyFcn;
obj.triggerEvnt;
Number of inputs: 4
Update
01-Jul-2008 17:19:36
11-25
11 Events — Sending and Responding to Messages
See Also
Related Examples
• “Callback Execution” on page 11-27
• “Create Function Handle”
11-26
Callback Execution
Callback Execution
In this section...
“When Callbacks Execute” on page 11-27
“Listener Order of Execution” on page 11-27
“Callbacks That Call notify” on page 11-27
“Manage Callback Errors” on page 11-27
“Invoke Functions from Function Handles” on page 11-27
Callback function execution continues until the function completes. If an error occurs in a callback
function, execution stops and control returns to the calling function. Then any remaining listener
callback functions execute.
The handle class notify method calls all listeners before returning execution to the function that
called notify.
Listener callbacks can call notify to trigger events, including the same event that invoked the
callback. When a function calls notify, MATLAB sets the property values of the event data object
that is passed to callback functions. To ensure that these properties have appropriate values for
subsequently called callbacks, always create a new event data object if you call notify with custom
event data.
11-27
11 Events — Sending and Responding to Messages
For example, the UpdateEvt class defines an event named Update and a listener for that event. The
listener callback is the private method evtCb.
Private methods are normally accessible only by class methods. However, because the function
handle is created in a class method, notify can execute the callback from outside of the class:
a = UpdateEvt;
a.notify('Update')
See Also
Related Examples
• “Listener Callback Syntax” on page 11-24
11-28
Determine If Event Has Listeners
Note When called, event.hasListener must have NotifyAccess for the event. That is, call
event.hasListener in a context in which you can call notify for the event in question.
Coding Patterns
• Conditionalize the creation of event data and the call to notify using event.hasListener. For
an object array a, determine if there are listeners before creating event data and triggering the
event:
if any(event.hasListener(a,'NameOfEvent'))
evt = MyCustomEventData(...);
notify(a,'NameOfEvent',evt)
end
• Trigger events selectively using logical indexing with the values returned by
event.hasListener. Send event notifications only for array elements that have listeners:
ind = event.hasListeners(a,'NameOfEvent');
notify(a(ind),'NameOfEvent',evt)
For example, in the following diagram, the class of a heterogeneous array formed with objects of
classes SpecificA, SpecificB, and SpecificC is RootSuperclass. Therefore,
event.hasListener can find listeners only for the RootEvent event, because it is the only event
common to all array elements.
11-29
11 Events — Sending and Responding to Messages
het = [SpecificA,SpecificB,SpecificC];
class(het)
ans
RootSuperclass
events(het)
RootEvent
event.hasListener cannot determine if there are listeners for events that are defined by some but
not all objects in the array:
event.hasListener(het,'ClassAEvent')
Determine if individual objects in the heterogeneous array have listeners defined for their specific
events, by indexing into the array:
event.hasListener(het(1),'ClassAEvent')
For more information about determining the class of heterogeneous arrays, see “Designing
Heterogeneous Class Hierarchies” on page 10-20.
11-30
Determine If Event Has Listeners
See Also
Related Examples
• “Listener Lifecycle” on page 11-23
11-31
11 Events — Sending and Responding to Messages
In the properties block, enable the SetObservable attribute. You can define PreSet and PostSet
listeners for the properties defined in this block:
properties (SetObservable)
PropOne
PropTwo
...
end
The listener executes the callback function when MATLAB triggers the property event. Define the
callback function to have two specific arguments, which are passed to the function automatically
when called by the listener:
• Event source — a meta.property object describing the object that is the source of the property
event
• Event data — a event.PropertyEvent object containing information about the event
You can pass additional arguments if necessary. It is often simple to define this method as Static
because these two arguments contain most necessary information in their properties.
For example, suppose the handlePropEvents function is a static method of the class creating
listeners for two properties of an object of another class:
methods (Static)
function handlePropEvents(src,evnt)
switch src.Name
case 'PropOne'
% PropOne has triggered an event
...
11-32
Listen for Changes to Property Values
case 'PropTwo'
% PropTwo has triggered an event
...
end
end
end
Another possibility is to use the event.PropertyEvent object's EventName property in the switch
statement to key off the event name (PreSet or PostSet in this case).
“Class Metadata” on page 17-2 provides more information about the meta.property class.
The addlistenerhandle class method enables you to attach a listener to a property without storing
the listener object as a persistent variable. For a property event, use the four-argument version of
addlistener.
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 that the callback function is a package function:
addlistener(EventObject,'PropOne','PostSet',@package.handlePropertyEvents);
For more information on passing functions as arguments, see “Create Function Handle”.
The PropEvent class enables property PreSet and PostSet event triggering by specifying the
SetObservable property attribute. These properties also enable the AbortSet attribute, which
prevents the triggering of the property events if the properties are set to a value that is the same as
their current value (see “Assignment When Property Value Is Unchanged” on page 11-35).
11-33
11 Events — Sending and Responding to Messages
PropOne
PropTwo
end
methods
function obj = PropEvent(p1,p2)
if nargin > 0
obj.PropOne = p1;
obj.PropTwo = p2;
end
end
end
end
You can define listeners for other events or other properties using a similar approach. 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.
classdef PropListener < handle
% Define property listeners
methods
function obj = PropListener(evtobj)
if nargin > 0
addlistener(evtobj,'PropOne','PostSet',@PropListener.handlePropEvents);
addlistener(evtobj,'PropTwo','PostSet',@PropListener.handlePropEvents);
end
end
end
methods (Static)
function handlePropEvents(src,evnt)
switch src.Name
case 'PropOne'
sprintf('PropOne is %s\n',num2str(evnt.AffectedObject.PropOne))
case 'PropTwo'
sprintf('PropTwo is %s\n',num2str(evnt.AffectedObject.PropTwo))
end
end
end
end
See Also
Related Examples
• “Assignment When Property Value Is Unchanged” on page 11-35
11-34
Assignment When Property Value Is Unchanged
You can prevent these actions by setting the property's AbortSet attribute to true. When AbortSet
is enabled, MATLAB compares the current property value to the new value being assigned to the
property. If the new value is the same as the current value, MATLAB does not:
To compare values, MATLAB must get the current value of the property. Getting the current value
causes the property get method (get.Property) to execute, if one exists. Any errors that occur
when calling the property get method are visible to the user, even if MATLAB does not change the
current value.
• You want to prevent notification of the PreSet and PostSet events and execution of the listener
callbacks when the property value does not change.
• The cost of setting a property value is greater than the cost of comparing the current property
value with the value being assigned, and you are willing to incur the comparison cost with all
assignments to the property.
11-35
11 Events — Sending and Responding to Messages
Implement AbortSet
The following example shows how the AbortSet attribute works. The AbortTheSet class defines a
property, PropOne, that has listeners for the PreGet, PreSet, PostGet, and PostSet events and
enables the AbortSet attribute.
Note To use this class, save the AbortTheSet class in a file with the same name in a folder on your
MATLAB path.
The class specifies an initial value of 7 for the PropOne property. Therefore, if you create an object
and assign the property value of 7, there is no need to trigger the PreSet event. However, the
getPropOne method is called to get the current value of the property to compare to the assigned
vale.
11-36
Assignment When Property Value Is Unchanged
obj = AbortTheSet;
obj.PropOne = 7;
get.PropOne called
If you specify a value other than 7, then MATLAB performs these steps:
obj = AbortTheSet;
obj.PropOne = 9;
get.PropOne called
Pre-set event triggered
set.PropOne called
Post-set event triggered
If you query the property value, the PreGet and PostGet events are triggered.
obj.PropOne
ans =
11-37
11 Events — Sending and Responding to Messages
function set.PropOne(obj,val)
disp('set.PropOne called')
obj.PropOne = val;
end
function getPrePropEvt(obj,src,evnt)
disp ('Pre-get event triggered')
% ...
end
function setPrePropEvt(obj,src,evnt)
disp ('Pre-set event triggered')
% ...
end
function getPostPropEvt(obj,src,evnt)
disp ('Post-get event triggered')
% ...
end
function setPostPropEvt(obj,src,evnt)
disp ('Post-set event triggered')
% ...
end
function disp(obj)
% Overload disp to avoid accessing property
disp (class(obj))
end
end
end
Because MATLAB applies scalar expansion to satisfy the size restriction, the following assignment
does not trigger the PreSet or PostSet events.
obj = AbortTheSet;
obj.PropOne = 7;
get.PropOne called
obj.PropOne
ans =
7 7 7
For information on property validation, see “Validate Property Values” on page 8-20.
See Also
Related Examples
• “Property Access Methods” on page 8-39
• “Determine If Event Has Listeners” on page 11-29
11-38
Techniques for Using Events and Listeners
Example Overview
This example defines two classes:
• fcneval — The function evaluator class contains a MATLAB expression and evaluates this
expression over a specified range
• fcnview — The function viewer class contains a fcneval object and displays surface graphs of
the evaluated expression using the data contained in fcneval.
• 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 contains. fcnview creates listeners to change
the graphs if any of the data in the fcneval object change.
11-39
11 Events — Sending and Responding to Messages
11-40
Techniques for Using Events and Listeners
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.
Method Purpose
fcnview Class constructor. Input is fcneval object.
createLisn Calls addlistener to create listeners for UpdateGraph and Lm
property PostSet listeners.
11-41
11 Events — Sending and Responding to Messages
Method Purpose
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.
listenLm Callback for Lm property PostSet event
delete Delete method for fcnview class.
createViews Static method that creates an instance of the fcnview class for each
subplot, defines the context menus that enable/disable listeners, and
creates the subplots
“Handle Class Methods” on page 7-11 provides a complete list of methods that are inherited when
you subclass the handle class.
• Create an instance of the fcneval class to contain the MATLAB expression of a function of two
variables and the range over which you want to evaluate this function
• Use the fcnview class static function createViews to visualize the function
• Change the MATLAB expression or the limits contained by the fcneval object and all the
fcnview objects respond to the events generated.
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. Use the class name to call
a static function:
fcnview.createViews(feobject);
The createView method generates four views of the function contained in the fcneval object.
11-42
Techniques for Using Events and Listeners
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:
Similarly, if you change the limits by assigning a value to the feobject.Lm property, the feobject
triggers a PostSet property event and the listener callbacks update the graph.
11-43
11 Events — Sending and Responding to Messages
In this figure, the listeners are reenabled 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
The UpdateGraph event is a class-defined event. The fcneval class names the event and calls
notify when the event occurs.
11-44
Techniques for Using Events and Listeners
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.
events
UpdateGraph
end
The fcneval class defines a property set method for the FofXY property. FofXY is the property that
stores the MATLAB expression for the mathematical function. This expression must be a valid
MATLAB expression for a function of two variables.
11-45
11 Events — Sending and Responding to Messages
If fcneval.isSuitable does not return an MException object, the set.FofXY method assigns
the value to the property and triggers the UpdateGraph event.
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
The set.FofXY method calls a static method (fcneval.isSuitable) to determine the suitability of
the specified expression. fcneval.isSuitable returns an MException object if it determines that
the expression is unsuitable. fcneval.isSuitable calls the MException constructor directly to
create more useful error messages for the user.
set.FofXY issues the exception using the 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.
The fcneval.isSuitable method could provide additional test to ensure that the expression
assigned to the FofXY property meets the criteria required by the class design.
11-46
Techniques for Using Events and Listeners
Other Approaches
The class could have implemented a property set event for the FofXY property and would, therefore,
not need to call notify (see “Listen for Changes to Property Values” on page 11-32). Defining a class
event provides more flexibility in this case because you can better control event triggering.
For example, suppose that you wanted to update the graph only if the new data is 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.
The fcnview class creates a listener for the UpdateGraph event using the addlistener method:
obj.HLUpdateGraph = addlistener(obj.FcnObject,'UpdateGraph',...
@(src,evnt)listenUpdateGraph(obj,src,evnt)); % Add obj to argument list
The fcnview object stores a handle to the event.listener object in its HLUpdateGraph property,
which is used to enable/disable the listener by a context menu (see “Enable and Disable Listeners” on
page 11-49).
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 the callback updates.
function listenUpdateGraph(obj,src,evnt)
if ishandle(obj.HSurface) % If surface exists
obj.updateSurfaceData % Update surface data
end
end
The updateSurfaceData function is a class method that updates the surface data when a different
mathematical function is assigned to the fcneval object. Updating a graphics object data is more
efficient than creating a new object using the new data:
function updateSurfaceData(obj)
% Get data from fcneval object and set surface data
set(obj.HSurface,...
'XData',obj.FcnObject.Data.X,...
'YData',obj.FcnObject.Data.Y,...
'ZData',obj.FcnObject.Data.Matrix);
end
11-47
11 Events — Sending and Responding to Messages
The fcneval class defines a set function for the Lm property. When a value is assigned to this
property during object construction or property reassignment, the following sequence occurs:
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.
To create a listener for the PostSet event, you must set the property's SetObservable attribute to
true:
properties (SetObservable = true)
Lm = [-2*pi 2*pi]; % specifies default value
end
“Specify Property Attributes” on page 8-5 provides a list of all property attributes.
11-48
Techniques for Using Events and Listeners
The fcnview class creates a listener for the PostSet event using the addlistener method:
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 “Enable and Disable Listeners” on page
11-49).
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 the callback updates.
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
There are two callbacks used by the context menu corresponding to the two items on the menu:
• 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.
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
11-49
11 Events — Sending and Responding to Messages
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
events
UpdateGraph
end
methods
function obj = fcneval(fcn_handle,limits) % Constructor returns object
if nargin > 0
obj.FofXY = fcn_handle; % Assign property values
obj.Lm = limits;
end
end
function set.FofXY(obj,func)
me = fcneval.isSuitable(func);
if ~isempty(me)
throw(me)
end
obj.FofXY = func;
notify(obj,'UpdateGraph');
end
function set.Lm(obj,lim)
if ~(lim(1) < lim(2))
error('Limits must be monotonically increasing')
else
obj.Lm = lim;
end
end
end
end % methods
11-50
Techniques for Using Events and Listeners
end % grid
end
end
methods
function obj = fcnview(fcnobj)
if nargin > 0
obj.FcnObject = fcnobj;
obj.createLisn;
end
end
function createLisn(obj)
obj.HLUpdateGraph = addlistener(obj.FcnObject,'UpdateGraph',...
@(src,evnt)listenUpdateGraph(obj,src,evnt));
obj.HLLm = addlistener(obj.FcnObject,'Lm','PostSet',...
@(src,evnt)listenLm(obj,src,evnt));
end
function lims(obj)
lmts = obj.FcnObject.Lm;
set(obj.HAxes,'XLim',lmts);
set(obj.HAxes,'Ylim',lmts);
end
function updateSurfaceData(obj)
data = obj.FcnObject.Data;
set(obj.HSurface,...
11-51
11 Events — Sending and Responding to Messages
'XData',data.X,...
'YData',data.Y,...
'ZData',data.Matrix);
end
function listenUpdateGraph(obj,~,~)
if ishandle(obj.HSurface)
obj.updateSurfaceData
end
end
function listenLm(obj,~,~)
if ishandle(obj.HAxes)
lims(obj);
if ishandle(obj.HSurface)
obj.updateSurfaceData
end
end
end
function delete(obj)
if ishandle(obj.HAxes)
delete(obj.HAxes);
else
return
end
end
end
methods (Static)
createViews(a)
end
end
@fcnview/createViews
function createViews(fcnevalobj)
p = pi; deg = 180/p;
hfig = figure('Visible','off',...
'Toolbar','none');
for k=4:-1:1
fcnviewobj(k) = fcnview(fcnevalobj);
axh = subplot(2,2,k);
fcnviewobj(k).HAxes = axh;
hcm(k) = uicontextmenu;
set(axh,'Parent',hfig,...
'FontSize',8,...
'UIContextMenu',hcm(k))
fcnviewobj(k).HEnableCm = uimenu(hcm(k),...
'Label','Listen',...
'Checked','on',...
'Callback',@(src,evnt)enableLisn(fcnviewobj(k),src,evnt));
fcnviewobj(k).HDisableCm = uimenu(hcm(k),...
'Label','Don''t Listen',...
'Checked','off',...
'Callback',@(src,evnt)disableLisn(fcnviewobj(k),src,evnt));
az = p/k*deg;
11-52
Techniques for Using Events and Listeners
view(axh,az,30)
title(axh,['View: ',num2str(az),' 30'])
fcnviewobj(k).lims;
surfLight(fcnviewobj(k),axh)
end
set(hfig,'Visible','on')
end
function surfLight(obj,axh)
obj.HSurface = surface(obj.FcnObject.Data.X,...
obj.FcnObject.Data.Y,...
obj.FcnObject.Data.Matrix,...
'FaceColor',[.8 .8 0],'EdgeColor',[.3 .3 .2],...
'FaceLighting','phong',...
'FaceAlpha',.3,...
'HitTest','off',...
'Parent',axh);
lims(obj)
camlight left; material shiny; grid off
colormap copper
end
function enableLisn(obj,~,~)
obj.HLUpdateGraph.Enabled = true;
obj.HLLm.Enabled = true;
set(obj.HEnableCm,'Checked','on')
set(obj.HDisableCm,'Checked','off')
end
function disableLisn(obj,~,~)
obj.HLUpdateGraph.Enabled = false;
obj.HLLm.Enabled = false;
set(obj.HEnableCm,'Checked','off')
set(obj.HDisableCm,'Checked','on')
end
11-53
12
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.
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.
12-2
Hierarchies of Classes — Concepts
When designing classes, your abstraction contains 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.
You can usually describe the relationship between an object of a subclass and an object of its
superclass with a statement like:
This relationship implies that objects belonging to a subclass have the same properties, methods, and
events as the superclass. Subclass objects also have any new features defined by the subclass. Test
this relationship with the isa function.
You can pass a subclass object to a superclass method, but you can access only those properties that
the superclass defines. This behavior enables you to modify the subclasses without affecting the
superclass.
Two points about super and subclass behavior to keep in mind are:
12-3
12 How to Build on Other Classes
Therefore, you can treat an Engineer object like any other Employees object, but an Employee
object cannot pass for an Engineer object.
MATLAB determines the class of an object based on its most specific class. Therefore, an Engineer
object is of class Engineer, while it is also an Employees object, as using the isa function reveals.
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
See “Concatenating Objects of Different Classes” on page 10-15 for more information.
See “Object Converters” on page 18-10 for information on defining converter methods.
Implementation inheritance enables code reuse by subclasses. For example, an employee class can
have a submitStatus method that all employee subclasses can use. Subclasses can extend an
inherited method to provide specialized functionality, while reusing the common aspects. See “Modify
Inherited Methods” on page 12-13 for more information on this process.
Create an interface using an abstract class as the superclass. This class defines the methods and
properties that you must implement in the subclasses, but does not provide an implementation.
The subclasses must provide their own implementation of the abstract members of the superclass. To
create an interface, define methods and properties as abstract using their Abstract attribute. See
“Abstract Classes and Class Members” on page 12-72 for more information and an example.
See Also
Related Examples
• “Design Subclass Constructors” on page 12-7
12-4
Subclass Syntax
Subclass Syntax
In this section...
“Subclass Definition Syntax” on page 12-5
“Subclass double” on page 12-5
When inheriting from multiple classes, use the & character to indicate the combination of the
superclasses:
See “Class Member Compatibility” on page 12-18 for more information on deriving from multiple
superclasses.
Class Attributes
Subclass double
Suppose you want to define a class that derived from double and restricts values to be positive
numbers. The PositiveDouble class:
• Supports a default constructor (no input arguments). See “No Input Argument Constructor
Requirement” on page 9-19
• Restricts the inputs to positive values using mustBePositive.
• Calls the superclass constructor with the input value to create the double numeric value.
a = PositiveDouble(1:5);
You can perform operations on objects of this class like any double.
12-5
12 How to Build on Other Classes
sum(a)
ans =
15
a = PositiveDouble(0:5);
See Also
Related Examples
• “Design Subclass Constructors” on page 12-7
• “Subclasses of MATLAB Built-In Types” on page 12-41
12-6
Design Subclass Constructors
If you do not explicitly call the superclass constructors from the subclass constructor, MATLAB
implicitly calls these constructors with no arguments. The superclass constructors must support the
no argument syntax to support implicit calls.
MATLAB does not guarantee any specific calling order when there are multiple superclasses. If the
order in which MATLAB calls the superclass constructors is important, call the superclass
constructors explicitly from the subclass constructor.
If you do not define a subclass constructor, you can call the default constructor with superclass
arguments. For more information, see “Default Constructor” on page 9-17 and “Implicit Call to
Inherited Constructor” on page 9-21.
obj@SuperClass1(args,...);
...
obj@SuperclassN(args,...);
Where obj is the output of the subclass constructor, SuperClass... is the name of a superclass,
and args are any arguments required by the respective superclass constructor.
For example, the following segment of a class definition shows that a class called Stocks that is a
subclass of a class called Assets.
12-7
12 How to Build on Other Classes
...
end
end
end
“Subclass Constructors” on page 9-19 provides more information on creating subclass constructor
methods.
If a superclass is contained in a package, include the package name. For example, the Assests class
is in the finance package:
classdef Stocks < finance.Assets
methods
function s = Stocks(asset_args,...)
if nargin == 0
...
end
% Call asset constructor
[email protected](asset_args);
...
end
end
end
To derive a class from multiple superclasses, initialize the subclass object with calls to each
superclass constructor:
classdef Stocks < finance.Assets & Taxable
methods
function s = Stocks(asset_args,tax_args,...)
if nargin == 0
...
end
% Call asset and member class constructors
[email protected](asset_args)
s@Taxable(tax_args)
...
end
end
end
For example, the Stocks class constructor supports the no argument case with the if statement, but
calls the superclass constructor outside of the if code block.
classdef Stocks < finance.Assets
properties
12-8
Design Subclass Constructors
NumShares
Symbol
end
methods
function s = Stocks(description,numshares,symbol)
if nargin == 0
description = '';
numshares = 0;
symbol = '';
end
[email protected](description);
s.NumShares = numshares;
s.Symbol = symbol;
end
end
end
The following implementations of classes A, B, and C show how to design this relationship in each
class.
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@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:
12-9
12 How to Build on Other Classes
classdef C < B
methods
function obj = C(x,y)
...
obj@B(x,y);
end
end
end
See Also
Related Examples
• “No Input Argument Constructor Requirement” on page 9-19
12-10
Control Sequence of Constructor Calls
If you explicitly call a superclass constructor from the most specific subclass constructor (ClassC in
the following diagram), then MATLAB calls the most specific subclass constructor first. If you do not
make an explicit call to a superclass constructor from the subclass constructor, MATLAB makes the
implicit call when accessing the object.
Suppose that you have a hierarchy of classes in which ClassC derives from ClassB, which derives
from ClassA. The constructor for a subclass can call only direct superclasses. Therefore, each class
constructor can call the direct superclass constructor:
In cases of multiple inheritance, the subclass constructor can call each superclass constructor. To
ensure that a specific superclass constructor calling sequence is followed, call all direct superclass
constructors explicitly from the most specific subclass constructor:
12-11
12 How to Build on Other Classes
See Also
Related Examples
• “Call Only Direct Superclass from Constructor” on page 12-9
• “Class Constructor Methods” on page 9-16
12-12
Modify Inherited Methods
For example, suppose that both superclass and subclass define a method called foo. The method
names are the same so the subclass method can call the superclass method. However, the subclass
method can also perform other steps before and after the call to the superclass method. It can
operate on the specialized parts to the subclass that are not part of the superclass.
For example, this subclass defines a foo method that calls the superclass foo method
classdef Sub < Super
methods
function foo(obj)
% preprocessing steps
...
foo@Super(obj);
% postprocessing steps
...
end
end
end
12-13
12 How to Build on Other Classes
classdef Super
methods
function foo(obj)
step1(obj) % Call step1
step2(obj) % Call step2
step3(obj) % Call step3
end
end
methods (Access = protected)
function step1(obj)
% Superclass version
end
function step2(obj)
% Superclass version
end
function step3(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 a subclass object to the superclass foo method, MATLAB calls the subclass step methods
because of the dispatching rules.
classdef Super
methods
function foo(obj)
% Superclass implementation
end
end
end
12-14
Modify Inherited Methods
See Also
Related Examples
• “Invoking Superclass Methods in Subclass Methods” on page 9-15
12-15
12 How to Build on Other Classes
If a superclass defines a property as abstract, the subclass must implement a concrete version of this
property or the subclass is also abstract. Superclasses define abstract properties to create a
consistent interface among subclasses.
If a superclass defines a property with private access, then only the superclass can access this
property. The subclass can implement a different property with the same name.
For example, if a subclass property has the same name as a superclass private property, and a method
of the superclass references the property name, MATLAB accesses the property defined by the
superclass.
classdef Super
properties (Access = private)
Prop = 2
end
methods
function p = superMethod(obj)
p = obj.Prop;
end
end
end
If you create an instance of the Sub class and use it to call the superclass method, MATLAB accesses
the private property of the superclass:
subObj = Sub
12-16
Modify Inherited Properties
subObj =
Prop: 1
subObj.superMethod
ans =
See Also
More About
• “Property Attributes” on page 8-7
12-17
12 How to Build on Other Classes
For more information on class syntax, see “Subclass Syntax” on page 12-5.
Here are various situations where you can resolve name and definition conflicts.
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:
• The method Access attribute is private so only the defining superclass can access the method.
• The method has the same definition in all subclasses. This situation can occur when all
superclasses inherit the method from a common base class and none of the superclasses override
the inherited definition.
• The subclass redefines the method to disambiguate the multiple definitions across all
superclasses. Therefore, the superclass methods must not have their Sealed attribute set to
true.
• Only one superclass defines the method as Sealed, in which case, the subclass adopts the sealed
method definition.
12-18
Subclassing Multiple Classes
• 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:
Multiple Inheritance
Resolving the potential conflicts involved when defining a subclass from multiple classes often
reduces the value of this approach. For example, problems can arise when you enhance superclasses
in future versions and introduce new conflicts.
Reduce potential problems by implementing only one unrestricted superclass. In all other
superclasses, all methods are
• Abstract
• Defined by a subclass
• Inherited from the unrestricted superclass
When using multiple inheritance, ensure that all superclasses remain free of conflicts in definition.
See Also
Related Examples
• “Design Subclass Constructors” on page 12-7
• “Handle Compatible Classes” on page 12-32
12-19
12 How to Build on Other Classes
Basic Knowledge
The material presented in this section builds on an understanding of the following information:
The AllowedSubclasses attribute provides a design point between Sealed classes, which do not
allow subclassing, and the default behavior, which does not restrict subclassing.
By controlling the allowed subclasses, you can create a sealed hierarchy of classes. That is, a system
of classes that enables a specific set of classes to derive from specific base classes, but that does not
allow unrestricted subclassing.
See “Define Sealed Hierarchy of Classes” on page 12-21 for more about this technique.
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:
classdef (AllowedSubclasses = ?Package.SubPackage.ClassName1) MySuperClass
...
end
Assigning an empty cell array to the AllowedSubclasses attribute is effectively the same as
defining a Sealed class.
12-20
Specify Allowed Subclasses
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.
Including a class in the list of AllowedSubclasses does not define that class as a subclass or
require you to define the class as a subclass. It just allows the referenced class to be defined as a
subclass.
Declaring a class as an allowed subclass does not affect whether this class can itself be subclassed.
A class definition can contain assignments to the AllowedSubclasses attribute that reference
classes that are not currently defined or available on the MATLAB path. However, any referenced
subclass that MATLAB cannot find when loading the class is effectively removed from the list without
causing an error or warning.
Note If MATLAB does not find any of the classes in the allowed classes list, the class is effectively
Sealed. A sealed class is equivalent to AllowedSubclasses = {}.
Sealed class hierarchies enable you to use the level of abstraction that your design requires while
maintaining a closed system of classes.
12-21
12 How to Build on Other Classes
See Also
Related Examples
• “Handle Compatible Classes” on page 12-32
12-22
Class Members Access
Basic Knowledge
The material presented in this section builds on an understanding of the following information:
Related Topics
• Properties — Access, GetAccess, and SetAccess. For a list of all property attributes, see
“Property Attributes” on page 8-7 .
• Methods — Access. For a list of all method attributes, see “Method Attributes” on page 9-4 .
• Events — ListenAccess and NotifyAccess. For a list of all event attributes, see “Event
Attributes” on page 11-16.
12-23
12 How to Build on Other Classes
• Access list — A list of one or more classes. Only the defining class and the classes in the list have
access to the class members to which the attribute applies. If you specify a list of classes, MATLAB
does not allow access by any other class (that is, access is private, except for the listed classes).
This technique provides greater flexibility and control in the design of a system of classes. For
example, use access control lists to define separate classes, but not allow access to class members
from outside the class system.
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 Specify the meta.class objects explicitly (created with the ? operator), not as values returned
by functions or other MATLAB expressions.
Generate the meta.class objects using only the ? operator and the class name. Values assigned to
the attributes cannot contain any other MATLAB expressions, including functions that return allowed
attribute values:
• meta.class objects
• Cell arrays of meta.class objects
• The values public, protected, or private
12-24
Class Members Access
Specify these values explicitly, as shown in the example code in this section.
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 method is defined as a Static method, however, it could be an ordinary method.
classdef NeedAccess
methods (Static)
function dispObj(GrantAccessObj)
disp(['Prop1 is: ',num2str(GrantAccessObj.Prop1)])
end
end
end
Get access to Prop1 is private so MATLAB returns an error if you attempt to access the property
from outside the class definition. For example, from the command line:
a = GrantAccess;
a.Prop1
NeedAccess.dispObj(a)
Prop1 is: 7
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 its m1 method:
classdef AcListSuper
methods (Access = {?AcListNonSub})
function obj = m1(obj)
disp ('Method m1 called')
end
12-25
12 How to Build on Other Classes
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
b.m1;
Including the defining class in the access list for a method grants access to all subclasses derived
from that class. When you derive from a class that has a method with an access list and that list does
not include the defining class:
For example, AcListSub is a subclass of AcListSuper. The AcListSuper class defines an access
list for method m1. However, this list does not include AcListSuper, so subclasses of AcListSuper
do not have access to method m1:
classdef AcListSub < AcListSuper
methods
function obj = sub1(obj,AcListSuper_Obj)
% Access m1 via superclass object (***NOT ALLOWED***)
AcListSuper_Obj.m1;
12-26
Class Members Access
end
function obj = sub2(obj,AcListNonSub_Obj,AcListSuper_obj)
% Access m1 via object that is in access list (is allowed)
AcListNonSub_Obj.nonSub1(AcListSuper_Obj);
end
end
end
Attempting to call the superclass m1 method from the sub1 method results in an error because
subclasses are not in the access list for m1:
a = AcListSuper;
c = AcListSub;
c.sub1(a);
You can call a superclass method from a subclass that does not have access to that method using an
object of a class that is in the superclass method access list.
The AcListSub sub2 method calls a method of a class (AcListNonSub) that is on the access list for
m1. This method, nonSub1, does have access to the superclass m1 method:
a = AcListSuper;
b = AcListNonSub;
c = AcListSub;
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 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;
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'.
12-27
12 How to Build on Other Classes
The AcListNonSub class is in the m1 method access list. This class can define a method that calls the
m1 method using an object 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);
This behavior is consistent with the behavior of any subclass object, which can substitute for an
object 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.
See Also
Related Examples
• “Property Access List” on page 12-29
• “Method Access List” on page 12-30
• “Event Access List” on page 12-31
12-28
Property Access List
• 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 provide 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.
See Also
Related Examples
• “Properties with Access Lists” on page 12-25
12-29
12 How to Build on Other Classes
classdef MethodAccess
methods (Access = {?ClassA, ?ClassB, ?MethodAccess})
function listMethod(obj)
...
end
end
end
• Access to listMethod from an instance of MethodAccess by methods of the classes ClassA and
ClassB.
• Access to listMethod from an instance of MethodAccess by methods of subclasses of
MethodAccess, because of the inclusion of MethodAccess in the access list.
• Subclasses of ClassA and ClassB are allowed to define a method named listMethod, and
MethodAccess is allowed to redefine listMethod. However, if MethodAccess was not in the
access list, its subclasses could not redefine listMethod.
See Also
Related Examples
• “Methods with Access Lists” on page 12-25
12-30
Event Access List
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.
• 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 Also
Related Examples
• “Events and Listeners Syntax” on page 11-18
12-31
12 How to Build on Other Classes
Basic Knowledge
The material presented in this section builds on knowledge of the following information.
Key Concepts
Handle-compatible class — a class that you can include with handle classes in a class hierarchy, even
if the class is not a handle class.
HandleCompatible — the class attribute that defines nonhandle classes as handle compatible.
The solution is to use handle-compatible classes. Handle compatible classes are a type of class that
you can use with handle classes when forming sets of superclasses. Designate a nonhandle
compatible class as handle-compatible by using the HandleCompatible class attribute.
classdef (HandleCompatible) MyClass
...
end
12-32
Handle Compatible Classes
• If a class does not explicitly set its HandleCompatible attribute and, if any superclass is a
handle, then all superclasses must be handle compatible.
• The HandleCompatible attribute is not inherited.
A class that does not explicitly set its HandleCompatible attribute to true is:
isa(obj,'handle')
See Also
Related Examples
• “How to Define Handle-Compatible Classes” on page 12-34
12-33
12 How to Build on Other Classes
• 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.
Handle compatibility provides greater flexibility when defining abstract superclasses. For example,
when using superclasses that support both handle and value subclasses, handle compatibility
removes the need to define both a handle version and a nonhandle version of a class.
The Utility class is useful to both handle and value subclasses. In this example, the Utility class
defines a method to reset property values to the default values defined in the respective class
definition:
classdef (HandleCompatible) Utility
methods
function obj = resetDefaults(obj)
mc = metaclass(obj);
mp = mc.PropertyList;
for k=1:length(mp)
if mp(k).HasDefault && ~strcmp(mp(k).SetAccess,'private')
obj.(mp(k).Name) = mp(k).DefaultValue;
end
end
end
end
end
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 “Class Introspection and Metadata” for information on
using meta-data classes.
The resetDefaults method defined by the Utility class returns the object it modifies. When you
call resetDefaults with a value object, the method must return the modified object. It is important
to implement methods that work with both handle and value objects in a handle compatible
superclass. See “Object Modification” on page 5-49 for more information on modifying handle and
value objects.
Consider the behavior of a value class that subclasses the Utility class. The PropertyDefaults
class defines three properties, all of which have default values:
12-34
How to Define Handle-Compatible Classes
pd = PropertyDefaults
pd =
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
pd =
Call the resetDefaults method, which is inherited from the Utility class. Because the
PropertyDefaults class is not a handle class, return the modified object.
pd = pd.resetDefaults
pd =
If the PropertyDefaults class was a handle class, then you would not need to save the object
returned by the resetDefaults method. To design a handle compatible class like Utility, ensure
that all methods work with both kinds of classes.
12-35
12 How to Build on Other Classes
However, subclassing a handle-compatible class does not necessarily result in the subclass being
handle compatible. Consider the following two cases, which demonstrate two possible results.
Suppose that you define a class that subclasses a handle class, and the handle compatible Utility
class discussed in “A Handle Compatible Class” on page 12-34. The HPropertyDefaults class has
these characteristics:
ans =
If you subclass both a value class that is not handle compatible and a handle compatible class, the
subclass is a nonhandle compatible value class. The ValueSub class:
The ValueSub class is a nonhandle-compatible value class because the MException class does not
define the HandleCompatible attribute as true:
hv = ValueSub('MATLAB:narginchk:notEnoughInputs',...
'Not enough input arguments.');
12-36
How to Define Handle-Compatible Classes
mc = metaclass(hv);
mc.HandleCompatible
ans =
See Also
Related Examples
• “Methods for Handle Compatible Classes” on page 12-38
12-37
12 How to Build on Other Classes
• If an input object is a handle object and the method alters the handle object, these changes are
visible to all workspaces that contain 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 effects of such changes
are not the same for handle and nonhandle objects.
See “Object Modification” on page 5-49 for information about modifying handle and value objects.
See Also
Related Examples
• “Handle-Compatible Classes and Heterogeneous Arrays” on page 12-39
12-38
Handle-Compatible Classes and Heterogeneous Arrays
Heterogeneous Arrays
A heterogeneous array contains objects of different classes. Members of a heterogeneous array have
a common superclass, but can belong to different subclasses. See the
matlab.mixin.Heterogeneous class for more information on heterogeneous arrays. The
matlab.mixin.Heterogeneous class is a handle-compatible class.
Subclasses cannot override sealed methods. In situations requiring subclasses to specialize methods
defined by a utility class, you can employ the design pattern referred to as the template method.
Template Technique
Suppose that you implement a handle compatible class that works with heterogeneous arrays. This
approach enables you to seal public methods, while providing a way for each subclass to specialize
how the method works on each subclass instance. In the handle compatible class:
Each subclass in the heterogeneous hierarchy implements a concrete version of the abstract method.
The concrete method provides specialized behavior required by the particular subclass.
12-39
12 How to Build on Other Classes
end
end
See Also
Related Examples
• “Handle Compatible Classes” on page 12-32
12-40
Subclasses of MATLAB Built-In Types
In this section...
“MATLAB Built-In Types” on page 12-41
“Built-In Types You Can Subclass” on page 12-41
“Why Subclass Built-In Types” on page 12-41
“Which Functions Work with Subclasses of Built-In Types” on page 12-42
“Behavior of Built-In Functions with Subclass Objects” on page 12-42
“Built-In Subclasses That Define Properties” on page 12-43
Built-in types define methods that perform operations on objects of these classes. For example, you
can perform operations on numeric arrays such as, sorting, arithmetic, and logical operations.
See “Fundamental MATLAB Classes” 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.
You cannot subclass any class that has its Sealed attribute set to true. To determine if the class is
Sealed, query the class metadata:
mc = ?ClassName;
mc.Sealed
A value of 0 indicates that the class is not Sealed and can be subclasses.
12-41
12 How to Build on Other Classes
To see a list of functions that the subclass has inherited as methods, use the methods function:
methods('SubclassName')
• Inherited methods
• Functions that normally accept input arguments of the same class as the superclass.
Built-in functions and methods that work on built-in classes can behave differently when called with
subclasses of built-in classes. Their behavior depends on which function you are using and whether
your subclass defines properties.
Behavior Categories
When you call an inherited method on a subclass of a built-in class, the result depends on the nature
of the operation performed by the method. The behaviors of these methods fit into several categories.
• Operations on data values return objects of the superclass. For example, if you subclass double
and perform addition on two subclass objects, MATLAB adds the numeric values and returns a
value of class double.
• Operations on the orientation or structure of the data return objects of the subclass. Methods that
perform these kinds of operations include, reshape, permute, transpose, and so on.
• Converting a subclass object to a built-in class returns an object of the specified class. Functions
such as uint32, double, char work with subclass objects the same as they work with built-in
objects.
• Comparing objects or testing for inclusion in a specific set returns logical or built-in objects,
depending on the function. Functions such as isequal, ischar, isobject work with subclass
objects the same as they work with superclass objects.
• Indexing expressions return objects of the subclass. If the subclass defines properties, then
default indexing no longer works. The subclass must define its own indexing methods.
• Concatenation returns an object of the subclass. If the subclass defines properties, then default
concatenation no longer works and the subclass must define its own concatenation methods.
To list the built-in functions that work with a subclass of a built-in class, use the methods function.
12-42
Subclasses of MATLAB Built-In Types
The subclass must define what indexing and concatenation mean for a class with properties. If your
subclass needs indexing and concatenation functionality, then the subclass must implement the
appropriate methods.
See Also
Related Examples
• “Representing Hardware with Classes” on page 12-66
• “Subclasses of Built-In Types with Properties” on page 12-54
• “Subclasses of Built-In Types Without Properties” on page 12-48
12-43
12 How to Build on Other Classes
Subclass double
Most built-in functions used with built-in classes are actually methods of the built-in class. For
example, the double and single classes define several methods to perform arithmetic operations,
indexing, matrix operation, and so on. All these built-in class methods work with subclasses of the
built-in class.
Subclassing double enables your class to use features without implementing the methods that a
MATLAB built-in class defines.
sc =
1x10 DocSimpleDouble:
double data:
1 2 3 4 5 6 7 8 9 10
Call a method inherited from class double that operates on the data, such as sum. sum returns a
double and, therefore, uses the display method of class double:
sum(sc)
ans =
55
Index sc like an array of doubles. The returned value is the class of the subclass:
a = sc(2:4)
a =
1x3 DocSimpleDouble:
12-44
Behavior of Inherited Built-In Methods
double data:
2 3 4
Indexed assignment works the same as the built-in class. The returned value is the class of the
subclass:
sc(1:5) = 5:-1:1
sc =
1x10 DocSimpleDouble:
double data:
5 4 3 2 1 6 7 8 9 10
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 =
1x10 DocSimpleDouble:
double data:
1 2 3 4 5 6 7 8 9 10
sc = DocSimpleDouble(1:10);
a = sin(sc);
class(a)
ans =
double
sc = DocSimpleDouble(randi(9,1,10))
sc = DocSimpleDouble(randi(9,1,10))
sc =
1x10 DocSimpleDouble:
double data:
6 1 8 9 7 7 7 4 6 2
b = sort(sc)
12-45
12 How to Build on Other Classes
b =
1x10 DocSimpleDouble:
double data:
1 2 4 6 6 7 7 7 8 9
• reshape
• permute
• sort
• transpose
• ctranspose
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
The value returned from an indexing operation is an object of the subclass. You cannot make indexed
references if your subclass defines properties, unless your subclass overrides the default subsref
method.
Assigning a new value to the second element in the DocSimpleDouble object operates only on the
superclass data:
sc(2) = 12
sc =
1x10 DocSimpleDouble:
double data:
1 12 3 4 5 6 7 8 9 10
12-46
Behavior of Inherited Built-In Methods
sc1 = DocSimpleDouble(1:10);
sc2 = DocSimpleDouble(11:20);
[sc1,sc2]
ans =
1x20 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
[sc1;sc2]
ans =
2x10 DocSimpleDouble:
double data:
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
c = cat(3,sc1,sc2)
c =
1x10x2 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
If the subclass of a built-in class defines properties, you cannot concatenate objects of the subclass.
There is no way to determine how to combine properties of different objects. However, your subclass
can define custom horzcat and vertcat methods to support concatenation in whatever way makes
sense for your subclass.
See Also
Related Examples
• “Subclasses of Built-In Types Without Properties” on page 12-48
• “Subclasses of Built-In Types with Properties” on page 12-54
12-47
12 How to Build on Other Classes
In this section...
“Specialized Numeric Types” on page 12-48
“A Class to Manage uint8 Data” on page 12-48
“Using the DocUint8 Class” on page 12-49
For more information, see “Subclasses of MATLAB Built-In Types” on page 12-41.
• Capability to convert various classes of image data to uint8 to reduce object data storage.
• A method to display the intensity images contained in the subclass objects.
• Ability to use all the methods supported by uint8 data (for example, size, indexing, reshape,
bitshift, cat, fft, arithmetic operators, and so on).
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:
12-48
Subclasses of Built-In Types Without Properties
The DocUint8 class provides a method to display all images stored as DocUint8 objects in a
consistent way. For example:
cir = imread('circuit.tif');
img1 = DocUint8(cir);
img1.showImage;
Because DocUint8 subclasses uint8, you can use any uint8 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.
Therefore, you can index into the image data and call a subclass method:
showImage(img1(100:200,1:160));
12-49
12 How to Build on Other Classes
Subscripted reference operations (controlled by the inherited subsref method) return a DocUint8
object.
img1(100:120,140:160) = 255;
img1.showImage;
12-50
Subclasses of Built-In Types Without Properties
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]);
12-51
12 How to Build on Other Classes
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, so calling showImage throws an error:
a = img1.*1.8;
showImage(a);
Check for missing argument or incorrect argument data type in call to function 'showImage'.
To perform operations of this type, implement a subclass method to override the inherited method.
The times method implements array (element-by-element) multiplication.
function o = times(obj,val)
u8 = uint8(obj).*val;
o = DocUint8(u8);
end
When you override a uint8 method, MATLAB calls the subclass method, not the base class method.
The subclass method must:
12-52
Subclasses of Built-In Types Without Properties
After adding the times method to the DocUint8 class, the output of multiplication expressions is an
object of the DocUint8 class:
showImage(img1.*1.8);
See Also
Related Examples
• “Operator Overloading” on page 18-38
• “Subclasses of Built-In Types with Properties” on page 12-54
12-53
12 How to Build on Other Classes
Providing additional data storage in the subclass by defining properties can be a useful extension to
the built-in data class. However, the addition of properties to the subclass requires the subclass to
define methods to implement standard array behaviors.
For more information, see “Subclasses of MATLAB Built-In Types” on page 12-41.
This sample implementation of the ExtendDouble class derives from the double class and defines a
single property. The ExtendDouble class definition demonstrates how to implement indexing and
concatenation for subclasses of built-in classes
Property Added
The ExtendDouble class defines the DataString property to contain text that describes the data.
The superclass part of the class contains the numeric data.
Methods Implemented
The following methods modify the behavior of the ExtendDouble class:
12-54
Subclasses of Built-In Types with Properties
• subsasgn — Enables subscripted assignment to the superclass part of the subclass, dot notation
reference to the DataString property, and dot notation reference the built-in data via the name
Data.
• horzcat — Defines horizontal concatenation of ExtendDouble objects. concatenates the
superclass part using the double class horzcat method and forms a cell array of the
DataString properties.
• vertcat — The vertical concatenation equivalent of horzcat (both are required).
• char — A ExtendDouble to char converter used by horzcat and vertcat.
• disp — ExtendDouble implements a disp method to provide a custom display for the object.
properties
DataString
end
methods
function obj = ExtendDouble(data,str)
if nargin == 0
data = 0;
str = '';
elseif nargin == 1
str = '';
end
obj = obj@double(data);
obj.DataString = str;
end
12-55
12 How to Build on Other Classes
end
end
function disp(obj)
disp(obj.DataString)
disp(double(obj))
end
end
end
Using ExtendDouble
Create an instance of ExtendDouble and notice that the display is different from the default:
12-56
Subclasses of Built-In Types with Properties
ed = ExtendDouble(1:10,'One to ten')
ed =
One to ten
1 2 3 4 5 6 7 8 9 10
Inherited Methods
The ExtendDouble class inherits methods from the class double. To see a list of all public methods
defined by the double class, use the methods function:
methods(double.empty)
The sum function continues to operate on the superclass part of the object:
sum(ed)
ans =
55
sort(ed(10:-1:1))
ans =
1 2 3 4 5 6 7 8 9 10
ed.^2
ans =
1 4 9 16 25 36 49 64 81 100
Subscripted Indexing
Because the ExtendDouble class defines a property, the class must implement its own subsref and
subsasgn methods.
This class implements the following subscripted indexing expressions for reference and assignment.
The class subsref method enables you to use ExtendDouble objects like numeric arrays to
reference the numeric data:
ed = ExtendDouble(1:10,'One to ten');
ed(10:-1:1)
ans =
12-57
12 How to Build on Other Classes
One to ten
10 9 8 7 6 5 4 3 2 1
Access the numeric data of the ExtendDouble using property-style indexing with the arbitrarily
chosen name Data:
ed.Data(10:-1:1)
ans =
One to ten
10 9 8 7 6 5 4 3 2 1
ans =
One to ten
One to thirteen'
1 2 3 4 5 6 7 8 9 10 11 12 13
The ExtendDouble inherits converter methods from the double class. For example, MATLAB calls
the char method to perform this assignment statement.
ed(11:13) = ['a','b','c']
ed =
one to thirteen
1 2 3 4 5 6 7 8 9 10 97 98 99
The ExtendDouble implements two forms of indexed reference in the subsref method:
a =
One to ten
1
b = ed.Data(1)
12-58
Subclasses of Built-In Types with Properties
b =
whos
The increased flexibility of the implementation of indexed reference in the ExtendDouble class.
hcat = [ed1,ed2]
hcat =
Columns 1 through 13
1 2 3 4 5 6 7 8 9 10 10 9 8
Columns 14 through 20
7 6 5 4 3 2 1
whos
vcat = [ed1;ed2]
vcat =
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.
12-59
12 How to Build on Other Classes
See Also
Related Examples
• “Subclasses of Built-In Types Without Properties” on page 12-48
12-60
Use of size and numel with Classes
The size and numel functions work consistently with arrays of user-defined objects. There is
generally no need to overload size or numel in user-defined classes.
Several MATLAB functions use size and numel to perform their operations. Therefore, if you do
overload either of these functions in your class, be sure that objects of your class work as designed
with other MATLAB functions.
If your class modifies array indexing, see “Overload numArgumentsFromSubscript Instead of numel”
on page 12-65
d = 1:10;
size(d)
ans =
1 10
numel(d)
ans =
10
dsub = d(7:end);
size(dsub)
ans =
1 4
12-61
12 How to Build on Other Classes
sd = SimpleDouble(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])
ans =
2 10
numel([sd;sd])
ans =
20
The SimpleDouble class inherits the indexing behavior of the double class:
sdsub = sd(7:end);
size(sdsub)
12-62
Use of size and numel with Classes
ans =
1 4
classdef VerySimpleClass
properties
Value
end
end
vs = VerySimpleClass;
vs.Value = 1:10;
size(vs)
ans =
1 1
numel(vs)
ans =
size([vs;vs])
ans =
2 1
numel([vs;vs])
ans =
size(vs.Value)
ans =
1 10
vssub = vs.Value(7:end);
size(vssub)
ans =
1 4
12-63
12 How to Build on Other Classes
class(vs.Value)
ans =
double
vsArray(1:10) = VerySimpleClass;
isempty([vsArray(2:10).Value])
ans =
MATLAB does not apply scalar expansion to object array property value assignment. Use the deal
function for this purpose:
[vsArray.Value] = deal(1:10);
isempty([vsArray.Value])
ans =
The deal function assigns values to each Value property in the vsArray object array.
Indexing rules for object arrays are equivalent to the rules for arrays of struct:
vsArray(1).Value
ans =
1 2 3 4 5 6 7 8 9 10
vsArray(1).Value(6)
ans =
Other MATLAB functions use the values returned by these functions. If you change the way that size
and numel behave, ensure that the values returned make sense for the intended use of your class.
12-64
Use of size and numel with Classes
A(1:2).Prop
Subclasses of built-in classes always return scalar objects as a result of subscripted reference and
always use scalar objects for subscripted assignment.
If you define a class in which nargout for subsref or nargin for subsasgn must be a specific
value, then overload numArgumentsFromSubscript to return that value.
See Also
numArgumentsFromSubscript
Related Examples
• “Modify nargout and nargin for Indexing Methods” on page 18-7
12-65
12 How to Build on Other Classes
Objective
This example implements a class to represent an optical multiplex card. These cards typically have
several input ports and an output port. The MuxCard class represents the ports by the port names
and port data rates. The output rate of a multiplex card is the sum of the input port data rates.
Implementation
Here is the definition of the MuxCard class. Notice that the input port rates initialize the int32
portion of class.
methods
function obj = MuxCard(inptnames, inptrates, outpname)
obj = obj@int32(inptrates);
obj.InPutNames = inptnames;
obj.OutPutName = outpname;
end
function x = get.OutPutRate(obj)
x = sum(obj);
end
function x = subsref(card, s)
if strcmp(s(1).type,'.')
base = subsref@int32(card, s(1));
12-66
Representing Hardware with Classes
if isscalar(s)
x = base;
else
x = subsref(base, s(2:end));
end
else
x = subsref(int32(card), s);
end
end
end
end
omx =
int32 data:
3 12 12 48
ans =
'inp2' 'inp3'
ans =
0 1 1 0
Indexing the MuxCard object accesses the int32 vector of input port rates:
omx(1:2)
ans =
3 12
12-67
12 How to Build on Other Classes
The OutPutRate property get access method uses sum to sum the output port rates:
omx.OutPutRate
ans =
75
See Also
Related Examples
• “Subclasses of Built-In Types with Properties” on page 12-54
12-68
Determine Array Class
a = [2,5,7,11];
class(a)
ans =
double
ans =
char
a = [2,5,7,11];
isa(a,'double')
ans =
1
isa(a,'float')
ans =
1
isa(a,'numeric')
ans =
1
isa returns true for classes derived from the specified class. For example, the SubInt class derives
from the built-in type int16:
12-69
12 How to Build on Other Classes
By definition, an instance of the SubInt class is also an instance of the int16 class:
aInt = SubInt;
isa(aInt,'int16')
ans =
1
isa(aInt,'integer')
ans =
1
class(aInt)
ans =
SubInt
Use the strcmp function with the class function to check for a specific class of an object:
a = int16(7);
strcmp(class(a),'int16')
ans =
1
Because the class function returns the class name as a char vector, the inheritance does not affect
the result of the comparison performed by strcmp:
aInt = SubInt;
strcmp(class(aInt),'int16')
ans =
0
12-70
Determine Array Class
Use the following techniques to exclude subclasses of built-in types from the input arguments.
• Define a cell array that contains the names of built-in types accepted by your function.
• Call class and strcmp to test for specific types in a MATLAB control statement.
if strcmp(class(inputArg),'single')
% Call function
else
inputArg = single(inputArg);
end
Suppose that you create a MEX-function, myMexFcn, that requires two numeric inputs that must be of
type double or single:
outArray = myMexFcn(a,b)
Define a cell array that contains the character arrays double and single:
floatTypes = {'double','single'};
Use isobject to separate built-in types from subclasses of built-in types. The isobject function
returns false for instances of built-in types:
ans =
0
12-71
12 How to Build on Other Classes
Abstract Classes
Abstract classes are useful for describing functionality that is common to a group of classes, but
requires unique implementations within each class.
abstract class — A class that cannot be instantiated, but that defines class components used by
subclasses.
concrete class — A class that can be instantiated. Concrete classes contain no abstract members.
interface — An abstract class describing functionality that is common to a group of classes, but that
requires unique implementations within each class. The abstract class defines the interface of each
subclass without specifying the actual implementation.
An abstract class serves as a basis (that is, a superclass) for a group of related subclasses. An
abstract class can define abstract properties and methods that subclasses implement. Each subclass
can implement the concrete properties and methods in a way that supports their specific
requirements.
A subclass must implement all inherited abstract properties and methods to become a concrete class.
Otherwise, the subclass is itself an abstract class.
MATLAB does not force subclasses to implement concrete methods with the same signature or
attributes.
Abstract classes:
12-72
Abstract Classes and Class Members
If a subclass of an abstract class does not define concrete implementations for all inherited abstract
methods or properties, it is also abstract.
Abstract Class
• Concrete subclasses must redefine any properties or methods that are declared as abstract.
• The abstract class does not need to define any abstract methods or properties.
When you define any abstract methods or properties, MATLAB automatically sets the class Abstract
attribute to true.
Abstract Methods
methods (Abstract)
abstMethod(obj)
end
• Do not use a function...end block to define an abstract method, use only the method
signature.
• Abstract methods have no implementation in the abstract class.
• Concrete subclasses are not required to support the same number of input and output arguments
and do not need to use the same argument names. However, subclasses generally use the same
signature when implementing their version of the method.
• Abstract methods cannot define arguments blocks.
Abstract Properties
properties (Abstract)
AbsProp
end
• Concrete subclasses must redefine abstract properties without the Abstract attribute.
• Concrete subclasses must use the same values for the SetAccess and GetAccess attributes as
those attributes used in the abstract superclass.
12-73
12 How to Build on Other Classes
• Abstract properties cannot define access methods and cannot specify initial values. The subclass
that defines the concrete property can create access methods and specify initial values.
For more information on access methods, see “Property Access Methods” on page 8-39.
classdef AbsClass
methods(Abstract)
result = absMethodOne(obj)
output = absMethodTwo(obj)
end
end
Use the logical value of the meta.class Abstract property to determine if the class is abstract:
mc = ?AbsClass;
if ~mc.Abstract
% not an abstract class
end
Use the meta.abstractDetails function to display the names of abstract properties or methods
and the names of the defining classes:
meta.abstractDetails('AbsClass');
For example, suppose that you create a subclass of the AbsClass class that is defined in the previous
section. In this case, the subclass implements only one of the abstract methods defined by AbsClass.
12-74
Abstract Classes and Class Members
meta.abstractDetails(?SubAbsClass)
The SubAbsClass class is abstract because it has not implemented the absMethodOne method
defined in AbsClass.
msub = ?SubAbsClass;
msub.Abstract
ans =
If you implement both methods defined in AbsClass, the subclass becomes concrete.
See Also
Related Examples
• “Define an Interface Superclass” on page 12-76
12-75
12 How to Build on Other Classes
Interfaces
The properties and methods defined by a class form the interface that determines how class users
interact with objects of the class. When creating a group of related classes, interfaces define a
common interface to all these classes. The actual implementations of the interface can differ from one
class to another.
Consider a set of classes designed to represent various types of graphs. All classes 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. Each class can implement the Data property
differently.
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.
The basic idea of an interface class is to specify the properties and methods that each subclass must
implement without defining the actual implementation. This approach enables you to enforce a
consistent interface to a group of related objects. As you add more classes in the future, the interface
remains the same.
This approach enforces the use of a consistent interface while providing the necessary flexibility to
implement the internal workings of each specialized subclass differently.
In this example, a package folder contains the interface, derived subclasses, and a utility function:
+graphics/GraphInterface.m % abstract interface class
+graphics/LineGraph.m % concrete subclass
The graph class specifies the following properties, which the subclasses must define:
• Primitive — Handle of the graphics object used to implement the specialized graph. The class
user has no need to access these objects directly so this property has protected SetAccess and
GetAccess.
• AxesHandle — Handle of the axes used for the graph. The specialized graph objects can set axes
object properties. This property has protected SetAccess and GetAccess.
• Data — All subclasses of the GraphInterface class must store data. The type of data varies and
each subclass defines the storage mechanism. Subclass users can change the data values so this
property has public access rights.
12-76
Define an Interface Superclass
The GraphInterface class names three abstract methods that subclasses must implement. The
GraphInterface class also suggests in comments that each subclass constructor must accept the
plot data and property name/property value pairs for all class properties.
• Subclass constructor — Accept data and P/V pairs and return an object.
• draw — Used to create a drawing primitive and render a graph of the data according to the type
of graph implemented by the subclass.
• zoom — Implementation of a zoom method by changing the axes CameraViewAngle property. The
interface suggests the use of the camzoom function for consistency among subclasses. The zoom
buttons created by the addButtons static method use this method as a callback.
• updateGraph — Method called by the set.Data method to update the plotted data whenever the
Data property changes.
The package of classes that derive from the GraphInterface abstract class implement the following
behaviors:
The GraphInterface class is an abstract class that defines the methods and properties used by the
subclasses. Comments in the abstract class describe the intended implementation:
12-77
12 How to Build on Other Classes
end
methods
function set.Data(obj,newdata)
obj.Data = newdata;
updateGraph(obj)
end
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
end
end
The GraphInterface 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. The
GraphInterface class defines a set access method that calls an abstract method (updateGraph,
which each subclass must implement). The GraphInterface interface imposes a specific design on
the whole package of classes, without limiting flexibility.
The addButtons method adds push buttons for the zoom methods, which each subclass must
implement. Using a method instead of an ordinary function enables addButtons to access the
protected class data (the axes handle). Use the object zoom method as the push-button callback.
function addButtons(gobj)
hfig = get(gobj.AxesHandle,'Parent');
uicontrol(hfig,'Style','pushbutton',...
'String','Zoom Out',...
'Callback',@(src,evnt)zoom(gobj,.5));
uicontrol(hfig,'Style','pushbutton',...
'String','Zoom In',...
'Callback',@(src,evnt)zoom(gobj,2),...
'Position',[100 20 60 20]);
end
This example defines only a single subclass used to represent a simple line graph. It derives from
GraphInterface, but provides implementations for the abstract methods draw, zoom,
updateGraph, and its own constructor. The base class GraphInterface and subclass are all
contained in a package (graphics), which you must use to reference the class name:
classdef LineGraph < graphics.GraphInterface
Add Properties
The LineGraph class implements the interface defined in the GraphInterface 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.
12-78
Define an Interface Superclass
properties
LineColor = [0 0 0];
LineType = '-';
end
The constructor accepts a struct with x and y coordinate data, and property name/property value
pairs:
function gobj = LineGraph(data,varargin)
if nargin > 0
gobj.Data = data;
if nargin > 2
for k=1:2:length(varargin)
gobj.(varargin{k}) = varargin{k+1};
end
end
end
end
The LineGraph draw method uses property values to create a line object. The LineGraph class
stores the line handle as protected class data. To support the use of no input arguments for the
class constructor, draw checks the Data property to determine if it is empty before proceeding:
function gobj = draw(gobj)
if isempty(gobj.Data)
error('The LineGraph object contains no data')
end
h = line(gobj.Data.x,gobj.Data.y,...
'Color',gobj.LineColor,...
'LineStyle',gobj.LineType);
gobj.Primitive = h;
gobj.AxesHandle = get(h,'Parent');
end
The LineGraph zoom method follows the comments in the GraphInterface class which suggest
using the camzoom function. camzoom provides a convenient interface to zooming and operates
correctly with the push buttons created by the addButtons method.
Property set methods provide a convenient way to execute code automatically when the value of a
property changes for the first time in a constructor. (See “Property Set Methods” on page 8-44.) The
linegraph class uses set methods to update the line primitive data (which causes a redraw of the
plot) whenever a property value changes. The use of property set methods provides a way to update
the data plot quickly without requiring a call to the draw method. The draw method updates the plot
by resetting all values to match the current property values.
Three properties use set methods: LineColor, LineType, and Data. LineColor and LineType are
properties added by the LineGraph class and are specific to the line primitive used by this class.
Other subclasses can define different properties unique to their specialization (for example,
FaceColor).
12-79
12 How to Build on Other Classes
The GraphInterface class implements the Data property set method. However, the
GraphInterface class requires each subclass to define a method called updateGraph, which
handles the update of plot data for the specific drawing primitive used.
methods
function gobj = LineGraph(data,varargin)
if nargin > 0
gobj.Data = data;
if nargin > 1
for k=1:2:length(varargin)
gobj.(varargin{k}) = varargin{k+1};
end
end
end
end
function zoom(gobj,factor)
camzoom(gobj.AxesHandle,factor)
end
function updateGraph(gobj)
set(gobj.Primitive,...
'XData',gobj.Data.x,...
'YData',gobj.Data.y)
end
function set.LineColor(gobj,color)
gobj.LineColor = color;
set(gobj.Primitive,'Color',color)
end
function set.LineType(gobj,ls)
gobj.LineType = ls;
set(gobj.Primitive,'LineStyle',ls)
end
end
end
12-80
Define an Interface Superclass
The LineGraph class defines the simple API specified by the graph base class and implements its
specialized type of graph:
d.x = 1:10;
d.y = rand(10,1);
lg = graphics.LineGraph(d,'LineColor','b','LineType',':');
lg.draw;
lg.addButtons;
Clicking the Zoom In button shows the zoom method providing the callback for the button.
d.y = rand(10,1);
lg.Data = d;
lg.LineColor = [0.9,0.1,0.6];
12-81
12 How to Build on Other Classes
See Also
Related Examples
• “Abstract Classes and Class Members” on page 12-72
12-82
13
• The full name of the object class, including any package qualifiers
• Values of dynamic properties
• All property default values defined by the class at the time the first object of the class is saved to
the MAT-file.
• The names and values of all properties, with the following exceptions:
• Properties are not saved if their current values are the same as the default values specified in
the class definition.
• Properties are not saved if their Transient, Constant, or Dependent attributes set to true.
For a description of property attributes, see “Specify Property Attributes” on page 8-5
Note Do not use the pack command with objects that define events and listeners. The pack
command causes the destruction of any listeners defined for the objects in the workspace. For
information on restoring listeners when saving objects, see “Restore Listeners” on page 13-26.
13-2
Save and Load Process for Objects
• load assigns the default values saved in the MAT-file to properties whose values were not saved
because the properties were set to the default values when saved. These assignments result in
calls to property set methods defined by the class.
MATLAB calls property set methods to ensure that property values are still valid in cases where the
class definition has changed.
For information on property set methods, see “Property Set Methods” on page 8-44.
When an error occurs while an object is being loaded from a file, MATLAB does one of the following:
• If the class defines a loadobj method, MATLAB returns the saved values to the loadobj method
in a struct.
• If the class does not define a loadobj method, MATLAB silently ignores the errors. The load
function reconstitutes the object with property values that do not produce an error.
In the struct passed to the loadobj method, the field names correspond to the property names.
The field values are the saved values for the corresponding properties.
If the saved object derives from multiple superclasses that have private properties with same name,
the struct contains only the property value of the most direct superclass.
For information on how to implement saveobj and loadobj methods, see “Modify the Save and
Load Process” on page 13-12.
If a class definition changes property validation such that loaded property values are no longer valid,
MATLAB substitutes the currently defined default value for that property. The class can define a
loadobj method or converter methods to provide compatibility among class versions.
For information on property validation, see “Validate Property Values” on page 8-20
See Also
Related Examples
• “Object Save and Load”
13-3
13 Saving and Loading Objects
In this section...
“Default Values” on page 13-4
“Dependent Properties” on page 13-4
“Transient Properties” on page 13-4
“Avoid Saving Unwanted Variables” on page 13-4
Default Values
If a property often has the same value, define a default value for that property. When the user saves
the object to a MAT-file, MATLAB does not save the value of a property if the current value equals the
default value. MATLAB saves the default value on a per class basis to avoid saving the value for every
object.
For more information on how MATLAB evaluates default value expressions, see “Property Default
Values” on page 8-14.
Dependent Properties
Use a dependent property when the property value must be calculated at run time. A dependent
property is not saved in the MAT-file when you save an object. Instances of the class do not allocate
memory to hold a value for a dependent property.
Dependent is a property attribute (see “Property Attributes” on page 8-7 for a complete list.)
Transient Properties
MATLAB does not store the values of transient properties. Transient properties can store data in the
object temporarily as an intermediate computation step or for faster retrieval. Use transient
properties when you easily can reproduce the data at run time or when the data represents
intermediate state that can be discarded.
See Also
Related Examples
• “Modify the Save and Load Process” on page 13-12
• “Object Save and Load”
13-4
Save Object Data to Recreate Graphics Objects
What to Save
Use transient properties to avoid saving what you can recreate when loading the object. For example,
an object can contain component parts that you can regenerate from data that is saved. Regenerating
these components also enables newer versions of the class to create the components in a different
way.
The Chart property contains the handle to the bar chart. When you save a bar chart, MATLAB also
saves the figure, axes, and Bar object and the data required to create these graphics objects. The
YearlyRainfall class design eliminates the need to save objects that it can regenerate:
• The Chart property is Transient so the graphics objects are not saved.
• ChartData is a private property that provides storage for the Bar object data (YData).
• The load function calls the set.ChartData method, passing it the saved bar chart data.
• The setup method regenerates the bar chart and assigns the handle to the Chart property. Both
the class constructor and the set.ChartData method call setup.
13-5
13 Saving and Loading Objects
end
end
methods(Access = private)
function setup(rf,data)
rf.Chart = bar(data);
end
end
end
For example, change the type of graph from a bar chart to a stair-step graph by modifying the setup
method:
methods(Access = private)
function setup(rf,data)
rf.Chart = stairs(data);
end
end
See Also
Related Examples
• “Modify the Save and Load Process” on page 13-12
• “Object Save and Load”
13-6
Improve Version Compatibility with Default Values
Version Compatibility
Default property values can help you implement version compatibility for saved objects. For example,
suppose that you add a property to version 2 of your class. Having a default value enables MATLAB to
assign a value to the new property when loading a version 1 object.
Similarly, suppose version 2 of your class removes a property. If a version 2 object is saved and loaded
into version 1, your loadobj method can use the default value from version 1.
classdef EmployeeInfo
properties
Name
JobTitle
Department
end
end
Version 2 of the EmployeeInfo class adds a property, Country, for the country name of the
employee location. The Country property has a default value of 'USA'.
classdef EmployeeInfo
properties
Name
JobTitle
Department
Country = 'USA'
end
end
• MATLAB assigns an empty double [] to properties that do not have default values defined by the
class. Empty double is not a valid value for the Country property.
• In version 1, all employees were in the USA. Therefore, any version 1 object loaded into version 2
receives a valid value for the Country property.
13-7
13 Saving and Loading Objects
See Also
Related Examples
• “Modify the Save and Load Process” on page 13-12
• “Object Save and Load”
13-8
Avoid Property Initialization Order Dependency
Suppose that your class design is such that both of the following are true:
Then the final state of an object after changing a series of property values can depend on the order in
which you set the properties. This order dependency can affect the result of loading an object.
The load function sets property values in a particular order. This order can be different from the
order in which you set the properties in the saved object. As a result, the loaded object can have
different property values than the object had when it was saved.
If a property set function changes the values of other properties, then define the Dependent
attribute of that property as true. MATLAB does not save or restore dependent property values.
Use nondependent properties for storing the values set by the dependent property. Then the load
function restores the nondependent properties with the same values that were saved. The load
function does not call the dependent property set method because there is no value in the saved file
for that property.
• The Units property is dependent. Its property set method sets the TotalDistance property.
Therefore load does not call the Units property set method.
• The load function restores TotalDistance to whatever value it had when you saved the object.
classdef Odometer
properties(Constant)
ConversionFactor = 1.6
end
properties
TotalDistance = 0
end
properties(Dependent)
Units
13-9
13 Saving and Loading Objects
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 char vector
switch(newUnits)
case 'mi'
if strcmp(obj.PrivateUnits,'km')
obj.TotalDistance = obj.TotalDistance / ...
obj.ConversionFactor;
obj.PrivateUnits = newUnits;
end
case 'km'
if strcmp(obj.PrivateUnits,'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
Suppose that you create an instance of Odometer and set the following property values:
odObj = Odometer;
odObj.Units = 'km';
odObj.TotalDistance = 16;
If the Units property was not Dependent, loading it calls its set method and causes the
TotalDistance property to be set again.
13-10
Avoid Property Initialization Order Dependency
The class avoids order dependence when initializing property values during the load process by
making the TripDistance property dependent. MATLAB does not save or load a value for the
TripDistance property, but does save and load values for the two properties used to calculate
TripDistance in its property get method.
classdef Odometer2
properties
TotalDistance = 0
TripMarker = 0
end
properties(Dependent)
TripDistance
end
methods
function distance = get.TripDistance(obj)
distance = obj.TotalDistance - obj.TripMarker;
end
end
end
See Also
Related Examples
• “Modify the Save and Load Process” on page 13-12
• “Object Save and Load”
13-11
13 Saving and Loading Objects
• Rename a class
• Remove properties
• Define a circular reference of handle objects where initialization order is important
• Must call the constructor with arguments and, therefore, cannot use ConstructOnLoad
The save function calls your class saveobj method before performing the save operation. The save
function then saves the value returned by the saveobj method. You can use saveobj to return a
modified object or a struct that contains property values.
load calls your class loadobj method after loading the object. The load function loads the value
returned by the loadobj method into the workspace. A loadobj method can modify the object being
loaded or can reconstruct an object from the data saved by the class saveobj method.
Implement the loadobj method as a Static method because MATLAB can call the loadobj method
with a struct instead of an object of the class.
Implement the saveobj method as an ordinary method (that is, calling it requires an instance of the
class).
MATLAB saves the object class name so that load can determine which loadobj method to call in
cases where your saveobj method saves only the object data in a structure. Therefore, the class
must be accessible to MATLAB when you load the object.
13-12
Modify the Save and Load Process
• The class definition has changed since the object was saved, requiring you to modify the object
before loading.
• A saveobj method modified the object during the save operation, possibly saving data in a
struct. Implement the loadobj method to reconstruct the object from the output of saveobj.
Additional Considerations
When you decide to modify the default save and load process, keep the following points in mind:
• If loading any property value from the MAT-file produces an error, load passes a struct to
loadobj. The struct field names correspond to the property names extracted from the file.
• loadobj must always be able to accept a struct as input and return an object, even if there is
no saveobj or saveobj does not return a struct.
• If saveobj returns a struct, then load always passes that struct to loadobj.
• Subclass objects inherit superclass loadobj and saveobj methods. Therefore, if you do not
implement a loadobj or saveobj method in the subclass, MATLAB calls only the inherited
methods.
If a superclass implements a loadobj or saveobj method, then a subclass can also implement a
loadobj or saveobj method that calls the superclass methods. For more information, see “Save
and Load Objects from Class Hierarchies” on page 13-24.
• The load function does not call the constructor by default. For more information, see “Initialize
Objects When Loading” on page 13-22.
See Also
Related Examples
• “Basic saveobj and loadobj Pattern” on page 13-14
• “Object Save and Load”
13-13
13 Saving and Loading Objects
• Use saveobj to save all essential data in a struct and do not save the entire object.
• Use loadobj to reconstruct the object from the saved data.
This approach is not useful in cases where you cannot save property values in a struct field. Data
that you cannot save, such as a file identifier, you can possibly regenerate in the loadobj method.
If you implement a saveobj method without implementing a loadobj method, MATLAB loads a
default object of the class using the current class definition. Add a loadobj method to the class to
create an object using the data saved with the saveobj method.
saveobj
For this pattern, define saveobj as an ordinary method that accepts an object of the class and
returns a struct.
methods
function s = saveobj(obj)
s.Prop1 = obj.Prop1;
s.Prop2 = obj.Prop2
s.Data = obj.GraphHandle.YData;
end
end
loadobj
Define loadobj as a static method. Create an object by calling the class constructor. Then assign
values to properties from the struct passed to loadobj. Use the data to regenerate properties that
were not saved.
methods(Static)
function obj = loadobj(s)
if isstruct(s)
newObj = ClassConstructor;
newObj.Prop1 = s.Prop1;
newObj.Prop2 = s.Prop2
13-14
Basic saveobj and loadobj Pattern
newObj.GraphHandle = plot(s.Data);
obj = newObj;
else
obj = s;
end
end
end
If the load function encounters an error, load passes loadobj a struct instead of an object. Your
loadobj method must always be able to handle a struct as the input argument. The input to
loadobj is always a scalar.
The GraphExpression class creates a graph of a MATLAB expression over a specified range of data.
GraphExpression uses its loadobj method to regenerate the graph, which is not saved with the
object.
classdef GraphExpression
properties
FuncHandle
Range
end
methods
function obj = GraphExpression(fh,rg)
obj.FuncHandle = fh;
obj.Range = rg;
makeGraph(obj)
end
function makeGraph(obj)
rg = obj.Range;
x = min(rg):max(rg);
data = obj.FuncHandle(x);
plot(data)
end
end
methods (Static)
function obj = loadobj(s)
if isstruct(s)
fh = s.FuncHandle;
rg = s.Range;
obj = GraphExpression(fh,rg);
else
makeGraph(s);
obj = s;
end
end
end
end
13-15
13 Saving and Loading Objects
h =
FuncHandle: @(x)x.^4
Range: [1x25 double]
save myFile h
close
load myFile h
If the load function cannot create the object and passes a struct to loadobj, loadobj attempts to
create an object with the data supplied.
See Also
Related Examples
• “Modify the Save and Load Process” on page 13-12
• “Object Save and Load”
13-16
Maintain Class Compatibility
Rename Property
Suppose that you want to rename a property, but do not want to cause errors in existing code that
refer to the original property. For example, rename a public property called OfficeNumber to
Location. Here is the original class definition:
classdef EmployeeList
properties
Name
Email
OfficeNumber % Rename as Location
end
end
• In the class definition, set the OfficeNumber property attributes to Dependent and Hidden.
• Create a property set method for OfficeNumber that sets the value of the Location property.
• Create a property get method for OfficeNumber that returns the value of the Location location
property.
While the OfficeNumber property is hidden, existing code can continue to access this property. The
Hidden attribute does not affect access.
Because OfficeNumber is dependent, there is no redundancy in storage required by adding the new
property. MATLAB does not store or save dependent properties.
13-17
13 Saving and Loading Objects
end
end
You can load old instances of the EmployeeList class in the presence of the new class version. Code
that refers to the OfficeNumber property continues to work.
Suppose that you want to be able to load new EmployeeList objects into systems that still have the
old version of the EmployeeList class. To achieve compatibility with old and new versions:
In this version of the EmployeeList class, the OfficeNumber property saves the value used by the
Location property. Loading an object assigns values of the three original properties (Name, Email,
and OfficeNumber), but does not assign a value to the new Location property. The lack of the
Location property in the old class definition is not a problem.
classdef EmployeeList
properties
Name
Email
end
properties (Dependent)
Location
end
properties (Hidden)
OfficeNumber
end
methods
function obj = set.Location(obj,val)
obj.OfficeNumber = val;
end
function val = get.Location(obj)
val = obj.OfficeNumber;
end
end
end
Consider a class that has an AccountID property. Suppose that all account numbers must migrate
from eight-digit numeric values to 12-element character arrays.
• Tests to determine if the load function passed a struct or object. All loadobj methods must
handle both struct and object when there is an error in load.
13-18
Maintain Class Compatibility
• Tests to determine if the AccountID number contains eight digits. If so, change it to a 12-element
character array by calling the paddAccID method.
After updating the AccountID property, loadobj returns a MyAccount object that MATLAB loads
into the workspace.
classdef MyAccount
properties
AccountID
end
methods
function obj = padAccID(obj)
ac = obj.AccountID;
acstr = num2str(ac);
if length(acstr) < 12
obj.AccountID = [acstr,repmat('0',1,12-length(acstr))];
end
end
end
methods (Static)
function obj = loadobj(a)
if isstruct(a)
obj = MyAccount;
obj.AccountID = a.AccountID;
obj = padAccID(obj);
elseif isa(a,'MyAccount')
obj = padAccID(a);
end
end
end
end
You do not need to implement a saveobj method. You are using loadobj only to ensure that older
saved objects are brought up to date while loading.
Suppose that you define a class to represent an entry in a phone book. The PhoneBookEntry class
defines three properties: Name, Address, and PhoneNumber.
classdef PhoneBookEntry
properties
Name
Address
PhoneNumber
end
end
However, in future releases, the class adds more properties. To provide flexibility, PhoneBookEntry
saves property data in a struct using its saveobj method.
methods
function s = saveobj(obj)
s.Name = obj.Name;
13-19
13 Saving and Loading Objects
s.Address = obj.Address;
s.PhoneNumber = obj.PhoneNumber;
end
end
The loadobj method creates the PhoneBookEntry object, which is then loaded into the workspace.
methods (Static)
function obj = loadobj(s)
if isstruct(s)
newObj = PhoneBookEntry;
newObj.Name = s.Name;
newObj.Address = s.Address;
newObj.PhoneNumber = s.PhoneNumber;
obj = newObj;
else
obj = s;
end
end
end
With these changes, you could not load a version 2 object in a previous release. However, version 2
employs several techniques to enable compatibility:
• Preserve the Address property (which is used in version 1) as a Dependent property with private
SetAccess.
• Define an Address property get method (get.Address) to build a char vector that is compatible
with the version 2 Address property.
• The saveobj method invokes the get.Address method to assign the object data to a struct
that is compatible with previous versions. The struct continues to have only an Address field
built from the data in the new StreetAddress, City, State, and ZipCode properties.
• When the loadobj method sets the Address property, it invokes the property set method
(set.Address), which extracts the substrings required by the StreetAddress, City, State,
and ZipCode properties.
• The Transient (not saved) property SaveInOldFormat enables you to specify whether to save
the version 2 object as a struct or an object.
classdef PhoneBookEntry
properties
Name
StreetAddress
City
State
ZipCode
PhoneNumber
end
properties (Constant)
Sep = ', '
end
13-20
Maintain Class Compatibility
See Also
Related Examples
• “Modify the Save and Load Process” on page 13-12
• “Object Save and Load”
13-21
13 Saving and Loading Objects
Enable ConstructOnLoad when you do not want to implement a loadobj method, but must
perform some actions at construction time. For example, enable ConstructOnLoad when you are
registering listeners for another object. Ensure that MATLAB can call the class constructor with no
arguments without generating an error.
Attributes set on superclasses are not inherited by subclasses. Therefore, MATLAB does not use the
value of the superclass ConstructOnLoad attribute when loading objects. If you want MATLAB to
call the class constructor, set the ConstructOnLoad attribute in your specific subclass.
The LabResults class shares the constructor object initialization steps with the loadobj method by
performing these steps in the assignStatus method.
classdef LabResult
properties
CurrentValue
end
properties (Transient)
Status
end
methods
function obj = LabResult(cv)
obj.CurrentValue = cv;
obj = assignStatus(obj);
end
function obj = assignStatus(obj)
v = obj.CurrentValue;
if v < 10
obj.Status = 'Too low';
13-22
Initialize Objects When Loading
The LabResults class uses loadobj to determine the status of a given test value. This approach
provides a way to:
See Also
Related Examples
• “Modify the Save and Load Process” on page 13-12
• “Object Save and Load”
13-23
13 Saving and Loading Objects
• Superclasses implement saveobj methods to save their property data in the struct.
• The subclass saveobj method calls each superclass saveobj method and returns the completed
struct to the save function. Then the save function writes the struct to the MAT-file.
• The subclass loadobj method creates a subclass object and calls superclass methods to assign
their property values in the subclass object.
• The subclass loadobj method returns the reconstructed object to the load function, which loads
the object into the workspace.
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
properties
X
Y
end
methods
13-24
Save and Load Objects from Class Hierarchies
function S = saveobj(obj)
S.PointX = obj.X;
S.PointY = obj.Y;
end
function obj = reload(obj,S)
obj.X = S.PointX;
obj.Y = S.PointY;
end
end
methods (Static)
function obj = loadobj(S)
if isstruct(s)
obj = MySuper;
obj = reload(obj,S);
end
end
end
end
Call the superclass saveobj and loadobj methods from the subclass saveobj and loadobj
methods.
See Also
Related Examples
• “Modify the Save and Load Process” on page 13-12
• “Object Save and Load”
13-25
13 Saving and Loading Objects
Restore Listeners
In this section...
“Create Listener with loadobj” on page 13-26
“Use Transient Property to Load Listener” on page 13-26
“Using the BankAccount and AccountManager Classes” on page 13-27
When the AccountBalance property value changes, the listener callback determines the account
status. Important points include:
• The BankAccount class defines the AccountManagerListener property to contain the listener
handle. This property enables the loadobj method to create a listener and return a reference to
it in the object that is loaded into the workspace.
• The AccountManagerListener property is Transient because there is no need to store the
listener handle with a BankAccount object. Create a listener that is attached to the new
BankAccount object created during the load process.
• The AccountBalance listener sets the AccountStatus.
• Only the AccountManager class can access AccountStatus property.
13-26
Restore Listeners
else
obj.AccountManagerListener = AccountManager.addAccount(obj);
end
end
end
end
Assume the AccountManager class provides services for various types of accounts. For the
BankAccount class, the AccountManager class defines two Static methods:
• assignStatus — Callback for the AccountBalance property PostSet listener. This method
determines the value of the BankAccount AccountStatus property.
• addAccount — Creates the AccountBalance property PostSet listener. The BankAccount
constructor and loadobj methods call this method.
classdef AccountManager
methods (Static)
function assignStatus(BA,~)
if BA.AccountBalance < 0 && BA.AccountBalance >= -100
BA.AccountStatus = 'overdrawn';
elseif BA.AccountBalance < -100
BA.AccountStatus = 'frozen';
else
BA.AccountStatus = 'open';
end
end
function lh = addAccount(BA)
lh = addlistener(BA,'AccountBalance','PostSet', ...
@(src,evt)AccountManager.assignStatus(BA));
end
end
end
ba = BankAccount(100)
ba =
AccountBalance: 100
AccountManagerListener: [1x1 event.proplistener]
AccountStatus: 'New Account'
Now set an account value to confirm that the AccountManager sets AccountStatus appropriately:
ba.AccountBalance = -10;
ba.AccountStatus
ans =
overdrawn
13-27
13 Saving and Loading Objects
See Also
Related Examples
• “Modify the Save and Load Process” on page 13-12
• “Property Attributes” on page 8-7
• “Listen for Changes to Property Values” on page 11-32
• “Object Save and Load”
13-28
14
Enumerations
Named Values
In this section...
“Kinds of Predefined Names” on page 14-2
“Techniques for Defining Enumerations” on page 14-2
• 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 “Define Class Properties with Constant Values” on page 15-2 for more information.
Enumerations
Use enumerations when you want to create a fixed set of names representing a single type of value.
Use this new type in multiple places without redefining it for each class.
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 the mathematical and relational operations that MATLAB
defines for those classes.
Using enumerations instead of character strings to represent a value, such as colors ('red'), can
result in more readable code because:
14-2
Named Values
You can define enumeration classes in ways that are most useful to your application, as described in
the following sections.
Simple enumeration classes have no superclasses and no properties. These classes define a set of
related names that have no underlying values associated with them. Use this kind of enumeration
when you want descriptive names, but your application does not require specific information
associated with the name.
See the WeekDays class in the “Enumeration Class” on page 14-4 and the “Define Methods in
Enumeration Classes” on page 14-5 sections.
Enumeration classes that subclass MATLAB built-in classes inherit most of the behaviors of those
classes. For example, an enumeration class derived from the double class inherits the mathematical,
relational, and set operations that work with variables of the class.
Enumerations do not support the colon (:) operator, even if the superclass does.
Enumeration classes that do not subclass MATLAB built-in numeric and logical classes can define
properties. These classes can define constructors that set each member's unique property values.
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
See Also
Related Examples
• “Enumeration Class Restrictions” on page 14-25
• “Enumerations Derived from Built-In Classes” on page 14-26
• “Enumerations That Encapsulate Data” on page 14-36
14-3
14 Enumerations
Enumeration Class
Create an enumeration class by adding an enumeration block to a class definition. For example, the
WeekDays class enumerates a set of days of the week.
classdef WeekDays
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
end
end
To execute the MATLAB code in the following sections, place the WeekDays class definition in a .m
file on your path.
ClassName.MemberName
For example, assign the enumeration member WeekDays.Tuesday to the variable today:
today = WeekDays.Tuesday;
whos
today
today =
Tuesday
14-4
Define Enumeration Classes
accept its own class as input and return an instance of the superclass. MATLAB built-in numeric
classes, such as uint32, allow this conversion.
For example, the Bearing class derives from the uint32 built-in class:
a = Bearing.East;
b = uint32(a);
whos
a 1x1 60 Bearing
b 1x1 4 uint32
The uint32 constructor accepts an object of the subclass Bearing and returns an object of class
uint32.
classdef WeekDays
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
end
methods
function tf = isMeetingDay(obj)
tf = ~(WeekDays.Tuesday == obj);
end
end
end
today = WeekDays.Tuesday;
today.isMeetingDay
ans =
14-5
14 Enumerations
isMeetingDay(WeekDays.Wednesday)
ans =
classdef SyntaxColors
properties
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
When you refer to an enumeration member, the constructor initializes the property values:
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
For more information on enumeration classes that define properties, see “Mutable Handle vs.
Immutable Value Enumeration Members” on page 14-31.
14-6
Define Enumeration Classes
MATLAB provides a default constructor for all enumeration classes that do not explicitly define a
constructor. The default constructor creates an instance of the enumeration class:
For example, the input arguments for the Bool class are 0 for Bool.No and 1 for Bool.Yes.
The values of 0 and 1 are of class logical because the default constructor passes the argument to
the first superclass. That is, this statement:
n = Bool.No;
MATLAB passes the member argument only to the first superclass. For example, suppose Bool
derived from another class:
classdef MyBool
methods
function boolValues = testBools(obj)
...
end
end
end
14-7
14 Enumerations
See Also
Related Examples
• “Refer to Enumerations” on page 14-9
• “Operations on Enumerations” on page 14-16
14-8
Refer to Enumerations
Refer to Enumerations
In this section...
“Instances of Enumeration Classes” on page 14-9
“Conversion of Characters to Enumerations” on page 14-10
“Enumeration Arrays” on page 14-12
The WeekDays class defines enumeration members for five days of the week.
classdef WeekDays
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
end
end
today = WeekDays.Monday;
tomorrow = WeekDays.Tuesday;
The variables today and tomorrow are objects of the WeekDays class.
The PPM class defines three enumeration members. Each member has an associated numeric value
derived from the class superclass.
level = PPM.High;
When you substitute enumeration members for instances of the superclass, MATLAB coerces the
enumeration member to the superclass. For example, add an enumeration member of the PPM class
with a numeric value.
levelNew =
1100
14-9
14 Enumerations
whos
You can substitute superclass values for enumeration members when the values correspond. For
example, pass one of the numeric values defined in the enumeration class to the PPMSwitch function.
function PPMSwitch(ppm)
switch ppm
case PPM.Low
disp Low
case PPM.Medium
disp Medium
case PPM.High
disp High
end
end
PPMSwitch(100)
Medium
Medium
For information on operations you can perform on enumeration class instances, see “Operations on
Enumerations” on page 14-16.
Use a char vector instead of a direct reference to an enumeration member when you want to use a
simple character strings to specify an enumeration member. However, specifying an enumeration
member directly eliminates the conversion from char to enumeration.
Because the char vector 'Tuesday' matches the enumeration member WeekDays.Tuesday, the
Weekdays char method can perform the conversion.
class(today)
ans =
WeekDays
Create an enumeration array using the WeekDay class constructor and a cell array of char vectors.
14-10
Refer to Enumerations
wd = WeekDays({'Monday','Wednesday','Friday'})
wd =
class(wd)
ans =
WeekDays
All char vectors in the cell array must correspond to an enumeration member defined by the class.
MATLAB coerces char vectors into enumerations members when the dominant argument is an
enumeration. Because user-defined classes are dominant over the char class, MATLAB attempts to
convert the char vector to a member of the enumeration class.
Create an enumeration array. Then insert a char vector that represents an enumeration member into
the array.
a = [WeekDays.Monday,WeekDays.Wednesday,WeekDays.Friday]
a =
a(end+1) = 'Tuesday'
a =
class(a)
ans =
WeekDays
You can use enumeration members in place of char vectors in cases where functions require char
vectors. For example, this call to sprintf expects a char vector, designated by the %s format
specifier.
sprintf('Today is %s',WeekDays.Friday)
ans =
Today is Friday
The automatic conversion of enumeration classes to char enable you to use enumeration members in
this case.
14-11
14 Enumerations
Enumeration Arrays
Create enumeration arrays by:
wd = [WeekDays.Tuesday,WeekDays.Wednesday,WeekDays.Friday];
a(1) = WeekDays.Tuesday;
a(2) = WeekDays.Wednesday;
a(3) = WeekDays.Friday;
You can concatenate enumeration members and char vectors as long as the char vector represents
an enumeration member.
clear a
a = [WeekDays.Wednesday,'Friday'];
class(a)
ans =
WeekDays
clear a
a(1) = WeekDays.Wednesday;
a(2) = 'Friday';
class(a)
ans =
WeekDays
The default member an enumeration class is the first enumeration member defined in the
enumeration block. For the WeekDays class, the default enumeration member is WeekDays.Monday.
classdef WeekDays
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
end
end
MATLAB allows assignment to any element of an array, even if the array variable does not previously
exist. To fill in unassigned array elements, MATLAB uses the default enumeration member.
14-12
Refer to Enumerations
clear a
a(5) = WeekDays.Tuesday;
MATLAB must initialize the values of array elements a(1:4) with the default enumeration member.
The result of the assignment to the fifth element of the array a is:
a =
See Also
Related Examples
• “Operations on Enumerations” on page 14-16
14-13
14 Enumerations
properties
PropName EnumerationClass
end
This syntax restricts values of PropName to members of the enumeration class EnumerationClass.
classdef WeekDays
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
end
end
Use the WeekDays enumerations to restrict the allowed values of the Today property:
classdef Days
properties
Today WeekDays
end
end
d = Days;
d.Today = WeekDays.Tuesday;
d =
Today: Tuesday
The automatic conversion feature enables users of the Days class to assign values to the Today
property as either enumeration members, char vectors, or string scalars. The Today property is
14-14
Enumerations for Property Values
restricted to members of the WeekDays enumeration class. Therefore, you can assign a char vector
that represents a member of the WeekDays class.
d = Days;
d.Today = 'Tuesday';
d = Days;
d.Today = "Tuesday";
For more information on restricting property values, see “Validate Property Values” on page 8-20 and
“Property Class and Size Validation” on page 8-25.
14-15
14 Enumerations
Operations on Enumerations
In this section...
“Operations Supported by Enumerations” on page 14-16
“Enumeration Class” on page 14-16
“Default Methods” on page 14-16
“Convert Enumeration Member to Characters” on page 14-17
“Convert Enumeration Array to Cell Array of char Vectors” on page 14-17
“Enumerations and char Vectors in Relational Operations” on page 14-17
“Enumerations in switch Statements” on page 14-18
“Enumeration Set Membership” on page 14-19
“Enumeration Text Comparison Methods” on page 14-20
“How to Get Information About Enumerations” on page 14-20
“Testing for an Enumeration” on page 14-20
Enumeration Class
The WeekDays class defines members that enumerate days of the week. This topic uses the
WeekDays class to illustrate how to perform operations on enumerations.
classdef WeekDays
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
end
end
For information on defining enumerations, see “Define Enumeration Classes” on page 14-4.
Default Methods
Enumeration classes have the following default methods:
methods('WeekDays')
Methods for class WeekDays:
The WeekDays method converts char vectors, a cell array of char vectors, or string array
elements to enumerations.
Other methods behave similarly to the equivalent function when used with enumerations. For
information on a specific method, see the documentation for that function.
14-16
Operations on Enumerations
today = WeekDays.Friday;
['Today is ',char(today)]
ans =
Today is Friday
ca = cellstr([WeekDays.Tuesday,WeekDays.Thursday]);
class(ca)
ans =
cell
class([ca{1:2}])
ans =
char
Note Enumeration classes that derive from MATLAB built-in classes cannot substitute char vectors
for enumeration members.
today = WeekDays.Friday;
today == 'Friday'
ans =
wd = [WeekDays.Monday,WeekDays.Wednesday,WeekDays.Friday];
wd == 'Friday'
14-17
14 Enumerations
ans =
0 0 1
ans =
1 1 0
The char vector Wednesday is equal to (==) the enumeration member WeekDays.Wednesday. You
can use this equality in conditional statements:
today = 'Wednesday';
...
if today == WeekDays.Wednesday
disp('Team meeting at 2:00')
end
ans =
Note Enumeration classes that derive from MATLAB built-in classes cannot substitute char vectors
for enumeration members.
14-18
Operations on Enumerations
Although you can use char vectors instead of specifying enumerations explicitly, MATLAB must
convert the char to an enumeration. Eliminate the need for this conversion if it is not necessary.
Determine if today is a meeting day for your team. Create a set of enumeration members
corresponding to the days on which the team has meetings.
today = WeekDays.Tuesday;
teamMeetings = [WeekDays.Wednesday WeekDays.Friday];
ans =
0
If you pass both enumeration and char arguments to an enumeration class method, the class
attempts to convert the char to the class of the enumeration.
ans =
Determine if the enumeration member is a member of the cell array of char vectors.
14-19
14 Enumerations
ismember(WeekDays.Friday,{'Wednesday','Friday'})
ans =
The string comparison methods can compare enumeration members and char vectors.
today = WeekDays.Tuesday;
strcmp(today,'Friday')
ans =
strcmp(today,'Tuesday')
ans =
enumeration WeekDays
Monday
Tuesday
Wednesday
Thursday
Friday
14-20
Operations on Enumerations
today = WeekDays.Wednesday;
isenum(today)
ans =
noday = WeekDays.empty;
isenum(noday)
ans =
To determine if the class of a variable class is an enumeration class, use the meta.class object.
today = WeekDays.Wednesday;
mc = metaclass(today);
mc.Enumeration
ans =
See Also
Related Examples
• “Enumeration Class Restrictions” on page 14-25
14-21
14 Enumerations
When an enumeration class derives from another class, such as a numeric or logical class, then each
member can have a value associated with it. If two members have the same value assigned to them,
then the member defined first in the class definition masks the second member. Both names are valid
enumeration members, but the first one defined is the primary member. While masking makes it
possible to use one member name in place of another, it does not hide the secondary name from the
class users.
Using the Hidden attribute removes the masked member names from user view. For example, the
HighlightColor class defines enumeration members that represent syntax highlighting colors.
A new version of the class uses more descriptive member names, but the class needs to avoid
breaking existing code that uses the original member names, red, green, and blue. Using the Hidden
attribute for enumeration members enables the class to hide the original members.
Code that uses the original member names continues to work. For example, existing references to the
now-hidden member HighlightColor.blue is compatible with the same-valued nonhidden member
HighlightColor.keyword.
%
a = HighlightColor.blue
a =
HighlightColor enumeration
keyword
a == HighlightColor.Keyword
14-22
Hide Enumeration Members
ans =
logical
For enumeration members that represent values, the first member defined in the class is the primary
member for that value. For example, in the HighlightColor class, keyword is the primary member
and blue is the secondary member, both representing the value 3. Typically, the primary member is
not hidden while the secondary member is hidden. However, if the class design requires that the
primary member is hidden, then the secondary member must be hidden too.
For example, the PCComponents class defines enumerations that are used in an online form for a
computer order. While the FloppyDrive component is obsolete, the enumeration member can
remain in the class as a hidden member. The form can exclude FloppyDrive from the list of choices,
but the class author can keep this member available so that existing forms that refer to
FloppyDrive are still valid.
classdef PCComponents
enumeration
USBSlots
CDPlayer
end
enumeration (Hidden)
FloppyDrive
end
end
mc =?HighlightColor
mc =
Name: 'HighlightColor'
Description: ''
DetailedDescription: ''
Hidden: 0
Sealed: 0
Abstract: 0
Enumeration: 1
ConstructOnLoad: 0
14-23
14 Enumerations
HandleCompatible: 0
InferiorClasses: {[1×1 meta.class]}
ContainingPackage: [0×0 meta.package]
RestrictsSubclassing: 0
PropertyList: [0×1 meta.property]
MethodList: [140×1 meta.method]
EventList: [0×1 meta.event]
EnumerationMemberList: [6×1 meta.EnumeratedValue]
SuperclassList: [1×1 meta.class]
mc.EnumerationMemberList(4)
ans =
Name: 'red'
Description: ''
DetailedDescription: ''
Hidden: 1
To list the names of all hidden members, use the handle class findobj method:
findobj(mc.EnumerationMemberList,'Hidden',true).Name
ans =
'red'
ans =
'green'
ans =
'blue'
See Also
enumeration | findobj
14-24
Enumeration Class Restrictions
• Enumeration classes are implicitly Sealed. You cannot define a subclass of an enumeration class
because doing so would expand the set.
• The properties of value-based enumeration classes are immutable. Only the constructor can assign
property values. MATLAB implicitly defines the SetAccess attributes of all properties defined by
value-based enumeration classes as immutable. You cannot set the SetAccess attribute to any
other value.
• All properties inherited by a value-based enumeration class that are not defined as Constant
must have immutable SetAccess.
• The properties of handle-based enumeration classes are mutable. You can set property values on
instances of the enumeration class. See “Mutable Handle vs. Immutable Value Enumeration
Members” on page 14-31.
• An enumeration member cannot have the same name as a property, method, or event defined by
the same class.
• Enumerations do not support colon (a:b) operations. For example,
FlowRate.Low:FlowRate.High causes an error even if the FlowRate class derives from a
numeric superclass.
• Classes that define enumerations cannot restrict properties of the same class to an enumeration
type. Create a separate enumeration class to restrict property values to an enumeration. For
information on restricting property values, see “Example of Restricted Property” on page 14-14.
• If the primary enumeration member sets the Hidden attribute, then the secondary member (one
with the same underlying value) must also set the Hidden attribute. For more information, see
See Also
Related Examples
• “Enumerations Derived from Built-In Classes” on page 14-26
14-25
14 Enumerations
For a more basic discussion of enumeration classes, see “Define Enumeration Classes” on page 14-4.
Note Enumeration classes derived from built-in numeric and logical classes cannot define properties.
If an enumeration class subclasses a built-in numeric class, the subclass inherits ordering and
arithmetic operations that you can apply to the enumerated names.
For example, the Results class subclasses the int32 built-in class. This class associates an integer
value with each of the four enumeration members — First, Second, Third, and NoPoints.
classdef Results < int32
enumeration
First (100)
Second (50)
Third (10)
NoPlace (0)
end
end
The enumeration member inherits the methods of the int32 class (except the colon operator). Use
these enumerations like numeric values (summed, sorted, averaged).
isa(Results.Second,'int32')
ans =
For example, use enumeration names instead of numbers to rank two teams:
Team1 = [Results.First, Results.NoPlace, Results.Third, Results.Second];
Team2 = [Results.Second, Results.Third, Results.First, Results.First];
14-26
Enumerations Derived from Built-In Classes
ans =
160
mean(Team1)
ans =
40
sort(Team2,'descend')
ans =
ans =
1 0 0 0
ans =
When you first refer to an enumeration class that derives from a built-in class such as, int32,
MATLAB passes the input arguments associated with the enumeration members to the superclass
constructor. For example, referencing the Second Results member, defined as:
Second (50)
Specify aliased names with the same superclass constructor argument as the actual name:
classdef Bool < logical
enumeration
No (0)
Yes (1)
off (0)
14-27
14 Enumerations
on (1)
end
end
For example, the actual name of an instance of the Bool.off enumeration member is No:
a = Bool.No
a =
No
b = Bool.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 = Bool.Yes
a =
Yes
logical(a)
ans =
The FlowRate enumeration class defines three members, Low, Medium, and High.
classdef FlowRate < int32
enumeration
Low (10)
Medium (50)
High (100)
end
end
14-28
Enumerations Derived from Built-In Classes
setFlow = FlowRate.Medium;
This statement causes MATLAB to call the default constructor with the argument value of 50.
MATLAB passes this argument to the first superclass constructor (int32(50) in this case). The
result is an underlying value of 50 as a 32-bit integer for the FlowRate.Medium member.
Because FlowRate subclasses a built-in numeric class (int32), this class cannot define properties.
However FlowRate inherits int32 methods including a converter method. Programs can use the
converter to obtain the underlying value:
setFlow = FlowRate.Medium;
int32(setFlow)
ans =
50
Default Converter
If an enumeration is a subclass of a built-in numeric class, you can convert from built-in numeric data
to the enumeration using the name of the enumeration class. For example:
a = Bool(1)
a =
Yes
An enumerated class also accepts enumeration members of its own class as input arguments:
Bool(a)
ans =
Yes
Bool([0,1])
ans =
No Yes
Bool.empty
ans =
14-29
14 Enumerations
See Also
Related Examples
• “Mutable Handle vs. Immutable Value Enumeration Members” on page 14-31
• “Fundamental MATLAB Classes”
14-30
Mutable Handle vs. Immutable Value Enumeration Members
Value-based enumeration classes implicitly define the SetAccess attributes of all properties as
immutable. You cannot set the SetAccess attribute to any other value.
However, all superclass properties must explicitly define property SetAccess as immutable.
An instance of a value-based enumeration class is unique until the class is cleared and reloaded. For
example, given this class:
classdef WeekDays
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
end
end
a = WeekDays.Monday;
b = WeekDays.Monday;
isequal(a,b)
ans =
a == b
ans =
14-31
14 Enumerations
Value-based enumeration classes that define properties are immutable. For example, the Colors
enumeration class associates RGB values with color names.
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
ans =
1 0 0
Note You cannot derive an enumeration class from matlab.mixin.Copyable because the number
of instances you can create are limited to the ones defined inside the enumeration block.
Given a handle-based enumeration class with properties, changing the property value of an instance
causes all references to that instance to reflect the changed value.
For example, the HandleColors enumeration class associates RGB values with color names, the
same as the Colors class in the previous example. However, HandleColors derives from handle:
classdef HandleColors < handle
properties
14-32
Mutable Handle vs. Immutable Value Enumeration Members
R = 0
G = 0
B = 0
end
methods
function c = HandleColors(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
a = HandleColors.Red;
a.R
ans =
MATLAB constructs the HandleColors.Red enumeration member, which sets the R property to 1,
the G property to 0, and the B property to 0.
a.R = 0.8;
After setting the value of the R property to 0.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.8. A 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
14-33
14 Enumerations
clear classes
a = HandleColors.Red;
a.R
ans =
To prevent reassignment of a given property value, set that property's SetAccess attribute to
immutable.
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 handle
classes that are not enumeration 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.
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.
14-34
Mutable Handle vs. Immutable Value Enumeration Members
end
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
m = Machine;
m.start
Running
m.stop
NotRunning
See Also
Related Examples
• “Enumerations That Encapsulate Data” on page 14-36
14-35
14 Enumerations
Note Enumeration classes that subclass built-in numeric or logical classes cannot define or inherit
properties. For more information on this kind of enumeration class, see “Enumerations Derived from
Built-In Classes” on page 14-26 .
Define properties in an enumeration class if you want to associate specific data with enumeration
members, but do not need to inherit arithmetic, ordering, or other operations that MATLAB defines
for specific built-in classes.
Representing Colors
Define an enumeration class to represent the RGB values of the colors in a 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
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
You can access the property values via the enumeration member:
Colors.Reddish.R
14-36
Enumerations That Encapsulate Data
ans =
0.9294
Suppose that you want to create a plot with the new shade of red named Reddish:
a = Colors.Reddish;
[a.R,a.G,a.B]
ans =
Use these values by accessing the enumeration member properties. For example, the myPlot
function accepts a Colors enumeration member as an input argument. The function accesses the
RGB values defining the color from the property values.
function h = myPlot(x,y,LineColor)
h = line('XData',x,'YData',y);
r = LineColor.R;
g = LineColor.G;
b = LineColor.B;
h.Color = [r g b];
end
h = myPlot(1:10,1:10,Colors.Reddish);
The Colors class encapsulates the definitions of a standard set of colors. You can change the
enumeration class definition of the colors and not affect functions that use the enumerations.
The Cars class defines categories used to inventory automobiles. The Cars class derives from the
CarPainter class, which derives from handle. The abstract CarPainter class defines a paint
method, which modifies the Color property when a car is painted another color.
The Cars class uses the Colors enumeration members to specify a finite set of available colors. The
exact definition of any given color can change independently of the Cars class.
14-37
14 Enumerations
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
c1.paint(Colors.Reddish)
c1.Color
ans =
Reddish
See Also
Related Examples
• “Save and Load Enumerations” on page 14-39
• “Enumerations for Property Values” on page 14-14
14-38
Save and Load Enumerations
Basic Knowledge
See the save and load functions and “Save and Load Process for Objects” on page 13-2 for general
information on saving and loading objects.
To see a list of enumeration names defined by a class, use the enumeration function.
When loading these enumerations, MATLAB preserves names over underlying values. If the saved
named value is different from the current class definition, MATLAB uses the value defined in the
current class, and then issues a warning.
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 values defined by the class.
If the changes to the enumeration class definition do not prevent MATLAB from loading the object
(that is, all 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:
14-39
14 Enumerations
struct Fields
• ValueNames — A cell array of strings, one per unique value in the enumeration array.
• Values — An array of the same dimension as ValueNames containing the corresponding values
of the enumeration members named in ValueNames. Depending on the kind of enumeration class,
Values can be one of the following:
• If the enumeration class derives from a built-in class, the array class is the same as the built-in
class. The values in the array are the underlying values of each enumeration member.
• Otherwise, a struct array representing the property name — property values pairs of each
enumeration member. For simple and handle-based enumerations, the struct array has no
fields.
• ValueIndices — a uint32 array of the same size as the original enumeration. Each element is
an index into the ValueNames and Values arrays. The content of ValueIndices represents the
value of each object in the original enumeration array.
See Also
More About
• “Named Values” on page 14-2
14-40
15
Constant Properties
15 Constant Properties
Use constant properties to define constant values that you can access by name. Create a class with
constant properties by declaring the Constant attribute in the property blocks. Setting the
Constant attribute means that, once initialized to the value specified in the property block, the value
cannot be changed.
Assign any value to a Constant property, including a MATLAB expression. For example:
classdef NamedConst
properties (Constant)
R = pi/180
D = 1/NamedConst.R
AccCode = '0145968740001110202NPQ'
RN = rand(5)
end
end
MATLAB evaluates the expressions when loading the class. Therefore, the values MATLAB assigns to
RN are the result of 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 and reinitialize the
constant properties.
Refer to the constant using the class name and the property name:
ClassName.PropName
For example, to use the NamedConst class defined in the previous section, reference the constant for
the degree to radian conversion, R:
radi = 45*NamedConst.R
radi =
0.7854
Constants in Packages
To create a library for constant values that you can access by name, first create a package folder,
then define the various classes to organize the constants. For example, to implement a set of
15-2
Define Class Properties with Constant Values
constants that are useful for making astronomical calculations, define a AstroConstants class in a
package called constants:
+constants/@AstroConstants/AstroConstants.m
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 * ...
(1/constants.AstroConstants.Re-0.5*r);
end
Importing the package into the function eliminates the need to repeat the package name (see
import):
function E = energyToOrbit(m,r)
import constants.*;
E = AstroConstants.G * AstroConstants.Me * m * ...
(1/AstroConstants.Re - 0.5 * r);
end
For example, the ConstMapClass class defines a constant property. The value of the constant
property is a handle object (a containers.Map object).
To assign the current date to the Date key, return the handle from the constant property, then make
the assignment using the local variable on the left side of the assignment statement:
localMap = ConstMapClass.ConstMapProp
localMap('Date') = datestr(clock);
You cannot use a reference to a constant property on the left side of an assignment statement. For
example, MATLAB interprets the following statement as the creation of a struct named
ConstMapClass with a field ConstMapProp:
ConstMapClass.ConstMapProp('Date') = datestr(clock);
15-3
15 Constant Properties
MyProject.ProjectInfo.Date
ans =
18-Apr-2002 09:56:59
Because MyProject is a handle class, you can get the handle to the instance that is assigned to the
constant property:
p = MyProject.ProjectInfo;
p.Department
ans =
Engineering
Modify the nonconstant properties of the MyProject class using this handle:
p is a handle to the instance of MyProject that is assigned to the ProjectInfo constant property:
MyProject.ProjectInfo.Department
ans =
Quality Assurance
15-4
Define Class Properties with Constant Values
Clearing the class results in the assignment of a new instance of MyProject to the ProjectInfo
property.
clear MyProject
MyProject.ProjectInfo.Department
ans =
Engineering
You can assign an instance of the defining class as the default value of a property only when the
property is declared as Constant
See Also
Related Examples
• “Static Data” on page 4-2
More About
• “Named Values” on page 14-2
15-5
16
Class Aliasing
16 Class Aliasing
Aliases enable you to maintain backward compatibility when renaming classes in the following ways.
• Existing code that uses old names works in newer versions of MATLAB that uses the new names.
• Versions of MATLAB that use the new name can load MAT files containing objects that were
created using the old names.
• Versions of MATLAB that use the old name can load MAT files containing objects created using the
new name when the alias file was present in the version that created the objects.
Once defined, you can use aliases anywhere that you can use the class name. When you use the old
class name, MATLAB substitutes the new class name.
Defining Aliases
An alias definition is a mapping of an old name to a new name. Aliases are not part of class
definitions. Aliases are stored in special resource files that are co-located with the class definition.
Define aliases in code blocks using the aliasdef and classalias keywords:
aliasdef
classalias
OldClassName -> NewClassName
OldestClassName -> NextOldestClassName -> ... -> CurrentClassName
end
end
The classalias block can contain multiple name mappings and the aliasdef block can contain
multiple classalias blocks. There is no significance to the order of the mappings or the
classalias blocks. The definition can have only one aliasdef block. Store the definition in a file
name alias.
New class names can appear only once per aliasdef block. If you rename a class multiple times, list
all the names in a single line that chains the name in sequence from oldest to newest, as described in
“Sequential Renaming” on page 16-3.
16-2
Aliases for Class Names
To rename a package, you must define aliases for all the classes in the package. However, you cannot
create aliases for package functions. To rename a package that contains functions, keep the old
package in place and redefine the package functions to redirect to the functions in the new package.
For an example that renames a package, see “Rename Package” on page 16-7.
Once the new class definition is in place, remove the original class definition file so that MATLAB
finds the alias instead of the old class definition.
For example, in the following diagram, the C:\utilities\classes\general folder contains the
resources folder and the class definition file (MyNewUtility.m). The resources folder contains
the alias file.
C:\utilities\classes
├── general <--- path folder
│ └── resources <--- add resources folder
│ ├── alias <--- alias file added to resources folder
│ ├── MyNewUtility.m
│ ├── ...
The alias file contains the following mapping, assuming the original class name was MyUtility.
aliasdef
classalias
MyUtility -> MyNewUtility
end
end
The alias redirects all calls to MyUtility to the new name, MyNewUtility. In this example, replace
the file MyUtility.m with the new class file, MyNewUtility.m.
For more information about folder ordering on the MATLAB path, see “What Is the MATLAB Search
Path?”.
Sequential Renaming
If you rename a class more than one time, for example over subsequent releases, map all old names
to the new name in a sequential mapping. Alias files allow only one occurrence of a class name so all
changes must be chained together. For example, If ClassA is renamed to ClassB and then renamed
to ClassC, the alias file entry looks like this:
aliasdef
classalias
16-3
16 Class Aliasing
Maintain compatibility by ordering the name changes in the chronological order they were
introduced. List the oldest name as the leftmost name and the newest name as the rightmost name.
For example, suppose the C:\utilities\classes\general folder is on the MATLAB path and
contains a resources folder that contains an alias file. After modifying the aliases defined in the
alias file, force MATLAB to reload the alias definitions with these commands.
rmpath('C:\utilities\classes\general')
addpath('C:\utilities\classes\general')
Aliasing Examples
Rename Path Class
• Add a resources folder to the folder that contains the class or use an existing resources folder.
• Define the alias file in the resources folder.
• Specify the name mapping in the alias file.
• Remove the original class definition and save the new class definition using the new name.
Before After
C:\utilities\classes C:\utilities\classes
├── general <--- path folder ├── general <--- path folder
│ ├── OldClassName.m │ └── resources <--- add resources folder
│ ├── ... │ ├── alias <--- add alias file to resources fo
│ ├── NewClassName.m
│ ├── ...
After creating the alias, any calls to OldClassName result in a call to NewClassName.
obj = OldClassName;
class(obj)
16-4
Aliases for Class Names
ans =
'NewClassName'
• Add a resources folder to the folder that contains the package or use an existing resources
folder.
• Define the alias file in the resources folder.
• Specify the name mapping in the alias file.
• Replace the original class definition file with the new class definition file.
Before After
C:\utilities\classes C:\utilities\classes
├── general <--- path folder ├── general <--- path folder
│ └── +pkage │ └── resources <--- add resources folder
│ ├── OldClassName.m │ ├── alias <--- add alias file to resources fo
│ ├── OtherClass1.m │ └── +pkage
│ ├── OtherClass2.m │ ├── NewClassName.m
│ ├── ... │ ├── OtherClass1.m
│ ├── OtherClass2.m
│ ├── ...
Create the alias file and define the redirection for pkage.OldClassName to
pkage.NewClassName. Only the renamed class is affected by the name change.
aliasdef
classalias
pkage.OldClassName -> pkage.NewClassName
end
end
obj = pkage.OldClassName;
class(obj)
ans =
'pkage.NewClassName'
• Add a resources folder to the folder that contains the package where the new class will be
located.
• Define the alias file in the resources folder.
• Specify the name mapping in the alias file. Map the class name to package and class name.
16-5
16 Class Aliasing
For example, to map a class named ClassName to pkage.ClassName, add a folder called
resources to the path folder that contains the package that will contain the class. Add the alias
file to the resources folder.
Before After
C:\utilities\classes C:\utilities\classes
├── general <--- path folder ├── general <--- path folder
│ ├── ClassName.m │ └── resources <--- add resources folder
│ ├── ... │ ├── alias <--- add alias file to resources
│ └── +pkage
│ ├── ClassName.m
│ ├── ...
Define the aliasdef code block in the alias file. The alias file contains the redirection for
ClassName to pkage.ClassName.
aliasdef
classalias
ClassName -> pkage.ClassName
end
end
After creating the alias, any calls to ClassName result in a call to pkage.ClassName.
obj = ClassName;
class(obj)
ans =
'pkage.ClassName'
Move a class that is defined in a class folder (a folder named @ClassName) into a package.
• Add a resources folder to the folder containing the package that will contain the class folder.
• Define the alias file in the resources folder.
• Specify the name mapping in the alias file. Map the simple class name to use the package and
class name.
• Move the original class folder with the definition files that it contains into the package.
For information on class folders, see “Using Class Folders” on page 6-14.
For example, move a class named ClassName that is in a class folder, @ClassName, to a package
named pkage.
16-6
Aliases for Class Names
Before After
C:\utilities\classes C:\utilities\classes
├── general <--- path folder ├── general <--- path folder
│ └── @ClassName <--- Class folder │ └── resources <--- add resources folder
│ ├── ClassName.m │ ├── alias <--- add alias file to resources fo
│ ├── method1.m │ └── +pkage
│ ├── method2.m │ └── @ClassName <--- Class folder
│ ├── ... │ ├── ClassName.m
│ ├── method1.m
│ ├── method2.m
│ ├── ...
Define the aliasdef code block in the alias file. The alias file contains the redirection for
ClassName to pkage.ClassName.
aliasdef
classalias
ClassName -> pkage.ClassName
end
end
After creating the alias, any calls to ClassName result in a call to pkage.ClassName.
obj = ClassName;
class(obj)
ans =
'pkage.ClassName'
Rename Package
Rename a package by mapping all classes in the package to the new package name.
• Add a resources folder to the folder that contains the new package.
• Define the alias file in the resources folder.
• Specify the name mapping in the alias file. Map the original package contents to the new
package contents.
• Retain the original package to contain any package functions that are redefined as wrappers for
functions in the new package. Remove the aliased class files from the original package.
You can create aliases only for classes. If a package contains functions, then you must keep the
original package in place to contain those functions. Then redefine each function in the original
package as a wrapper for the functions in the new package. When called, the original package
functions redirect to the functions in the new package.
For example, rename pkageA to pkageB.subpkage. Put the resources folder in the path folder
containing the top-level package.
16-7
16 Class Aliasing
Before After
C:\utilities\classes C:\utilities\classes
├── general <--- path folder ├── general <--- path folder
│ └── +pkageA │ └── resources <--- add resources folder
│ ├── pkFunction.m │ ├── alias <--- add alias file
│ ├── Class1.m │ └── +pkageB
│ ├── Class2.m │ └── +subpkage
│ ├── pkFunction.m
│ ├── Class1.m
│ ├── Class2.m
Because the original package contained a function, you must retain the original package with the
original package function name, pkageA.pkFunction. Redefine this function to be a wrapper for the
function in the new package, pkageB.subpkage.pkFunction.
The alias file contains the redirection from pkageA to pkageB.subpkage for all the classes in the
package.
aliasdef
classalias
pkageA.Class1 -> pkageB.subpkage.Class1
pkageA.Class2 -> pkageB.subpkage.Class2
end
end
See Also
path
Related Examples
• “Search Path”
• “Class File Organization”
16-8
17
Class Metadata
In this section...
“What Is Class Metadata?” on page 17-2
“The meta Package” on page 17-2
“Metaclass Objects” on page 17-3
“Metaclass Object Lifecycle” on page 17-3
All class components have an associated metaclass, which you access from the meta.class object.
For example, create the meta.class object for the matlab.mixin.Copyable class:
mc = ?matlab.mixin.Copyable
mc =
Name: 'matlab.mixin.Copyable'
Description: 'Implement copy method for handle objects in MA...'
DetailedDescription: ''
Hidden: 0
Sealed: 0
Abstract: 1
Enumeration: 0
ConstructOnLoad: 1
HandleCompatible: 1
InferiorClasses: {0x1 cell}
ContainingPackage: [1x1 meta.package]
PropertyList: [0x1 meta.property]
MethodList: [19x1 meta.method]
EventList: [1x1 meta.event]
EnumerationMemberList: [0x1 meta.EnumeratedValue]
SuperclassList: [1x1 meta.class]
17-2
Class Metadata
Metaclass Objects
You cannot instantiate metaclasses directly by calling the respective class constructor. Create
metaclass objects from class instances or from the class name.
• ?ClassName — Returns a meta.class object for the named class. Use meta.class.fromName
with class names stored as characters in variables.
• meta.class.fromName('ClassName') — returns the meta.class object for the named class
(meta.class.fromName is a meta.class method).
• metaclass(obj) — Returns a metaclass object for the class instance (metaclass)
mc = ?MyClass;
Create meta.class object from class name using the fromName method:
mc = meta.class.fromName('MyClass');
obj = MyClass;
mc = metaclass(obj);
The metaclass function returns the meta.class object (that is, an object of the meta.class
class). You can obtain other metaclass objects (meta.property, meta.method, and so on) from the
meta.class object.
Note Metaclass is a term used here to refer to all 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.
However, MATLAB does not update existing metaclass objects to the new class definition. If you
change a class definition while metaclass objects of that class exist, MATLAB deletes the metaclass
objects and their handles become invalid. You must create a new metaclass object after updating the
class.
For information on how to modify and reload classes, see “Automatic Updates for Modified Classes”
on page 5-39.
17-3
17 Information from Class Metadata
See Also
Related Examples
• “Class Introspection with Metadata” on page 17-5
• “Find Objects with Specific Values” on page 17-9
• “Get Information About Properties” on page 17-12
• “Find Default Values in Property Metadata” on page 17-17
17-4
Class Introspection with Metadata
Using the EmployeeData class, create a meta.class object using the ? operator:
mc = ?EmployeeData;
Determine from what classes EmployeeData derives. The returned value is a meta.class object for
the handle superclass:
a = mc.SuperclassList;
a.Name
17-5
17 Information from Class Metadata
ans =
handle
The EmployeeData class has only one superclass. For classes having more than one direct
superclass, a contains a meta.class object for each superclass.
a(1).Name
mc.SuperclassList(1).Name
ans =
handle
Inspect 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.
mc = ?EmployeeData;
mpArray = mc.PropertyList;
The length of mpArray indicates that there are two meta.property objects, one for each property
defined by the EmployeeData class:
length(mpArray)
ans =
2
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.
Query other meta.property object properties to determine the attributes of the EmployeeName
properties.
You can use indexing techniques to list class components that have specific attribute values. For
example, this code lists the methods in the EmployeeData class that have private access:
mc = ?EmployeeData;
mc.PropertyList(ismember({mc.PropertyList(:).SetAccess},'private')).Name
17-6
Class Introspection with Metadata
ans =
EmployeeNumber
Access is not a property of the meta.property class. Use SetAccess and GetAccess, which are
properties of the meta.property class.
Find components with attributes that are logical values using a statement like this one:
mc = ?handle;
mc.MethodList(ismember([mc.MethodList(:).Hidden],true)).Name
ans =
empty
The value of the EmployeeName property is the text My Name, which was assigned in the constructor.
ans =
My Name
The value of the EmployeeNumber property is not accessible because the property has private
Access.
EdObj.(mpArray(2).Name)
mpArray(2).GetAccess
ans =
private
mpArray(1).SetMethod
ans =
@D:\MyDir\@EmployeeData\EmployeeData.m>EmployeeData.set.EmployeeName
classdef WeekDays
enumeration
Monday, Tuesday, Wednesday, Thursday, Friday
17-7
17 Information from Class Metadata
end
end
mc = ?WeekDays;
mc.EnumerationMemberList(2).Name
ans =
Tuesday
See Also
Related Examples
• “Find Objects with Specific Values” on page 17-9
17-8
Find Objects with Specific Values
PB(2).addprop('HighSpeedInternet');
PB(2).HighSpeedInternet = '1M';
Find the object representing employee Nancy Wong and display the name and number by
concatenating the strings:
NW = findobj(PB,'Name','Nancy Wong');
[NW.Name,' - ',NW.Number]
ans =
Search for objects with specific property names using the -property option:
H = findobj(PB,'-property','HighSpeedInternet');
H.HighSpeedInternet
17-9
17 Information from Class Metadata
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
For example, find the abstract methods in a class definition by searching the meta.class
MethodList for meta.method objects with their Abstract property set to true:
Use the class name in character format because class is abstract. You cannot create an object of the
class:
mc = meta.class.fromName('MyClass');
Search the MethodList list of meta.method objects for those methods that have their Abstract
property set to true:
absMethods = findobj(mc.MethodList,'Abstract',true);
methodNames = {absMethods.Name};
The cell array, methodNames, contains the names of the abstract methods in the class.
Find the names of all properties in the containers.Map class that have public GetAccess:
mc = ?containers.Map;
mpArray = findobj(mc.PropertyList,'GetAccess','public');
names = {mpArray.Name};
Display the names of all containers.Map properties that have public GetAccess:
celldisp(names)
names{1} =
17-10
Find Objects with Specific Values
Count
names{2} =
KeyType
names{3} =
ValueType
~isempty(findobj([mc.MethodList(:)],'Static',true))
ans =
findobj returns an array of meta.method objects for the static methods. In this case, the list of
static methods is not empty. Therefore, there are static methods defined by this class.
Get the names of any static methods from the meta.method array:
staticMethodInfo = 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
Name: 'empty'
Description: 'Returns an empty object array of the given size'
DetailedDescription: ''
Access: 'public'
Static: 1
Abstract: 0
Sealed: 0
Hidden: 1
InputNames: {'varargin'}
OutputNames: {'E'}
DefiningClass: [1x1 meta.class]
See Also
empty
Related Examples
• “Get Information About Properties” on page 17-12
17-11
17 Information from Class Metadata
Get the meta.property object for a property from the meta.class object. To get the meta.class
object for a class:
Create the meta.class object using the ? operator with the class name:
mc = ?BasicHandle
mc =
Name: 'BasicHandle'
Description: ''
DetailedDescription: ''
Hidden: 0
Sealed: 0
Abstract: 0
Enumeration: 0
ConstructOnLoad: 0
HandleCompatible: 1
InferiorClasses: {0×1 cell}
ContainingPackage: [0×0 meta.package]
RestrictsSubclassing: 0
PropertyList: [3×1 meta.property]
MethodList: [22×1 meta.method]
EventList: [1×1 meta.event]
17-12
Get Information About Properties
mc.PropertyList(1).Name
ans =
Date
The meta.class object contains a meta.property object for all properties, including hidden
properties. The properties function returns only public properties.
For a handle class, use the handle findprop method to get the meta.property object for a
specific property.
For example, find the meta.property object for the Category property of the BasicHandle class.
mp = findprop(BasicHandle,'Category')
mp =
Name: 'Category'
Description: ''
DetailedDescription: ''
GetAccess: 'public'
SetAccess: 'public'
Dependent: 0
Constant: 0
Abstract: 0
Transient: 0
Hidden: 0
GetObservable: 0
SetObservable: 0
AbortSet: 0
NonCopyable: 0
GetMethod: []
SetMethod: []
HasDefault: 1
DefaultValue: 'new'
DefiningClass: [1×1 meta.class]
The preceding meta.property display shows that a default BasicHandle object Category
property:
For a list of property attributes, see “Table of Property Attributes” on page 8-7.
17-13
17 Information from Class Metadata
Access other metaclass objects directly from the meta.class object properties. For example, the
statement:
mc = ?containers.Map;
class(mc)
ans =
meta.class
Referencing the PropertyList meta.class property returns an array with one meta.property
object for each property of the containers.Map class:
class(mc.PropertyList)
ans =
meta.property
mc.Properties(1)
ans =
[1x1 meta.property]
The Name property of the meta.property object contains a char vector that is the name of the
property:
class(mc.PropertyList(1).Name)
ans =
char
mc.PropertyList(1).Name([1 end])
ans =
Ct
17-14
Get Information About Properties
• Find objects that define constant properties (Constant attribute set to true).
• Determine what properties are read-only (GetAccess = public, SetAccess = private).
The findAttrValue function returns a cell array of property names that set the specified attribute.
The findAttrValue function accesses information from metadata using these techniques:
• If input argument, obj, is a char vector, use the meta.class.fromName static method to get the
meta.class object.
• If input argument, obj, is an object, use the metaclass function to get the meta.class object.
• Every property has an associated meta.property object. Obtain these objects from the
meta.class PropertyList property.
• Use the handle class findprop method to determine if the requested property attribute is a
valid attribute name. All property attributes are properties of the meta.property object. The
statement, findobj(mp,'PropertyName') determines whether the meta.property object,
mp, has a property called PropertyName.
• Reference meta.property object properties using dynamic field names. For example, if
attrName = 'Constant', then MATLAB converts the expression mp.(attrName) to
mp.Constant
• The optional third argument enables you to specify the value of attributes whose values are not
logical true or false (such as GetAccess and SetAccess).
function cl_out = findAttrValue(obj,attrName,varargin)
if ischar(obj)
mc = meta.class.fromName(obj);
elseif isobject(obj)
mc = metaclass(obj);
end
ii = 0; numb_props = length(mc.PropertyList);
cl_array = cell(1,numb_props);
for c = 1:numb_props
mp = mc.PropertyList(c);
if isempty (findprop(mp,attrName))
error('Not a valid attribute name')
end
attrValue = mp.(attrName);
if attrValue
if islogical(attrValue) || strcmp(varargin{1},attrValue)
ii = ii + 1;
cl_array(ii) = {mp.Name};
end
end
end
cl_out = cl_array(1:ii);
end
17-15
17 Information from Class Metadata
ans =
findAttrValue(mapobj,'GetAccess','public')
ans =
See Also
Related Examples
• “Find Default Values in Property Metadata” on page 17-17
17-16
Find Default Values in Property Metadata
Default Values
Class definitions can specify explicit default values for properties (see “Property Default Values” on
page 8-14). Determine if a class defines an explicit default value for a property and what the value of
the default is from the property meta.property object.
meta.property Data
The meta.class object for a class contains a meta.property object for every property defined by
the class, including properties with private and protected access.
For example, get the meta.class object for the PropertyWithDefault class shown here:
classdef PropertyWithDefault
properties
Date = date
RandNumber = randi(9)
end
end
The second element in the mp array is the meta.property object for the RandNumber property.
Listing the meta.property object shows the information contained in its properties:
mp(2)
Name: 'RandNumber'
Description: ''
DetailedDescription: ''
GetAccess: 'public'
SetAccess: 'public'
Dependent: 0
Constant: 0
Abstract: 0
Transient: 0
Hidden: 0
GetObservable: 0
SetObservable: 0
AbortSet: 0
NonCopyable: 0
GetMethod: []
SetMethod: []
17-17
17 Information from Class Metadata
HasDefault: 1
DefaultValue: 5
DefiningClass: [1×1 meta.class]
• HasDefault — true (displayed as 1) if the class specifies a default value for the property, false
if it does not.
• DefaultValue — Contains the default value, when the class defines a default value for the
property. If the default value is an expression, the value of DefaultValue is the result of
evaluating the expression.
For more information on the evaluation of property default values defined by expressions, see
“Evaluation of Expressions in Class Definitions” on page 6-8.
These properties provide a programmatic way to obtain property default values without opening class
definition files. Use these meta.property object properties to obtain property default values for
both built-in classes and classes defined in MATLAB code.
Use the ? operator, the metaclass function, or the meta.class.fromName static method (works
with char vector variable) to obtain a meta.class object.
The meta.class object PropertyList contains an array of meta.property objects. Identify which
property corresponds to which meta.property object using the meta.property Name property.
Follow these steps to obtain the default value defined for the Material property. Include any error
checking that is necessary for your application.
17-18
Find Default Values in Property Metadata
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
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.
Abstract and dynamic properties cannot define default values. Therefore, MATLAB returns an error if
you attempt to query the default value of properties with these attributes. Always test the logical
value of the meta.property HasDefault property before querying the DefaultValue property to
avoid generating an error.
Class definitions can define property default values as MATLAB expressions (see “Evaluation of
Expressions in Class Definitions” on page 6-8 for more information). MATLAB evaluates these
expressions the first time the default value is needed, such as the first time you create an instance of
the class.
Querying the meta.property DefaultValue property causes MATLAB to evaluate a default value
expression, if it had not yet been evaluated. Therefore, querying a property default value can return
an error or warning if errors or warnings occur when MATLAB evaluates the expression. See
“Property with Expression That Errors” on page 17-20 for an example.
MyClass does not explicitly define a default value for the Foo property:
classdef MyFoo
properties
Foo
end
end
The meta.property instance for property Foo has a value of false for HasDefault. Because the
class does not explicitly define a default value for Foo, attempting to access the DefaultValue
property causes an error:
mc = ?MyFoo;
mp = mc.PropertyList(1);
mp.HasDefault
ans =
dv = mp.DefaultValue;
17-19
17 Information from Class Metadata
Abstract Property
classdef MyAbst
properties (Abstract)
Foo
end
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;
MyPropEr defines the Foo property default value as an expression that errors when evaluated.
classdef MyPropEr
properties
Foo = sin(pie/2)
end
end
The meta.property object for property Foo has a value of true for its HasDefault property
because Foo does have a default value:
sin(pie/2)
However, this expression returns an error (pie is a function that creates a pie graph, not the value
pi).
mc = ?MyPropEr;
mp = mc.PropertyList(1);
mp.HasDefault
ans =
dv = mp.DefaultValue;
Querying the default value causes the evaluation of the expression and returns the error.
17-20
Find Default Values in Property Metadata
classdef MyEmptyProp
properties
Foo = []
end
end
The meta.property object 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 =
[]
See Also
Related Examples
• “Get Information About Properties” on page 17-12
17-21
18
In this section...
“How to Customize Class Behavior” on page 18-2
“Which Methods Control Which Behaviors” on page 18-2
“Overload Functions and Override Methods” on page 18-3
You can change how user-defined objects behave by defining methods that control specific behaviors.
To change a behavior, implement the appropriate method with the name and signature of the
MATLAB function.
18-2
Methods That Modify Default Behavior
18-3
18 Specialize Object Behavior
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 timeseries class overloads the MATLAB plot function. When you call plot with
a timeseries object as an input argument, MATLAB calls 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 object of the subclass, then
MATLAB calls the subclass method.
See Also
Related Examples
• “Overload Functions in Class Definitions” on page 9-26
• “Object Precedence in Method Invocation” on page 9-36
• “Operator Overloading” on page 18-38
18-4
Number of Arguments for subsref and subsasgn
Therefore, the indexing code determines the value of nargout for the call to subsref and the value
of nargin for the call to subsasgn.
classdef ValuesArray
properties
Values
end
methods
function obj = ValuesArray(v)
if nargin > 0
obj.Values = v;
end
end
end
end
l = ValuesArray.empty;
for k = 1:10
l(k) = ValuesArray(k);
end
This subscripted reference returns a comma-separated list of three elements. For this statement, the
value of nargout in subsref is 3.
l(1:3).Values
ans =
ans =
18-5
18 Specialize Object Behavior
ans =
The left side of a subscripted assignment statement affects the number of input arguments that
MATLAB uses to call subsasgn. This subscripted assignment assigns three values to the three
elements added to the array. For this assignment, the value of nargin within subsasgn is 5 (the
object, the indexing substructure, and the three values to assign).
[l(11:13).Values] = l(1:3).Values
l =
Values
If the number of right-side arguments cannot satisfy the number of left-side arguments, MATLAB
returns an error:
[l(11:13).Values] = l(1).Values
Insufficient number of outputs from right hand side of equal sign to satisfy
assignment.
If a class overloads subsasgn to support either '{}', '.', or both types of indexing, and the
operation assigns more than one value, overload subsasgn to accept multiple values using
varargin:
function A = subsasgn(A,S,varargin)
...
end
See Also
More About
• “Modify nargout and nargin for Indexing Methods” on page 18-7
• “Comma-Separated Lists”
18-6
Modify nargout and nargin for Indexing Methods
If your class design requires that indexing operations return or assign a different number of values
than the number defined by the indexing operation, use numArgumentsFromSubscript to specify
the required number. numArgumentsFromSubscript provides control over nargout for subsref
and nargin for subsasgn.
Before MATLAB release R2015b, MATLAB produced different results for some indexing expressions
that return or assign to a comma-separated list. Use numArgumentsFromSubscript to support code
that relies on the behavior of previous releases. Also, now you can overload
numArgumentsFromSubscript instead of numel to achieve specific results without redefining how
numel works.
function n = numArgumentsFromSubscript(obj,s,indexingContext)
...
end
MATLAB uses the value returned by numArgumentsFromSubscript for indexed reference and
assignment. Determine the context in which the indexing operation executes by testing the value of
18-7
18 Specialize Object Behavior
Note For MATLAB version R2015b and later releases, overload numArgumentsFromSubscript
instead of numel to customize indexing for your class.
See Also
More About
• “Number of Arguments for subsref and subsasgn” on page 18-5
• “Use of size and numel with Classes” on page 12-61
18-8
Concatenation Methods
Concatenation Methods
In this section...
“Default Concatenation” on page 18-9
“Methods to Overload” on page 18-9
Default Concatenation
You can concatenate objects into arrays. For example, suppose that you have three instances of the
class MyClass, obj1, obj2, obj3. You can form arrays of 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. To concatenate arrays along different dimensions, use
the cat function. For example:
ndArray = cat(3,HorArray,HorArray);
Methods to Overload
Overload horzcat, vertcat, and cat to produce specialized behaviors in your class. Overload both
horzcat and vertcat whenever you want to modify object concatenation because MATLAB uses
both functions for any concatenation operation.
See Also
Related Examples
• “Subclasses of Built-In Types with Properties” on page 12-54
18-9
18 Specialize Object Behavior
Object Converters
In this section...
“Why Implement Converters” on page 18-10
“Converters for Package Classes” on page 18-10
“Converters and Subscripted Assignment” on page 18-11
Suppose that you define a polynomial class. If you create a double method for the polynomial
class, you can use it to call other functions that require inputs of type double.
p = polynomial(...);
dp = double(p);
roots(dp)
p is a polynomial object, double is a method of the polynomial class, and roots is a standard
MATLAB function whose input arguments are the coefficients of a polynomial.
classdef MyClass
...
methods
function objPkgClass = PkgName.PkgClass(objMyclass)
...
end
end
end
You cannot define a converter method that uses dots in the name in a separate file. Define package-
class converters in the classdef file.
18-10
Object Converters
A(1) = myobj;
MATLAB compares the class of the Right-Side variable to the class of the Left-Side variable. If the
classes are different, MATLAB attempts to convert the Right-Side variable to the class of the Left-Side
variable. To do this conversion, MATLAB first searches for a method of the Right-Side class that has
the same name as the Left-Side class. Such a method is a converter method, which is similar to a
typecast operation in other languages.
If the Right-Side class does not define a method to convert from the Right-Side class to the Left-Side
class, MATLAB calls the Left-Side class constructor. passing it the Right-Side variable.
MATLAB attempts to call a method of ClassB named ClassA. If no such converter method exists,
MATLAB software calls the ClassA constructor, passing objB as an argument. If the ClassA
constructor cannot accept objB as an argument, then MATLAB returns an error.
See Also
Related Examples
• “Converter Methods” on page 10-17
• “The Double Converter” on page 20-11
18-11
18 Specialize Object Behavior
Arrays enable you to reference and assign elements of the array using a subscripted notation. This
notation specifies the indices of specific array elements. For example, suppose that you create two
arrays of numbers (using randi and concatenation).
A = randi(9,3,4)
A =
4 8 5 7
4 2 6 3
7 5 7 7
B = [3 6 9];
Reference and assign elements of either array using index values in parentheses:
B(2) = A(3,4);
B
B =
3 7 9
C = A(3,4);
MATLAB calls the built-in subsref function to determine how to interpret the statement. Similarly, if
you execute a statement that involves indexed assignment:
C(4) = 7;
MATLAB calls the built-in subsasgn function to determine how to interpret the statement.
The MATLAB default subsref and subsasgn functions also work with user-defined objects. For
example, create an array of objects of the same class:
18-12
Object Array Indexing
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);
class(D)
ans =
MyClass
You can assign an object to an array of objects of the same class, or an uninitialized variable:
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 standard array behavior with your class.
Once you add a subsref or subsasgn method to your class, then MATLAB calls only the class
method, not the built-in function. Therefore, your class method must implement all the indexed
reference and assignment operations that you want your class to support. These operations include:
Implementing subsref and subsasgn methods gives you complete control over the interpretation of
indexing expressions for objects of your class. Implementing the extent of behaviors that MATLAB
provides by default is nontrivial.
This statement:
obj.Data(2,3)
Returns the value contained in the second row, third column of the array. If you have an array of
objects, use an expression like:
objArray(3).Data(2,3)
18-13
18 Specialize Object Behavior
This statement returns the value contained in the second row, third column of the third element in the
array.
Modify the default indexing behavior when your class design requires behavior that is different from
MATLAB default behavior.
calls the built-in subsref function. To call the class-defined subsref method, use:
subsref(obj,substruct('.','Prop'))
Whenever a method requires the functionality of the class-defined subsref or subsasgn method,
the class must call the overloaded methods as functions. Do not use the operators, '()', '{}', or
'.'.
For example, suppose that you define a class to represent polynomial. This class has a subsref
method that evaluates the polynomial with the value of the independent variable equal to the
subscript. Assume that this statement defines the polynomial with its coefficients:
p = polynom([1 0 -2 -5]);
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 explicitly
y1 = subsref(p1,subs);
y2 = subsref(p2,subs);
if y1 == y2
ToF = true;
else
ToF = false;
18-14
Object Array Indexing
end
end
end
This behavior enables you to use standard MATLAB indexing to implement specialized behaviors. See
“Class with Modified Indexing” on page 18-32 for examples of how to use both built-in and class-
modified indexing.
This subsref enables the use of dot notation to 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.
You do not need to code each method and property name. The otherwise code in the inner switch
block manages 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
18-15
18 Specialize Object Behavior
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.
See Also
Related Examples
• “Code Patterns for subsref and subsasgn Methods” on page 18-17
• “Indexed Reference” on page 18-23
• “Indexed Assignment” on page 18-25
18-16
Code Patterns for subsref and subsasgn Methods
For an overview of object indexing, see “Object Array Indexing” on page 18-12.
If your class design requires that indexing operations return or assign a different number of values
than the number defined by the default indexing operation, overload the
numArgumentsFromSubscript function to control nargout for subsref and nargin for
subsasgn. For more information and examples, see numArgumentsFromSubscript.
For example, the CustomIndex class defines a property that you can use in indexing expressions.
classdef CustomIndex
properties
18-17
18 Specialize Object Behavior
DataArray
end
end
Create an object and assign a 5-by-5 matrix created by the magic function to the DataArray
property.
a = CustomIndex;
a.DataArray = magic(5);
This subscripted reference expression returns the first row of the 5-by-5 matrix.
a.DataArray(1,:)
ans =
17 24 1 8 15
This expression assigns new values to the first row of the array stored in the DataArray property.
a.DataArray(1,:) = [1 2 3 4 5];
The indexing structure contains this information in the type and subs fields.
• type — One of the three possible indexing types: '.', '()', '{}'
• subs — A char vector with the property name or cell array of the indices used in the expression,
including : and end.
If the indexing expression is a compound expression, then MATLAB passes an array of structures, one
struct for each level of indexing. For example, in this expression:
a.DataArray(1,:)
• S(1).type is set to '.', indicating that the first indexing operation is a dot.
• s(1).subs is set to the property name, 'DataArray'
The second level of indexing is in the second element of the indexing structure:
• S(2).types is set to '()' indicating the second indexing operation is parentheses indexing
• S(2).subs is set to a cell array containing the indices {[1],[:]}
18-18
Code Patterns for subsref and subsasgn Methods
• Determine the full indexing expression using the types and subs fields of the indexing structure.
• Implement the specialized behaviors for the indexing operations supported by the class.
• Return the appropriate values or modified objects in response to the call by MATLAB.
A switch statement is a convenient way to detect the first level of indexing. There are three types of
indexing—dot, parentheses, and braces. Each case block in the switch statement implements all
indexing expressions that begin with that first-level type of indexing.
The methods must implement all indexing expressions that the class supports. If you do not customize
a particular type of indexing, call the built-in function to handle that expression.
Use the length of the indexing structure array and indexing type define conditional statements for
compound indexing expressions.
The following framework for the subsref method shows how to use information in the indexing
structure in conditional statements. Your application can involve other expressions not shown here.
function varargout = subsref(obj,s)
switch s(1).type
case '.'
if length(s) == 1
% Implement obj.PropertyName
...
elseif length(s) == 2 && strcmp(s(2).type,'()')
% Implement obj.PropertyName(indices)
...
else
[varargout{1:nargout}] = builtin('subsref',obj,s);
end
case '()'
if length(s) == 1
% Implement obj(indices)
...
elseif length(s) == 2 && strcmp(s(2).type,'.')
% Implement obj(ind).PropertyName
...
elseif length(s) == 3 && strcmp(s(2).type,'.') && strcmp(s(3).type,'()')
% Implement obj(indices).PropertyName(indices)
...
else
% Use built-in for any other expression
[varargout{1:nargout}] = builtin('subsref',obj,s);
end
case '{}'
if length(s) == 1
% Implement obj{indices}
...
elseif length(s) == 2 && strcmp(s(2).type,'.')
% Implement obj{indices}.PropertyName
...
else
% Use built-in for any other expression
[varargout{1:nargout}] = builtin('subsref',obj,s);
end
otherwise
error('Not a valid indexing expression')
end
18-19
18 Specialize Object Behavior
Using varargout for the returned value enables the method to work with object arrays. For
example, suppose that you want to support the return of a comma-separated list with an expression
like this one:
[x1,...xn] = objArray.PropertyName(Indices)
This expression results in a two-element indexing structure array. The first-level type is dot ('.') and
the second level is parentheses ('()'). Build the varargout cell array with each value in the array.
case '.'
...
if length(s)==2 && strcmp(s(2).type,'()')
prop = s(1).subs; % Property name
n = numel(obj); % Number of elements in array
varargout = cell(1,n); % Preallocate cell array
for k = 1:n
varargout{k} = obj(k).(prop).(s(2).subs);
end
end
...
end
subsasgn Pattern
The following framework for the subsasgn method shows how to use the indexing structure in
conditional statements that implement assignment operations.
function obj = subsasgn(obj,s,varargin)
switch s(1).type
case '.'
if length(s) == 1
% Implement obj.PropertyName = varargin{:};
...
elseif length(s) == 2 && strcmp(s(2).type,'()')
% Implement obj.PropertyName(indices) = varargin{:};
...
else
% Call built-in for any other case
obj = builtin('subsasgn',obj,s,varargin{:});
end
case '()'
if length(s) == 1
% Implement obj(indices) = varargin{:};
elseif length(s) == 2 && strcmp(s(2).type,'.')
% Implement obj(indices).PropertyName = varargin{:};
...
elseif length(s) == 3 && strcmp(s(2).type,'.') && strcmp(s(3).type,'()')
% Implement obj(indices).PropertyName(indices) = varargin{:};
...
else
% Use built-in for any other expression
obj = builtin('subsasgn',obj,s,varargin{:});
end
case '{}'
if length(s) == 1
% Implement obj{indices} = varargin{:}
...
elseif length(s) == 2 && strcmp(s(2).type,'.')
% Implement obj{indices}.PropertyName = varargin{:}
...
18-20
Code Patterns for subsref and subsasgn Methods
Using varargin for the right-side value of the assignment statement enables the method to work
with object arrays. For example, suppose that you want to support the assignment of a comma-
separated list with an expression like this one:
C = {'one';'two';'three'};
[objArray.PropertyName] = C{:}
This expression results in an indexing structure with the dot type ('.') indexing The cell array C on
the right side of the assignment statement produces a comma-separated list. This code assigns one
list item to each property in the object array.
case '.'
if length(s)==1
prop = s(1).subs; % Property name
n = numel(obj); % Number of elements in array
for k = 1:n
obj(k).(prop) = varargin{k};
end
end
end
Assigning to an element of an uninitialized variable results in a call to the subsasgn method of the
class on the right side of the assignment. For example, this class defines a subsasgn method that
simply calls the built-in subsasgn method for parenthesis indexing.
classdef MyClass
methods
function obj = subsasgn(obj,s,varargin)
switch s(1).type
case '()'
obj = builtin('subsasgn',obj,s,varargin{:});
end
end
end
end
When attempting to assign an object of MyClass to the first element of the uninitialized variable,
B(1) in the following statement, MATLAB calls the subsasgn method of MyClass with an empty
double ([]) as the first argument. The assignment can cause an error because the subsasgn method
must be passed an object of the class.
clear B
B(1) = MyClass;
18-21
18 Specialize Object Behavior
The subsasgn method can detect this situation and take the appropriate action, such as returning a
useful error message if the class does not support this type of assignment, or converting the input to
an object of the class and passing it to subsasgn.
For example, because MyClass can allow subscripted assignment to an uninitialized variable, the
subsasgn method can change the first argument from the empty double to an empty MyClass
object.
Use the isequal function to check the input and the empty static method to create the empty object.
classdef MyClass
methods
function obj = subsasgn(obj,s,varargin)
if isequal(obj,[])
obj = MyClass.empty;
end
obj = builtin('subsasgn',obj,s,varargin{:});
end
end
end
clear B
B(1) = MyClass;
B =
See Also
Related Examples
• “Class with Modified Indexing” on page 18-32
• “Representing Hardware with Classes” on page 12-66
• “Subclasses of Built-In Types with Properties” on page 12-54
18-22
Indexed Reference
Indexed Reference
In this section...
“How Indexed Reference Works” on page 18-23
“Compound Indexed References” on page 18-24
A(I)
A{I}
A.name
Each of these statements results in a call by MATLAB to the subsref of class A, or a call to the built-
in subsasgn function if the class of A does not implement a subsasgn method.
MATLAB passes two arguments to subsref and requires subsref to return the result of the indexed
reference:
B = subsref(A,S)
The first argument is the object being referenced, A. The second argument, S, is a substruct with
two fields:
• S.type is a char vector containing '()', '{}', or '.' specifying the indexing type used.
• S.subs is a cell array or char vector containing the actual index or name. A colon used as an
index is passed in the cell array as the colon character ':'. Ranges specified using a colon (e.g.,
2:5) are expanded to 2 3 4 5.
A(1:4,:)
Causes MATLAB to call subsref(A,S), where S is a 1-by-1 structure with a two-element cell array.
The cell array contains the numbers 1, 2, 3, 4, and the colon character :.
S.type = '()'
S.subs = {1:4,':'}
Returning the contents of each cell of S.subs gives the index values for the first dimension and a
char vector ':' 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 the columns in the array.
18-23
18 Specialize Object Behavior
A{1:4}
S.type ='{}'
S.subs = {1:4}
The default subsref returns the contents of all cell array elements in rows 1 through 4 and all the
columns in the array.
This expression:
A.Name
S.type = '.'
S.subs = 'Name'
A(1,2).PropertyName(1:4)
See Also
Related Examples
• “Indexed Assignment” on page 18-25
• “Number of Arguments for subsref and subsasgn” on page 18-5
• “Modify nargout and nargin for Indexing Methods” on page 18-7
• “Code Patterns for subsref and subsasgn Methods” on page 18-17
18-24
Indexed Assignment
Indexed Assignment
In this section...
“How Indexed Assignment Works” on page 18-25
“Indexed Assignment to Objects” on page 18-26
“Compound Indexed Assignments” on page 18-27
A(I) = B
A{I} = B
A.name = B
Each of these statements results in a call by MATLAB to the subsasgn method of class A, or a call to
the built-in subsasgn function if the class of A does not implement a subsasgn method.
MATLAB passes three arguments to subsasgn and requires subsasgn to return the result of the
assignment:
A = subsasgn(A,S,B)
The first argument, A, is the object being assigned the value in the third argument B.
The second argument is the indexing structure, substruct. S has two fields:
• S.type is a char vector containing '()', '{}', or '.' specifying the indexing type used.
• S.subs is a cell array or character array containing the actual indices or field name. A colon used
as an index is passed in the cell array as the character ':'. Ranges specified using a colon (e.g.,
2:5) are expanded to 2 3 4 5.
A(2,3) = B;
A = subsasgn(A,S,B)
S contains:
S.type = '()'
S.subs = {2,3}
• Determines the class of A. If B is not the same class as A, then MATLAB tries to construct an object
of the same class as A using B as an input argument. 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.
18-25
18 Specialize Object Behavior
• 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 default objects of class B.
A{2,3} = B
S.type ='{}'
S.subs = {2,3}
This expression:
A.Name = B
S.type = '.'
S.subs = 'Name'
You can redefine all or some of these assignment behaviors by implementing a subsasgn method for
your class.
A.Name = B
S.type = '.'
S.subs = 'Name'
18-26
Indexed Assignment
• If the Name property has restricted access (private or protected), MATLAB determines if the
assignment is allowed based on the context in which the assignment is made.
• If the class of A defines a set method for property Name, MATLAB calls the set method.
• MATLAB applies all other property attributes before determining whether to assigning B to the
property Name.
A(1,2).PropertyName(1:4) = B
See Also
Related Examples
• “Indexed Reference” on page 18-23
• “Number of Arguments for subsref and subsasgn” on page 18-5
• “Modify nargout and nargin for Indexing Methods” on page 18-7
• “Code Patterns for subsref and subsasgn Methods” on page 18-17
18-27
18 Specialize Object Behavior
Classes can overload the end function to implement specialized behavior. If your class defines an end
method, MATLAB calls that method to determine how to interpret the expression.
ind = end(A,k,n)
• 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
For example, consider the 3-by-5 array A. When MATLAB encounters the expression:
A(end-1,:)
MATLAB calls the end method defined for the object A using the arguments:
ind = end(A,1,2)
These arguments mean that the end statement occurs in the first index and there are two indices.
The end class method returns the index value for the last element of the first dimension (from which
1 is subtracted in this case). The original expression is evaluated as:
A(3-1,:)
If your class implements an end method, ensure that it returns a value appropriate for the class.
obj(4:end)
obj.Data(2,3:end)
This end method determines a positive integer value for end. The method returns the value so that
MATLAB can use it in the indexing expression.
18-28
end as Object Index
See Also
Related Examples
• “Class with Modified Indexing” on page 18-32
• “Objects in Index Expressions” on page 18-30
18-29
18 Specialize Object Behavior
Objects Indexes
MATLAB can use objects as indices in indexed expressions. The rules of array indexing apply —
indices must be positive integers. Therefore, MATLAB must be able to derive a value from the object
that is a positive integer for use in the indexed expression.
Indexed expressions like X(A), where A is an object, cause MATLAB to call the subsindex function.
However, if an indexing expression results in a call to an overloaded subsref or subsasgn method
defined by the class of X, then MATLAB does not call subsindex.
• Define a subsindex method in the class of A that converts A to an integer. MATLAB calls A's
subsindex method to perform indexing operations when the class of X does not overload
subsref or subsasgn.
• If the class of X overloads subsref or subsasgn, these methods can call the subsindex method
of A explicitly. The class of A must implement a subsindex method that returns an appropriate
value.
• If the class of X overloads subsref or subsasgn, these methods can contain code that
determines an integer index value. In this case, the class of A does not implement a subsindex
method.
subsindex Implementation
subsindex must return the value of the object as a zero-based integer index value in the range 0 to
prod(size(X))-1.
Suppose that you want to use object A to index into object B. B can be a single object or an array,
depending on the class designs.
C = B(A);
Here are two examples of subsindex methods. The first assumes you can convert class A to a
uint8. The second assumes class A stores an index value in a property.
• The subsindex method implemented by class A can convert the object to numeric format to be
used as an index:
18-30
Objects in Index Expressions
The class of obj implements a uint8 method to provide the conversion from the object to an
integer value.
• Class A implements subsindex to return a numeric value that is stored in a property:
See Also
numArgumentsFromSubscript | subsasgn | subsref
Related Examples
• “end as Object Index” on page 18-28
More About
• “Modify nargout and nargin for Indexing Methods” on page 18-7
18-31
18 Specialize Object Behavior
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')
obj =
18-32
Class with Modified Indexing
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 each instance is created.
Here is the preliminary code listing without the subsref, subsasgn double, and plus 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
if nargin > 1
obj.Description = desc;
end
obj.Date = clock;
end
end
end
obj.Data(2,3)
ans =
5
• And to add the functionality to index into the Data property with an expression like this
statement:
obj(2,3)
If you redefine '()' indexing to support access to the Data property, you cannot create arrays of
MyDataClass objects and use '()' indexing to access individual objects. You can reference only
scalar objects.
To achieve the design goals, the subsref method must handle all indexing types. The subsref
method:
18-33
18 Specialize Object Behavior
obj.Data(2,3) = 9;
• Add the functionality to assign values to the Data property with an expression like this statement:
obj(2,3) = 9;
The substruct function redefines the index type and index subscripts structure that MATLAB passes
to subsref and subsasgn.
18-34
Class with Modified Indexing
case '{}'
error('MyDataClass:subsasgn',...
'Not a supported subscripted assignment')
end
end
Allow direct addition of the Data property values by implementing a plus method. Implementing a
plus method enables the use of the + operator for addition of MyDataClass objects.
Because the plus method implements addition by adding double arrays, MATLAB:
The plus method uses the double method to convert the object to numeric values before performing
the addition:
function a = double(obj)
a = obj.Data;
end
function c = plus(obj,b)
c = double(obj) + double(b);
end
For example, the plus method enables you to add a scalar number to the object Data array.
Here are the values of the Data, displayed using indexed reference:
obj(:,:)
ans =
8 9 3 9
9 6 9 2
2 1 9 9
obj + 7
ans =
15 16 10 16
16 13 16 9
9 8 16 16
18-35
18 Specialize Object Behavior
MyDataClass.m
This definition for MyDataClass includes the end indexing method discussed in “end as Object
Index” on page 18-28. extraneous
classdef MyDataClass
% Example for "A Class with Modified Indexing"
properties
Data
Description
end
properties (SetAccess = private)
Date
end
methods
function obj = MyDataClass(data,desc)
% Support 0-2 args
if nargin > 0
obj.Data = data;
end
if nargin > 1
obj.Description = desc;
end
obj.Date = clock;
end
18-36
Class with Modified Indexing
snew = substruct('.','Data','()',s(1).subs(:));
obj = subsasgn(obj,snew,val);
end
end
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
See Also
Related Examples
• “end as Object Index” on page 18-28
• “Number of Arguments for subsref and subsasgn” on page 18-5
18-37
18 Specialize Object Behavior
Operator Overloading
In this section...
“Why Overload Operators” on page 18-38
“How to Define Operators” on page 18-38
“Sample Implementation — Addable Objects” on page 18-39
“MATLAB Operators and Associated Functions” on page 18-40
Each operator has an associated function (e.g., the + operator has an associated plus.m function).
You can implement any operator by creating a class method with the appropriate name. This method
can perform whatever steps are appropriate for the operation being implemented.
For a list of operators and associated function names, see “MATLAB Operators and Associated
Functions” on page 18-40.
User-defined classes have a higher precedence than built-in classes. For example, suppose q is an
object of class double and p is a user-defined class. Both of these expressions generate a call to the
plus method in the user-define class, if it exists:
q + p
p + q
Whether this method can add objects of class double and the user-defined class depends on how you
implement the method.
When p and q are objects of different classes, MATLAB applies the rules of precedence to determine
which method to use.
“Object Precedence in Method Invocation” on page 9-36 provides information on how MATLAB
determines which method to call.
Operator Precedence
Overloaded operators retain the original MATLAB precedence for the operator. For information on
operator precedence, see “Operator Precedence”.
18-38
Operator Overloading
The Adder class also implements the less than operator (<) by defining a lt method. The lt method
returns a logical value after comparing the values in each object NumericData property.
classdef Adder
properties
NumericData
end
methods
function obj = Adder(val)
obj.NumericData = val;
end
function r = plus(obj1,obj2)
a = double(obj1);
b = double(obj2);
r = Adder(a + b);
end
function d = double(obj)
d = obj.NumericData;
end
function tf = lt(obj1,obj2)
if obj1.NumericData < obj2.NumericData
tf = true;
else
tf = false;
end
end
end
end
Using a double converter enables you to add numeric values to Adder objects and to perform
addition on objects of the class.
a = Adder(1:10)
a =
NumericData: [1 2 3 4 5 6 7 8 9 10]
ans =
NumericData: [2 4 6 8 10 12 14 16 18 20]
18-39
18 Specialize Object Behavior
b = uint8(255) + a
b =
NumericData: [256 257 258 259 260 261 262 263 264 265]
a < b
ans =
Ensure that your class provides any error checking required to implement your class design.
18-40
Operator Overloading
a:b colon(a,b)
a' ctranspose(a) Complex conjugate transpose
a.' transpose(a) Matrix transpose
[a b] horzcat(a,b,...) Horizontal concatenation
[a; b] vertcat(a,b,...) Vertical concatenation
a(s1,s2,...sn) subsref(a,s) Subscripted reference
a(s1,...,sn) = b subsasgn(a,s,b) Subscripted assignment
b(a) subsindex(a) Subscript index
See Also
Related Examples
• “Define Arithmetic Operators” on page 20-16
• “Methods That Modify Default Behavior” on page 18-2
18-41
19
a.field1 = 7
a =
field1: 7
MATLAB provides user-defined classes with similar display functionality. User-defined classes can
customize how MATLAB displays objects of the class using the API provided by the
matlab.mixin.CustomDisplay class. To use this API, derive your class from
matlab.mixin.CustomDisplay.
• A header showing the class name, and the dimensions for nonscalar arrays.
• A list of all nonhidden public properties, shown in the order of definition in the class.
The actual display depends on whether the object is scalar or nonscalar. Also, there are special
displays for a scalar handle to a deleted object and empty object arrays. Objects in all of these states
are displayed differently if the objects have no properties.
The details function creates the default detailed display. The detailed display adds these items to
the simple display:
19-2
Custom Display Interface
See “Class with Default Object Display” on page 19-11 for an example of how MATLAB displays
objects.
MATLAB displays object properties that have public get access and are not hidden (see “Property
Attributes” on page 8-7). Inherited abstract properties are excluded from display. When the object
being displayed is scalar, any dynamic properties attached to the object are also included.
CustomDisplay Class
The matlab.mixin.CustomDisplay class provides an interface that you can use to customize
object display for your class. To use this interface, derive your class from CustomDisplay:
The CustomDisplay class is HandleCompatible, so you can use it in combination with both value
and handle superclasses.
Note You cannot use matlab.mixin.CustomDisplay to derive a custom display for enumeration
classes.
The CustomDisplay interface does not allow you to override disp, display, and details.
Instead, override any combination of the customization methods defined for this purpose.
• Part builder methods build the strings used for the standard display. Override any of these
methods to change the respective parts of the display.
• State handler methods are called for objects in specific states, like scalar, nonscalar, and so on.
Override any of these methods to handle objects in a specific state.
All of these methods have protected access and must be defined as protected in your subclass of
CustomDisplay (that is, Access = protected).
There are three parts that makeup the standard object display — header, property list, and footer
For example, here is the standard object display for a containers.Map object:
19-3
19 Customizing Object Display
The default object display does not include a footer. The detailed display provides more information:
You can customize how MATLAB displays objects as a result of expressions that display objects in the
command window such as unterminated statements that return objects or calls to disp and
display. The results displayed when calling details on an object or object array are not changed
by the CustomDisplay API.
Each part of the object display has an associated method that assembles the respective part of the
display.
19-4
Custom Display Interface
There are four object states that affect how MATLAB displays objects:
Each object state has an associated method that MATLAB calls whenever displaying objects that are
in that particular state.
Utility Methods
The CustomDisplay class provides utility methods that return strings that are used in various parts
of the different display options. These static methods return text that simplifies the creation of
customized object displays.
If the computer display does not support hypertext linking, the strings are returned without the links.
19-5
19 Customizing Object Display
See Also
Related Examples
• “How CustomDisplay Works” on page 19-7
19-6
How CustomDisplay Works
For example, suppose obj is a valid scalar object of a class derived from CustomDisplay. If you type
obj at the command line without terminating the statement with a semicolon:
>> obj
MATLAB follows a similar sequence for nonscalar object arrays and empty object arrays.
Only an instance of a handle class can be in a state of scalar handle to a deleted object.
19-7
19 Customizing Object Display
See Also
Related Examples
• “Class with Default Object Display” on page 19-11
19-8
Role of size Function in Custom Displays
An unusual or improper implementation of size can result in undesirable display behavior. For
example, suppose a class overloads size reports an object as scalar when it is not. In this class, a
property list consisting of a cell array of strings results in the property values of the first object of the
array being displayed. This behavior can give the impression that all objects in the array have the
same property values.
However, reporting an object as scalar when in fact the object is empty results in the object
displaying as an empty object array. The default methods of the CustomDisplay interface always
determine if the input is an empty array before attempting to access property values.
As you override CustomDisplay methods to implement your custom object display, consider how an
overloading size method can affect the result.
See Also
Related Examples
• “Methods That Modify Default Behavior” on page 18-2
19-9
19 Customizing Object Display
The versions of disp and display that are inherited from matlab.mixin.CustomDisplay are
sealed. However, these methods call all of the part builder (“Part Builder Methods” on page 19-4) and
state handler methods (“State Handler Methods” on page 19-5).
To use the CustomDisplay interface, the root class of the heterogeneous hierarchy can declare
these methods as Sealed and Access = protected.
If you do not need to override a particular method, then call the superclass method, as shown in the
following code.
For example, the following code shows modifications to the getPropertyGroups and
displayScalarObject methods, while using the superclass implementation of all others.
classdef RootClass < matlab.mixin.CustomDisplay & matlab.mixin.Heterogeneous
%...
methods (Sealed, Access = protected)
function header = getHeader(obj)
header = [email protected](obj);
end
function displayNonScalarObject(obj)
[email protected](obj);
end
function displayScalarObject(obj)
% Override of this method
% ...
end
function displayEmptyObject(obj)
[email protected](obj);
end
function displayScalarHandleToDeletedObject(obj)
[email protected](obj);
end
end
end
See Also
Related Examples
• “Designing Heterogeneous Class Hierarchies” on page 10-20
19-10
Class with Default Object Display
EmployeeInfo is also a handle class. Therefore instances of this class can be in the state referred to
as a handle to a deleted object. This state does not occur with value classes (classes not derived from
handle).
19-11
19 Customizing Object Display
>>Emp123 = EmployeeInfo;
Name: 'Bill Tork'
Job Title: 'Software Engineer'
Department: 'Product Development'
Salary: 1000
Password: 'bill123'
>>Emp123
Emp123 =
>>[Emp123,Emp124]
ans
Name
JobTitle
Department
Salary
Password
Empt =
Name
19-12
Class with Default Object Display
JobTitle
Department
Salary
Password
Use isempty to test for empty object arrays. An empty object array is not scalar because its
dimensions can never be 1–by-1.
emt =
Name
JobTitle
Department
Salary
Password
>> isscalar(emt)
ans =
>> delete(Emp123)
>> Emp123
Emp123 =
handle to deleted EmployeeInfo
Note isvalid is a handle class method. Calling isvalid on a value class object causes an error.
details(Emp123)
EmployeeInfo handle with properties:
19-13
19 Customizing Object Display
See Also
Related Examples
• “Custom Display Interface” on page 19-2
19-14
Choose a Technique for Display Customization
If you are making small changes to the default layout, then override the relevant part builder
methods (“Part Builder Methods” on page 19-4). For example, suppose you want to:
• Change the order or value of properties, display a subset of properties, or create property groups
• Modify the header text
• Add a footer
If you are defining a nonstandard display for a particular object state (scalar, for example), then the
best approach is to override the appropriate state handler method (“State Handler Methods” on page
19-5).
In some cases, a combination of method overrides might be the best approach. For example, your
implementation of displayScalarObject might
• Use some of the utility methods (“Utility Methods” on page 19-5) to build your own display strings
using parts from the default display
• Call a part builder method to get the default text for that particular part of the display
• Implement a completely different display for scalar objects.
Once you override any CustomDisplay method, MATLAB calls your override in all cases where the
superclass method would have been called. For example, if you override the getHeader method,
your override must handle all cases where a state handler method calls getHeader. (See “Methods
Called for a Given Object State” on page 19-7)
Use a nonstandard layout for scalar object display that is fully defined in the displayScalarObject
method:
classdef MyClass < matlab.mixin.CustomDisplay
...
methods (Access = protected)
function displayScalarObject(obj)
% Implement the custom display for scalar obj
19-15
19 Customizing Object Display
end
end
end
Use standard display layout, but create a custom property list for scalar and nonscalar display:
classdef MyClass < matlab.mixin.CustomDisplay
...
methods(Access = protected)
function groups = getPropertyGroups(obj)
% Return PropertyGroup instances
end
end
end
Use standard display layout, but create a custom property list for scalar only. Call the superclass
getPropertyGroups for the nonscalar case.
classdef MyClass < matlab.mixin.CustomDisplay
properties
Prop1
Prop2
Prop3
end
methods(Access = protected)
function groups = getPropertyGroups(obj)
if isscalar(obj)
% Scalar case: change order
propList = {'Prop2','Prop1','Prop3'};
groups = matlab.mixin.util.PropertyGroup(propList)
else
% Nonscalar case: call superclass method
groups = [email protected](obj);
end
end
end
end
Change the values displayed for some properties in the scalar case by creating property/value pairs in
a struct. This getPropertyGroups method displays only Prop1 and Prop2, and displays the value
of Prop2 as Prop1 divided by Prop3.
classdef MyClass < matlab.mixin.CustomDisplay
properties
Prop1
Prop2
Prop3
end
methods(Access = protected)
function groups = getPropertyGroups(obj)
if isscalar(obj)
% Specify the values to be displayed for properties
propList = struct('Prop1',obj.Prop1,...
'Prop2',obj.Prop1/obj.Prop3);
groups = matlab.mixin.util.PropertyGroup(propList)
else
% Nonscalar case: call superclass method
groups = [email protected](obj);
end
end
19-16
Choose a Technique for Display Customization
end
end
19-17
19 Customizing Object Display
Objective
Change the order and number of properties displayed for an object of your class.
In the default scalar object display, MATLAB displays all the public properties along with their values.
However, you want to display only Department, JobTitle, and Name, in that order. You can do this
by deriving from CustomDisplay and overriding the getPropertyGroups method.
Your override
• Defines method Access as protected to match the definition in the CustomDisplay superclass
• Creates a cell array of property names in the desired order
• Returns a PropertyGroup object constructed from the property list cell array
methods (Access = protected)
function propgrp = getPropertyGroups(~)
proplist = {'Department','JobTitle','Name'};
propgrp = matlab.mixin.util.PropertyGroup(proplist);
end
end
When you create a PropertyGroup object using a cell array of property names, MATLAB
automatically
The getPropertyGroups method is not called to create the display for a scalar handle to a deleted
object.
19-18
Customize Property Display
override of the getPropertyGroups method uses the default property display for nonscalar objects
by calling the superclass getPropertyGroups method. For scalar objects, the override:
• Changes the value displayed for the Password property to a '*' character for each character in
the password.
• Displays the text 'Not Available' for the Salary property.
methods (Access = protected)
function propgrp = getPropertyGroups(obj)
if ~isscalar(obj)
propgrp = [email protected](obj);
else
pd(1:length(obj.Password)) = '*';
propList = struct('Department',obj.Department,...
'JobTitle',obj.JobTitle,...
'Name',obj.Name,...
'Salary','Not available',...
'Password',pd);
propgrp = matlab.mixin.util.PropertyGroup(propList);
end
end
end
19-19
19 Customizing Object Display
See Also
Related Examples
• “Choose a Technique for Display Customization” on page 19-15
19-20
Customize Header, Property List, and Footer
Objective
Customize each of the three parts of the display — header, property groups, and footer.
Note This example uses the EmployeeInfo class described in the “Class with Default Object
Display” on page 19-11 section.
For properties:
• Nonscalar object arrays display a subset of property names in a different order than the default.
• Scalar objects create two property groups that have titles (Public Info and Personal Info).
• Add a footer to the display, only when the object is a valid scalar that displays property values.
Emp123 =
Public Info
Name: 'Bill Tork'
JobTitle: 'Software Engineer'
Personal Info
Salary: 1000
Password: 'bill123'
Company Private
19-21
19 Customizing Object Display
[Emp123,Emp124]
ans =
Department
Name
JobTitle
>> EmployeeInfo.empty(0,5)
ans =
Department
Name
JobTitle
>> delete(Emp123)
>> Emp123
Emp123 =
Implementation
• getHeader
• getPropertyGroups
• getFooter
Each method must produce the desired results with each of the following inputs:
• Scalar object
• Nonscalar object array
• Empty object array
• Nonscalar (including empty object) arrays call the superclass getHeader, which returns the
default header.
• Scalar handles to deleted objects do not result in a call to getHeader.
19-22
Customize Header, Property List, and Footer
• Scalar inputs build a custom header using the getClassNameForHeader static method to return
linked class name text, and the value of the Department property.
Here is the EmployeeInfo override of the getHeader method. The required protected access is
inherited from the superclass.
methods (Access = protected)
function header = getHeader(obj)
if ~isscalar(obj)
header = [email protected](obj);
else
className = matlab.mixin.CustomDisplay.getClassNameForHeader(obj);
newHeader = [className,' Dept: ',obj.Department];
header = sprintf('%s\n',newHeader);
end
end
end
getPropertyGroups Override
MATLAB calls getPropertyGroups to get the PropertyGroup objects, which control how
properties are displayed. This method override defines two different property lists depending on the
object’s state:
• For nonscalar inputs, including empty arrays and arrays containing handles to deleted objects,
create a property list as a cell array to reorder properties.
By default, MATLAB does not display property values for nonscalar inputs.
• For scalar inputs, create two property groups with titles. The scalar code branch lists properties in
a different order than the nonscalar case and includes Salary and Password properties.
MATLAB automatically assigns property values.
• Scalar handles to deleted objects do not result in a call to getPropertyGroups.
Here is the EmployeeInfo override of the getPropertyGroups method. The protected access is
inherited from the superclass.
methods (Access = protected)
function propgrp = getPropertyGroups(obj)
if ~isscalar(obj)
propList = {'Department','Name','JobTitle'};
propgrp = matlab.mixin.util.PropertyGroup(propList);
else
gTitle1 = 'Public Info';
gTitle2 = 'Personal Info';
propList1 = {'Name','JobTitle'};
propList2 = {'Salary','Password'};
propgrp(1) = matlab.mixin.util.PropertyGroup(propList1,gTitle1);
propgrp(2) = matlab.mixin.util.PropertyGroup(propList2,gTitle2);
end
end
end
getFooter Override
MATLAB calls getFooter to get the footer text. The EmployeeInfo getFooter method defines a
footer for the display, which is included only when the input is a valid scalar object. In all other cases,
getFooter returns an empty char vector.
19-23
19 Customizing Object Display
19-24
Customize Header, Property List, and Footer
See Also
Related Examples
• “Choose a Technique for Display Customization” on page 19-15
19-25
19 Customizing Object Display
Objective
Customize the display of scalar objects.
Note This example uses the EmployeeInfo class described in the “Class with Default Object
Display” on page 19-11 section.
• Modify the header to include the department name obtained from the Department property
• Group properties into two categories titled Public Info and Personal Info.
• Modify which properties are displayed
• Modify the values displayed for Personal Info category
• Use the default displayed for nonscalar objects, including empty arrays, and scalar deleted
handles
For example, here is the customized display of an object of the EmployeeInfo class.
Emp123 =
Public Info
Name: 'Bill Tork'
JobTitle: 'Software Engineer'
Personal Info
Salary: 'Level: 10'
Password: '*******'
Implementation
19-26
Customize Display of Scalar Objects
This implementation:
• Builds a custom header using the getClassNameForHeader static method to return linked class
name text and the value of the Department property to get the department name.
• Uses sprintf to add a new line to the header text
• Displays the header with the built-in disp function.
• Calls the getPropertyGroups override to define the property groups (see following section).
• Displays the property groups using the displayPropertyGroups static method.
Here is the EmployeeInfo override of the displayScalarObject method. The required protected
access is inherited from the superclass.
methods (Access = protected)
function displayScalarObject(obj)
className = matlab.mixin.CustomDisplay.getClassNameForHeader(obj);
scalarHeader = [className,' Dept: ',obj.Department];
header = sprintf('%s\n',scalarHeader);
disp(header)
propgroup = getPropertyGroups(obj);
matlab.mixin.CustomDisplay.displayPropertyGroups(obj,propgroup)
end
end
getPropertyGroups Override
MATLAB calls getPropertyGroups when displaying scalar or nonscalar objects. However, MATLAB
does not call this method when displaying a scalar handle to a deleted object.
The EmployeeInfo class overrides this method to implement the property groups for scalar object
display.
This implementation calls the superclass getPropertyGroups method if the input is not scalar. If
the input is scalar, this method:
Here is the EmployeeInfo override of the getPropertyGroups method. The required protected
access is inherited from the superclass.
methods (Access = protected)
function propgrp = getPropertyGroups(obj)
19-27
19 Customizing Object Display
if ~isscalar(obj)
propgrp = [email protected](obj);
else
gTitle1 = 'Public Info';
gTitle2 = 'Personal Info';
propList1 = {'Name','JobTitle'};
pd(1:length(obj.Password)) = '*';
level = round(obj.Salary/100);
propList2 = struct('Salary',...
['Level: ',num2str(level)],...
'Password',pd);
propgrp(1) = matlab.mixin.util.PropertyGroup(propList1,gTitle1);
propgrp(2) = matlab.mixin.util.PropertyGroup(propList2,gTitle2);
end
end
end
19-28
Customize Display of Scalar Objects
See Also
Related Examples
• “Choose a Technique for Display Customization” on page 19-15
19-29
19 Customizing Object Display
Objective
Customize the display of nonscalar objects, including empty object arrays.
Note This example uses the EmployeeInfo class described in the “Class with Default Object
Display” on page 19-11 section.
2. Employee:
Name: 'Alice Blackwell'
Department: 'QE'
3. Employee:
Name: 'Nancy Green'
Department: 'Documentation'
1. Employee:
Name: 'Bill Tork'
Department: 'Product Development'
19-30
Customize Display of Object Arrays
3. Employee:
Name: 'Nancy Green'
Department: 'Documentation'
To achieve the desired result, the EmployeeInfo class overrides the following methods of the
matlab.mixin.CustomDisplay class:
• Builds header text using convertDimensionsToString to obtain the array size and
getClassNameForHeader to get the class name with a link to the help for that class.
• Displays the modified header text.
• Loops through the elements in the array, building two different subheaders depending on the
individual object state. In the loop, this method:
• Detects handles to deleted objects (using the isvalid handle class method). Uses
getDeletedHandleText and getClassNameForHeader to build text for array elements that
are handles to deleted objects.
• Builds a custom subheader for valid object elements in the array
• Creates a PropertyGroup object containing the Name and Department properties for valid
objects
• Uses the displayPropertyGroups static method to generate the property display for valid
objects.
19-31
19 Customizing Object Display
• Gets the array dimensions in character format using the convertDimensionsToString static
method.
• Gets text with the class name linked to the helpPopup function using the
getClassNameForHeader static method.
• Builds and displays the custom text for empty arrays.
methods (Access = protected)
function displayEmptyObject(obj)
dimstr = matlab.mixin.CustomDisplay.convertDimensionsToString(obj);
className = matlab.mixin.CustomDisplay.getClassNameForHeader(obj);
emptyHeader = [dimstr,' ',className,' with no employee information'];
header = sprintf('%s\n',emptyHeader);
disp(header)
end
end
Empt = EmployeeInfo.empty(0,5)
Empt =
19-32
Customize Display of Object Arrays
else
numStr = [num2str(ix),'. Employee'];
disp(numStr)
propList = struct('Name',o.Name,...
'Department',o.Department);
propgrp = matlab.mixin.util.PropertyGroup(propList);
matlab.mixin.CustomDisplay.displayPropertyGroups(o,propgrp);
end
end
end
function displayEmptyObject(obj)
dimstr = matlab.mixin.CustomDisplay.convertDimensionsToString(obj);
className = matlab.mixin.CustomDisplay.getClassNameForHeader(obj);
emptyHeader = [dimstr,' ',className,' with no employee information'];
header = sprintf('%s\n',emptyHeader);
disp(header)
end
end
end
See Also
Related Examples
• “Choose a Technique for Display Customization” on page 19-15
19-33
19 Customizing Object Display
Display Methods
Subclassing matlab.mixin.CustomDisplay is the best approach to customizing object display.
However, if you do not derive your class from matlab.mixin.CustomDisplay, overload the disp
function to change how MATLAB displays objects of your class.
MATLAB calls the display function 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. MATLAB
calls display, which displays the value of a in the command line.
a = 5
a =
5
Overloaded disp
The built-in display function prints the name of the variable that is being displayed, if an
assignment is made, or otherwise uses ans as the variable name. Then display calls disp to handle
the actual display of the values.
If the variable that is being displayed is an object of a class that overloads disp, then MATLAB
always calls the overloaded method. MATLAB calls display with two arguments and passes the
variable name as the second argument.
• MATLAB executes a statement that returns a value and is not terminated with a semicolon.
• There is no left-side variable, then MATLAB prints ans = followed by the value.
• Code explicitly invokes the display function.
• If the input argument is an existing variable, display prints the variable name and equal sign,
followed by the value.
• If the input is the result of an expression, display does not print ans =.
MATLAB invokes the built-in disp function when the following occurs:
19-34
Overloading the disp Function
For empty built-in types (numeric types, char, struct, and cell) the display function displays:
See Also
Related Examples
• “Custom Display Interface” on page 19-2
• “Overload disp for DocPolynom” on page 20-13
19-35
20
In this section...
“Object Requirements” on page 20-2
“DocPolynom Class Members” on page 20-2
“DocPolynom Class Synopsis” on page 20-4
“The DocPolynom Constructor” on page 20-10
“Remove Irrelevant Coefficients” on page 20-11
“Convert DocPolynom Objects to Other Types” on page 20-11
“Overload disp for DocPolynom” on page 20-13
“Display Evaluated Expression” on page 20-13
“Redefine Indexed Reference” on page 20-14
“Define Arithmetic Operators” on page 20-16
Object Requirements
This example implements a class to represent polynomials in the MATLAB language. The design
requirements are:
• Value class behavior—a polynomial object should behave like MATLAB numeric variables when
copied and passed to functions.
• Specialized display and indexing
• Objects can be scalar only. The specialization of display and indexing functionality preclude
normal array behavior.
• Arithmetic operations
• Double converter simplifying the use of polynomial object with existing MATLAB functions that
accept numeric inputs.
The following table summarizes the properties defined for the DocPolynom class.
The following table summarizes the methods for the DocPolynom class.
20-2
Representing Polynomials with Classes
Create DocPolynom objects to represent the following polynomials. The argument to the constructor
function contains the polynomial coefficients and .
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 by passing the coefficients to the roots function.
roots(p1.coef)
ans =
2.0946 + 0.0000i
-1.0473 + 1.1359i
-1.0473 - 1.1359i
MATLAB calls the plus method defined for the DocPolynom class when you add two DocPolynom
objects.
p1 + p2
ans =
20-3
20 Defining Custom Data Types
20-4
Representing Polynomials with Classes
20-5
20 Defining Custom Data Types
20-6
Representing Polynomials with Classes
function r = mtimes(obj1,obj2)
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
r = DocPolynom(conv(obj1.coef,obj2.coef));
end
end
end end statements for methods and for
end
classdef.
classdef DocPolynom
% Documentation example
% A value class that implements a data type for polynomials
% See Implementing a Class for Polynomials in the
% MATLAB documentation for more information.
properties
coef
end
% Class methods
methods
function obj = DocPolynom(c)
if nargin > 0
if isa(c,'DocPolynom')
obj.coef = c.coef;
else
obj.coef = c(:).';
end
end
end % DocPolynom
function obj = set.coef(obj,val)
if ~isa(val,'double')
error('Coefficients must be doubles')
end
% Remove leading zeros
20-7
20 Defining Custom Data Types
ind = find(val(:).'~=0);
if ~isempty(ind);
obj.coef = val(ind(1):end);
else
obj.coef = val;
end
end % set.coef
function c = double(obj)
c = obj.coef;
end % double
20-8
Representing Polynomials with Classes
end
str = [s{:}];
end % char
function disp(obj)
% DISP Display object in MATLAB syntax
c = char(obj);
if iscell(c)
disp([' ' c{:}])
else
disp(c)
end
end % disp
function dispPoly(obj,x)
% evaluate obj at x
p = char(obj);
e = @(x)eval(p);
y = zeros(length(x));
disp(['y = ',p])
for k = 1:length(x)
y(k) = e(x(k));
disp([' ',num2str(y(k)),...
' = f(x = ',...
num2str(x(k)),')'])
end
end
function b = subsref(a,s)
% SUBSREF Implementing the following syntax:
% obj([1 ...])
% obj.coef
% obj.disp
% out = obj.method(args)
% out = obj.method
switch s(1).type
case '()'
ind = s.subs{:};
b = polyval(a.coef,ind);
case '.'
switch s(1).subs
case 'coef'
b = a.coef;
case 'disp'
disp(a)
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 % subsref
function r = plus(obj1,obj2)
20-9
20 Defining Custom Data Types
function r = minus(obj1,obj2)
% MINUS Implement obj1 - obj2 for DocPolynoms.
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
k = length(obj2.coef) - length(obj1.coef);
zp = zeros(1,k);
zm = zeros(1,-k);
r = DocPolynom([zp,obj1.coef] - [zm,obj2.coef]);
end % minus
function r = mtimes(obj1,obj2)
% MTIMES Implement obj1 * obj2 for DocPolynoms.
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
r = DocPolynom(conv(obj1.coef,obj2.coef));
end % mtimes
end % methods
end % classdef
• Input argument is a DocPolynom object — If you call the constructor function with an input
argument that is already a DocPolynom object, the constructor returns a new DocPolynom object
with the same coefficients as the input argument. The isa function checks for this input.
• Input argument is a coefficient vector — If the input argument is not a DocPolynom object, the
constructor attempts to reshape the values into a vector and assign them to the coef property.
The coef property set method restricts property values to doubles. See “Remove Irrelevant
Coefficients” on page 20-11 for a description of the property set method.
20-10
Representing Polynomials with Classes
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 that
the display of the object shows 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.
methods
function obj = set.coef(obj,val)
if ~isa(val,'double')
error('Coefficients must be doubles')
end
ind = find(val(:).'~=0);
if ~isempty(ind);
obj.coef = val(ind(1):end);
else
obj.coef = val;
end
end
end
• double — Converts to the double numeric type so functions can perform mathematical operations
on the coefficients.
• char — Converts to characters used to format output for display in the command window
The double converter method for the DocPolynom class simply returns the coefficient vector:
methods
function c = double(obj)
c = obj.coef;
end
end
20-11
20 Defining Custom Data Types
the statement:
c = double(p)
returns:
c=
1 0 -2 -5
The char method produces a char vector that represents the polynomial displayed as powers of x.
The char vector returned is a syntactically correct MATLAB expression.
The char method uses a cell array to collect the char vector components that make up the displayed
polynomial.
The disp method uses the char method to format the DocPolynom object for display. The evalPoly
method uses char to create the MATLAB expression to evaluate.
Users of DocPolynom objects 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.
20-12
Representing Polynomials with Classes
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
end
This disp method relies on the char method to produce a text representation of the polynomial,
which it then displays on the screen.
The char method returns a cell array or the character '0' if the coefficients are all zero.
methods
function disp(obj)
c = char(obj);
if iscell(c)
disp([' ' c{:}])
else
disp(c)
end
end
end
The statement:
p = DocPolynom([1 0 -2 -5])
creates a DocPolynom object. Because the statement is not terminated with a semicolon, the
resulting output is displayed on the command line:
p =
x^3 - 2*x - 5
methods
function dispPoly(obj,x)
p = char(obj);
e = @(x)eval(p);
20-13
20 Defining Custom Data Types
y = zeros(length(x));
disp(['y = ',p])
for k = 1:length(x)
y(k) = e(x(k));
disp([' ',num2str(y(k)),...
' = f(x = ',...
num2str(x(k)),')'])
end
end
end
p = DocPolynom([1 0 -2 -5])
p =
x^3 - 2*x - 5
dispPoly(p,[3 5 9])
y = x^3 - 2*x - 5
16 = f(x = 3)
110 = f(x = 5)
706 = f(x = 9)
p = DocPolynom([1 0 -2 -5])
p =
x^3 - 2*x - 5
The following subscripted expression evaluates the value of the polynomial at x = 3 and at x = 4,
and returns the resulting values:
p([3 4])
ans =
16 51
20-14
Representing Polynomials with Classes
If a class defines a subsref method, MATLAB calls this method for objects of this class whenever a
subscripted reference occurs. The subsref method must define all the indexed reference behaviors,
not just a specific case that you want to change.
p = DocPolynom([1 0 -2 -5])
p =
x^3 - 2*x - 5
polyval(p.coef,[3 5 7])
ans =
16 110 324
• Polynomial coefficients
• Values of the independent variable at which to evaluate the polynomial
The polyval function returns the value of f(x) at these values. subsref calls polyval through the
statements:
case '()'
ind = s.subs{:};
b = polyval(a.coef,ind);
When implementing subsref to support method calling with arguments using dot notation, both the
type and subs structure fields contain multiple elements.
The subsref method implements all subscripted reference explicitly, as show in the following code
listing.
methods
function b = subsref(a,s)
switch s(1).type
case '()'
ind = s.subs{:};
b = polyval(a.coef,ind);
case '.'
switch s(1).subs
case 'coef'
b = a.coef;
20-15
20 Defining Custom Data Types
case 'disp'
disp(a)
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
end
When overloading arithmetic operators, consider the data types you must support. The plus, minus,
andmtimes methods are defined for the DocPolynom class to handle addition, subtraction, and
multiplication on DocPolynom — DocPolynom and DocPolynom — double combinations of
operands.
Define + Operator
Generates a call to a function @DocPolynom/plus, unless the other object is of higher precedence.
The following method overloads the plus (+) operator for the DocPolynom class:
methods
function r = plus(obj1,obj2)
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
k = length(obj2.coef) - length(obj1.coef);
zp = zeros(1,k);
zm = zeros(1,-k);
r = DocPolynom([zp,obj1.coef] + [zm,obj2.coef]);
end
end
• Ensure that both input arguments are DocPolynom objects so that expressions such as
p + 1
20-16
Representing Polynomials with Classes
• Access the two coefficient vectors and, if necessary, pad one of them with zeros to make both the
same length. The actual addition is simply the vector sum of the two coefficient vectors.
• Call the DocPolynom constructor to create a properly typed object that is the result of adding the
polynomials.
Define - Operator
Implement the minus operator (-) using the same approach as the plus (+) operator.
The minus method computes p - q. The dominant argument must be a DocPolynom object.
methods
function r = minus(obj1,obj2)
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
k = length(obj2.coef) - length(obj1.coef);
zp = zeros(1,k);
zm = zeros(1,-k);
r = DocPolynom([zp,obj1.coef] - [zm,obj2.coef]);
end
end
Implement the mtimes method to compute the product p*q. The mtimes method implements matrix
multiplication since the multiplication of two polynomials is the convolution (conv) of their coefficient
vectors:
methods
function r = mtimes(obj1,obj2)
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
r = DocPolynom(conv(obj1.coef,obj2.coef));
end
end
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
20-17
21
A class design based on heterogeneous arrays provides a more convenient interface than, for
example, extracting elements from a cell array and operating on these elements individually. For
more information on the design of class hierarchies that support heterogeneous arrays, see
“Designing Heterogeneous Class Hierarchies” on page 10-20.
Note This example does not use valid terminology or techniques for managing financial assets. The
purpose of this example is only to illustrate techniques for defining heterogeneous class hierarchies.
This example implements a system of classes to represent financial assets, such as stocks, bonds, and
cash. Classes to represent categories of assets have certain common requirements. Each instance has
one of the following:
• Textual description
• Type (stock, bond, or cash)
• Means to determine the current value of the asset
Heterogeneous arrays of these objects need methods that can operate on the whole array. These
operations include:
These requirements are factored into the class that is the root of the hierarchy. The root class derives
from matlab.mixin.Heterogeneous. In the following diagram, the Assets class is the root of the
21-2
A Class Hierarchy for Heterogeneous Arrays
hierarchy. The Stocks, Bonds, and Cash classes provide the specialization required for each type of
asset.
21-3
21 Designing Related Classes
Assets Class
The Assets class:
Properties
Methods
• pie — A sealed method that creates a pie chart showing the relative mix of asset types.
• makeReport — A sealed method that creates a report listing the assets.
• getCurrentValue — An abstract method that each concrete subclass must implement to return
the current value of the asset.
• getDefaultScalarElement — matlab.mixin.Heterogeneous class method overridden in
the Assets class to specify a default object. The Assets class is abstract so it cannot be used as
the default object. For more information, see “Default Object” on page 21-9.
Concrete methods defined by superclasses in a heterogeneous hierarchy must specify the Sealed
attribute. Sealing these methods prevents subclasses from overriding methods implemented by the
superclass. When calling methods on a heterogeneous array, MATLAB calls the methods defined by
the class of the array (Assets in this example).
The pie and makeReport methods are examples of sealed methods that operate on heterogeneous
arrays composed of Stock, Bond, and Cash objects.
Abstract methods defined by the superclasses in a heterogeneous hierarchy must specify the
Abstract attribute. Defining an abstract method in a superclass ensures that concrete subclasses
have an implementation for that exact method name. Use these methods element-wise so that each
object calls its own method.
Each type of subclass object calculates its current value in a different way. If you add another
category of asset by adding another subclass to the hierarchy, this class must implement its own
21-4
A Class Hierarchy for Heterogeneous Arrays
For more information on the Sealed and Abstract method attributes, see “Method Attributes” on
page 9-4.
The Assets class and other classes in the hierarchy are contained in a package called financial.
classdef Assets < matlab.mixin.Heterogeneous
% file: +financial.@Assets/Assets.m
properties
Description char = 'Assets'
end
properties (Abstract, SetAccess = private)
Type
end
methods (Abstract)
% Not implemented by Assets class
value = getCurrentValue(obj)
end
methods (Static, Sealed, Access = protected)
function defaultObject = getDefaultScalarElement
defaultObject = financial.DefaultAsset;
end
end
methods (Sealed)
% Implemented in separate files
% +financial.@Assets/pie.m
% +financial.@Assets/makeReport.m
pie(assetArray)
makeReport(assetArray)
end
end
For code listings for pie and makeReport, see “Operating on an Assets Array” on page 21-11.
Stocks Class
The Stocks class represents a specific type of financial asset. It is a concrete class that implements
the abstract members defined by the Assets class, and defines class properties and methods specific
to this type of asset.
Properties
21-5
21 Designing Related Classes
Methods
• Stocks — The constructor assigns property values and supports a default constructor called with
no input arguments.
• getCurrentValue — This method is the Stocks class implementation of the abstract method
defined by the Assets class. It returns the current value of this asset.
• get.SharePrice — The property get method for the dependent SharePrice property returns
the current share price of this stock. For information on how to access web services from
MATLAB, see the webread function.
Bonds Class
The Bonds class represents a specific type of financial asset. It is a concrete class that implements
the abstract members defined by the Assets class and defines class properties and methods specific
to this type of asset.
21-6
A Class Hierarchy for Heterogeneous Arrays
Properties
Methods
• Bonds — The constructor assigns property values and supports a default constructor called with
no input arguments.
• getCurrentVlaue — This method is the Bonds class implementation of the abstract method
defined by the Assets class. It returns the current value of this asset.
• get.CurrentYield — The property get method for the dependent CurrentYield property
returns the current yield on this bond. For information on how to access web serviced from
MATLAB, see the webread function.
21-7
21 Designing Related Classes
mv = b.FaceValue*y/cy;
end
end
function r = get.CurrentYield(b)
% Implement web access to obtain
% Current yield for this bond
% Returning dummy value
r = 0.24;
end
end
end
Cash Class
The Cash class represents a specific type of financial asset. It is a concrete class that implements the
abstract members defined by the Assets class and defines class properties and methods specific to
this type of asset.
Properties
Methods
• Cash — The constructor assigns property values and supports a default constructor called with no
input arguments.
• getCurrentValue — This method is the Cash class implementation of the abstract method
defined by the Assets class. It returns the current value of this asset.
• save — This method adds the specified amount of cash to the existing amount and returns a new
Cash object with the current amount.
• spend — This method deducts the specified amount from the current amount and returns a new
Cash object with the current amount.
21-8
A Class Hierarchy for Heterogeneous Arrays
end
c.Description = description;
c.Amount = amount;
end
function value = getCurrentValue(c)
value = c.Amount;
end
function c = save(c,amount)
newValue = c.Amount + amount;
c.Amount = newValue;
end
function c = spend(c,amount)
newValue = c.Amount - amount;
if newValue < 0
c.Amount = 0;
disp('Your balance is $0.00')
else
c.Amount = newValue;
end
end
end
end
Default Object
The design of this class hierarchy uses an abstract root class (Assets). Therefore, the Assets class
must specify a concrete class to use as a default object by overriding getDefaultScalarElement.
In this case, options include:
• Use one of the existing concrete classes for the default object.
• Define a concrete class in the hierarchy to use for the default object.
This implementation adds the DefaultAsset class to the hierarchy as a subclass of the Assets
class. MATLAB creates objects of this class when:
21-9
21 Designing Related Classes
21-10
A Class Hierarchy for Heterogeneous Arrays
end
methods
function obj = DefaultAsset
obj.Description = 'Place holder';
end
function value = getCurrentValue(~)
value = 0;
end
end
end
• pie — Creates a pie chart showing the mix of asset types in the array.
• makeReport — Uses the MATLAB table object to display a table of asset information.
To operate on a heterogeneous array, a method must be defined for the class of the heterogeneous
array and must be sealed. In this case, the class of heterogeneous arrays is always the Assets class.
MATLAB does not use the class of the individual elements of the heterogeneous array when
dispatching to methods.
The Assets class makeReport method builds a table using the common properties and
getCurrentValue method for each object in the array.
function makeReport(obj)
numMembers = length(obj);
descs = cell(1,numMembers);
types(numMembers) = "";
values(numMembers) = 0;
for k = 1:numMembers
descs{k} = obj(k).Description;
types(k) = obj(k).Type;
values(k) = obj(k).getCurrentValue;
end
t = table;
t.Description = descs';
t.Type = types';
t.Value = values';
disp(t)
end
The Assets class pie method calls the getCurrentValue method element-wise on objects in the
array to obtain the data for the pie chart.
function pie(assetArray)
stockAmt = 0; bondAmt = 0; cashAmt = 0;
for k=1:length(assetArray)
if isa(assetArray(k),'financial.Stocks')
stockAmt = stockAmt + assetArray(k).getCurrentValue;
elseif isa(assetArray(k),'financial.Bonds')
21-11
21 Designing Related Classes
These statements create a heterogeneous array by concatenating the Stocks, Bonds, and Cash
objects. Calling the makeReport and pie methods creates the output shown.
21-12
A Class Hierarchy for Heterogeneous Arrays
See Also
Related Examples
• “Designing Heterogeneous Class Hierarchies” on page 10-20
• “Validate Property Values” on page 8-20
• “Set and Get Methods for Dependent Properties” on page 8-49
21-13