Matlab Oop PDF
Matlab Oop PDF
Object-Oriented Programming
R2016a
www.mathworks.com
www.mathworks.com/sales_and_services
User community:
www.mathworks.com/matlabcentral
Technical support:
www.mathworks.com/support/contact_us
Phone:
508-647-7000
Trademarks
MATLAB and Simulink are registered trademarks of The MathWorks, Inc. See
www.mathworks.com/trademarks for a list of additional trademarks. Other product or brand
names may be trademarks or registered trademarks of their respective holders.
Patents
MathWorks products are protected by one or more U.S. patents. Please see
www.mathworks.com/patents for more information.
Revision History
March 2008
October 2008
March 2009
September 2009
March 2010
September 2010
April 2011
September 2011
March 2012
September 2012
March 2013
September 2013
March 2014
October 2014
March 2015
September 2015
March 2016
Online only
Online only
Online only
Online only
Online only
Online only
Online only
Online only
Online only
Online only
Online only
Online only
Online only
Online only
Online only
Online only
Online only
Contents
1-2
1-2
1-6
Using Handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
What Is a Handle? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Copies of Handles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Handle Objects Modified in Functions . . . . . . . . . . . . . . . . .
Determine If an Object Is a Handle . . . . . . . . . . . . . . . . . .
Deleted Handle Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1-12
1-12
1-12
1-13
1-15
1-15
Basic Example
A Simple Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Define a Simple Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Create Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Access Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Call Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Add Constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Vectorize Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Overload Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
BasicClass Code Listing . . . . . . . . . . . . . . . . . . . . . . . . . . .
2-2
2-2
2-3
2-3
2-3
2-4
2-5
2-6
2-6
vi
Contents
3-2
3-2
3-4
3-8
3-8
3-9
3-10
3-14
3-15
3-15
3-16
3-19
3-19
3-19
3-19
3-21
3-24
3-24
3-24
3-25
3-25
3-26
3-27
3-28
3-29
3-30
3-31
3-36
3-36
3-36
3-37
3-38
3-39
3-50
Static Data
Static Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
What Is Static Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Static Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Static Data Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Constant Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3-53
3-53
3-54
3-55
4-2
4-2
4-2
4-3
4-5
5-2
5-2
5-2
5-2
5-3
Class Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Class Building Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Class Definition Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Properties Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Methods Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Events Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A Complete Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Enumeration Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Related Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5-5
5-5
5-5
5-6
5-6
5-7
5-7
5-8
5-9
Classdef Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
How to Specify Attributes and Superclasses . . . . . . . . . . . .
Class Attribute Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Superclass Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5-10
5-10
5-10
5-11
vii
viii
Contents
5-11
Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
The Properties Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Access to Property Values . . . . . . . . . . . . . . . . . . . . . . . . . .
5-12
5-12
5-13
5-15
5-15
5-15
5-17
5-17
5-17
5-18
5-18
5-20
5-20
5-20
Attribute Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Attribute Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Attribute Descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Attribute Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Simpler Syntax for true/false Attributes . . . . . . . . . . . . . . .
5-22
5-22
5-22
5-23
5-23
5-25
5-25
5-26
5-27
5-27
5-29
5-32
5-32
5-32
5-33
5-34
5-34
5-34
5-36
5-38
Operations on Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Object Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Help on Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Functions to Test Objects . . . . . . . . . . . . . . . . . . . . . . . . . .
Functions to Query Class Components . . . . . . . . . . . . . . . .
5-41
5-41
5-42
5-44
5-44
5-45
5-45
5-45
5-46
5-47
5-47
5-48
5-48
5-49
5-49
5-49
5-49
5-50
5-50
5-51
5-52
5-53
5-55
5-55
5-56
5-56
5-57
5-58
5-58
5-59
5-63
5-64
ix
Contents
6-2
6-2
6-2
6-3
6-3
6-3
6-3
6-4
Class Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Specifying Class Attributes . . . . . . . . . . . . . . . . . . . . . . . . . .
Specifying Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6-6
6-6
6-7
6-9
6-9
6-9
6-12
6-12
6-12
6-16
6-16
6-16
6-17
6-17
6-18
6-19
Class Precedence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Use of Class Precedence . . . . . . . . . . . . . . . . . . . . . . . . . . .
Why Mark Classes as Inferior . . . . . . . . . . . . . . . . . . . . . . .
InferiorClasses Attribute . . . . . . . . . . . . . . . . . . . . . . . . . . .
6-22
6-22
6-22
6-22
6-24
6-24
6-25
6-25
6-26
6-27
Import Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Syntax for Importing Classes . . . . . . . . . . . . . . . . . . . . . . .
Import Package Functions . . . . . . . . . . . . . . . . . . . . . . . . . .
Package Function and Class Method Name Conflict . . . . . .
Clearing Import List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6-29
6-29
6-29
6-30
6-30
7-2
7-2
7-3
7-4
7-5
7-7
7-9
7-11
7-11
7-11
7-12
7-13
7-13
7-13
7-14
7-14
7-14
7-14
7-16
7-16
7-16
7-17
7-18
7-18
7-20
7-20
7-21
xi
xii
Contents
7-24
7-24
7-24
7-25
7-25
7-25
7-26
7-26
7-27
7-32
7-32
7-33
7-35
7-38
7-38
7-38
8-2
8-2
8-2
Property Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Property Definition Block . . . . . . . . . . . . . . . . . . . . . . . . . . .
Access Property Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Inheritance of Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Specify Property Attributes . . . . . . . . . . . . . . . . . . . . . . . . . .
8-4
8-4
8-5
8-6
8-6
Property Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Purpose of Property Attributes . . . . . . . . . . . . . . . . . . . . . . .
Specifying Property Attributes . . . . . . . . . . . . . . . . . . . . . . .
Table of Property Attributes . . . . . . . . . . . . . . . . . . . . . . . . .
8-7
8-7
8-7
8-7
Defining Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
What You Can Define . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8-13
8-13
8-13
8-14
8-14
8-15
8-15
8-16
8-17
8-18
8-18
8-18
8-20
8-20
8-20
8-21
8-23
8-23
8-23
8-26
8-27
8-27
8-27
8-29
8-29
8-29
8-30
8-30
8-32
8-32
8-32
8-32
8-33
8-33
8-34
8-34
8-35
8-35
8-36
xiii
xiv
Contents
8-38
8-38
8-38
8-38
8-41
8-41
8-42
8-45
8-45
8-46
8-47
8-47
8-47
8-48
8-49
8-50
8-50
8-51
9-2
9-2
9-3
Method Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Purpose of Method Attributes . . . . . . . . . . . . . . . . . . . . . . . .
Specifying Method Attributes . . . . . . . . . . . . . . . . . . . . . . . .
Table of Method Attributes . . . . . . . . . . . . . . . . . . . . . . . . . .
9-5
9-5
9-5
9-5
Ordinary Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Ordinary Methods Operate on Objects . . . . . . . . . . . . . . . . .
Methods Inside classdef Block . . . . . . . . . . . . . . . . . . . . . . . .
Method Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9-7
9-7
9-7
9-8
9-10
9-10
9-11
9-11
9-12
Method Invocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Determining Which Method Is Invoked . . . . . . . . . . . . . . . .
Referencing Names with ExpressionsDynamic Reference .
Controlling Access to Methods . . . . . . . . . . . . . . . . . . . . . . .
Invoking Superclass Methods in Subclass Methods . . . . . . .
Invoking Built-In Functions . . . . . . . . . . . . . . . . . . . . . . . .
9-14
9-14
9-16
9-17
9-18
9-19
9-20
9-20
9-20
9-21
9-21
9-22
9-23
9-25
9-26
9-27
Static Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
What Are Static Methods . . . . . . . . . . . . . . . . . . . . . . . . . .
Why Define Static Methods . . . . . . . . . . . . . . . . . . . . . . . . .
Defining Static Methods . . . . . . . . . . . . . . . . . . . . . . . . . . .
Calling Static Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Inheriting Static Methods . . . . . . . . . . . . . . . . . . . . . . . . . .
9-28
9-28
9-28
9-28
9-29
9-29
9-30
9-30
9-30
9-32
9-34
9-34
9-35
9-36
9-44
9-44
xv
10
xvi
Contents
9-45
9-46
9-46
9-46
9-46
9-48
9-49
9-49
9-49
9-50
Object Arrays
Construct Object Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Build Arrays in the Constructor . . . . . . . . . . . . . . . . . . . . .
Referencing Property Values in Object Arrays . . . . . . . . . . .
10-2
10-2
10-3
10-5
10-5
10-6
Empty Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Creating Empty Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Assigning Values to an Empty Array . . . . . . . . . . . . . . . . .
10-8
10-8
10-8
10-10
10-11
10-13
10-15
10-15
10-15
10-16
10-16
10-18
11
Heterogeneous Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
MATLAB Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Heterogeneous Hierarchies . . . . . . . . . . . . . . . . . . . . . . . .
Heterogeneous Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Heterogeneous Array Concepts . . . . . . . . . . . . . . . . . . . . .
Nature of Heterogeneous Arrays . . . . . . . . . . . . . . . . . . . .
Unsupported Hierarchies . . . . . . . . . . . . . . . . . . . . . . . . . .
Default Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Conversion During Assignment and Concatenation . . . . . .
Empty Arrays of Heterogeneous Abstract Classes . . . . . . .
10-21
10-21
10-21
10-22
10-22
10-23
10-26
10-28
10-29
10-29
10-31
10-31
10-31
10-32
10-33
10-35
11-2
11-2
11-2
11-3
11-4
11-6
11-6
11-6
11-7
11-8
11-9
11-11
11-11
11-14
11-14
xvii
xviii
Contents
Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Default Event Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Events Only in Handle Classes . . . . . . . . . . . . . . . . . . . . .
Property-Set and Query Events . . . . . . . . . . . . . . . . . . . . .
Listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11-15
11-16
11-16
11-17
11-17
Event Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Specify Event Attributes . . . . . . . . . . . . . . . . . . . . . . . . . .
11-19
11-19
11-21
11-21
11-21
11-22
11-22
11-25
Listener Lifecycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Control Listener Lifecycle . . . . . . . . . . . . . . . . . . . . . . . . .
Temporarily Deactivate Listeners . . . . . . . . . . . . . . . . . . .
Permanently Delete Listeners . . . . . . . . . . . . . . . . . . . . . .
11-27
11-27
11-27
11-28
11-29
11-29
11-29
11-30
Callback Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
When Callbacks Execute . . . . . . . . . . . . . . . . . . . . . . . . . .
Listener Order of Execution . . . . . . . . . . . . . . . . . . . . . . .
Callbacks That Call notify . . . . . . . . . . . . . . . . . . . . . . .
Manage Callback Errors . . . . . . . . . . . . . . . . . . . . . . . . . .
Invoke Functions from Function Handles . . . . . . . . . . . . .
11-32
11-32
11-32
11-32
11-33
11-33
11-34
11-34
11-34
11-34
11-35
11-37
11-37
11-39
12
11-41
11-41
11-41
11-41
11-45
11-45
11-46
11-46
11-47
11-49
11-49
11-51
11-55
11-58
11-59
11-60
12-2
12-2
12-3
12-4
12-4
12-5
12-7
12-7
12-7
12-9
12-9
12-10
12-11
12-13
12-15
12-15
xix
xx
Contents
12-15
12-16
12-17
12-18
12-18
12-18
12-20
12-20
12-21
12-22
12-22
12-22
12-22
12-24
12-25
12-25
12-26
12-26
12-27
12-28
12-32
12-33
12-34
12-35
12-36
12-36
12-36
12-37
12-39
12-41
12-42
12-44
12-44
12-44
12-45
12-45
12-45
12-46
12-48
12-48
12-49
12-50
12-51
12-51
12-53
12-53
12-53
12-54
12-61
12-61
12-61
12-61
12-62
12-62
12-64
12-67
12-69
12-69
12-69
12-70
12-71
12-73
12-74
12-75
12-75
12-75
12-75
12-76
12-77
12-78
12-78
xxi
13
xxii
Contents
12-78
12-79
12-80
Abstract Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Abstract Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Declare Classes as Abstract . . . . . . . . . . . . . . . . . . . . . . .
Determine If a Class Is Abstract . . . . . . . . . . . . . . . . . . . .
Find Inherited Abstract Properties and Methods . . . . . . . .
12-82
12-82
12-83
12-84
12-85
12-87
12-87
12-87
13-2
13-2
13-2
13-2
13-3
13-4
13-4
13-4
13-4
13-5
13-6
13-6
13-6
13-7
13-8
13-8
13-8
13-10
13-10
13-10
13-12
13-14
13-14
13-14
13-14
13-15
13-17
13-17
13-18
13-21
13-21
13-23
13-24
13-25
13-28
13-28
13-28
13-30
13-30
13-30
Restore Listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Create Listener with loadobj . . . . . . . . . . . . . . . . . . . . .
Use Transient Property to Load Listener . . . . . . . . . . . . .
Using the BankAccount and AccountManager Classes . . . .
13-33
13-33
13-33
13-35
13-36
13-36
13-36
13-36
xxiii
14
xxiv
Contents
Enumerations
Named Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Kinds of Predefined Names . . . . . . . . . . . . . . . . . . . . . . . . .
Techniques for Defining Enumerations . . . . . . . . . . . . . . . .
14-2
14-2
14-3
14-5
14-5
14-5
14-6
14-7
14-7
14-8
Refer to Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Instances of Enumeration Classes . . . . . . . . . . . . . . . . . . .
Conversion of Characters to Enumerations . . . . . . . . . . . .
Enumeration Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14-11
14-11
14-13
14-15
14-17
14-17
14-17
Operations on Enumerations . . . . . . . . . . . . . . . . . . . . . . . .
Operations Supported by Enumerations . . . . . . . . . . . . . .
Enumeration Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Default Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Convert Enumeration Member to Characters . . . . . . . . . .
Convert Enumeration Array to Cell Array of char Vectors .
Enumerations and char Vectors in Relational Operations .
Enumerations in switch Statements . . . . . . . . . . . . . . . .
Enumeration Set Membership . . . . . . . . . . . . . . . . . . . . . .
Enumeration Text Comparison Methods . . . . . . . . . . . . . .
How to Get Information About Enumerations . . . . . . . . . .
Testing for an Enumeration . . . . . . . . . . . . . . . . . . . . . . .
14-19
14-19
14-19
14-20
14-20
14-20
14-21
14-22
14-23
14-24
14-25
14-25
14-27
14-28
14-28
14-28
15
14-30
14-31
14-32
14-34
14-34
14-34
14-36
14-39
14-41
14-41
14-41
14-45
14-45
14-45
14-45
14-46
Constant Properties
Properties with Constant Values . . . . . . . . . . . . . . . . . . . . . .
Defining Named Constants . . . . . . . . . . . . . . . . . . . . . . . . .
Constant Property Assigned a Handle Object . . . . . . . . . . .
Constant Property Assigned Any Object . . . . . . . . . . . . . . .
Constant Properties No Support for Get Events . . . . . . .
16
15-2
15-2
15-4
15-4
15-6
16-2
16-2
16-3
16-3
xxv
17
xxvi
Contents
16-4
16-5
16-5
16-5
16-8
16-10
16-10
16-11
16-14
16-14
16-18
16-20
16-20
16-20
17-2
17-2
17-2
17-4
17-5
17-5
17-6
17-8
17-8
17-8
Concatenation Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Default Concatenation . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Methods to Overload . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17-10
17-10
17-10
Object Converters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Why Implement Converters . . . . . . . . . . . . . . . . . . . . . . . .
Converters for Package Classes . . . . . . . . . . . . . . . . . . . . .
Converters and Subscripted Assignment . . . . . . . . . . . . . .
17-11
17-11
17-11
17-12
17-14
17-14
17-15
17-16
17-16
17-18
17-20
17-20
17-20
17-21
17-22
17-22
Indexed Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
How Indexed Reference Works . . . . . . . . . . . . . . . . . . . . .
Compound Indexed References . . . . . . . . . . . . . . . . . . . . .
How to Write subsref for Objects . . . . . . . . . . . . . . . . . . . .
17-27
17-27
17-28
17-29
Indexed Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
How Indexed Assignment Works . . . . . . . . . . . . . . . . . . . .
Indexed Assignment to Objects . . . . . . . . . . . . . . . . . . . . .
Compound Indexed Assignments . . . . . . . . . . . . . . . . . . . .
How to Write subsasgn for Objects . . . . . . . . . . . . . . . . . .
17-31
17-31
17-33
17-33
17-34
17-36
17-36
17-37
17-38
17-38
17-38
17-38
17-40
17-40
17-40
17-42
xxvii
18
xxviii
Contents
17-43
17-44
17-45
Operator Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Why Overload Operators . . . . . . . . . . . . . . . . . . . . . . . . . .
How to Define Operators . . . . . . . . . . . . . . . . . . . . . . . . . .
Sample Implementation Addable Objects . . . . . . . . . . .
MATLAB Operators and Associated Functions . . . . . . . . .
17-48
17-48
17-48
17-49
17-51
18-2
18-2
18-3
18-3
18-7
18-7
18-8
18-10
18-10
18-10
18-12
18-14
18-14
18-15
18-15
18-16
18-17
18-17
18-19
18-19
18-20
19
18-23
18-23
18-23
18-24
18-26
18-26
18-26
18-28
18-29
18-29
18-32
18-32
18-32
18-33
18-34
18-36
18-36
18-36
18-37
18-38
18-41
18-41
18-41
18-41
19-2
19-2
19-2
19-4
19-13
19-14
19-15
19-17
xxix
20
xxx
Contents
19-18
19-19
19-21
20-2
20-2
20-3
20-4
20-4
20-5
20-6
20-7
20-7
20-7
20-10
20-10
20-10
20-14
20-14
20-14
20-17
20-17
20-18
20-19
20-20
20-20
20-20
20-21
20-21
20-23
20-24
20-24
20-25
20-26
1
Using Object-Oriented Design in
MATLAB
Why Use Object-Oriented Design on page 1-2
Using Handles on page 1-12
In this code, ME is an object of the MException class, which the catch statement creates
to capture information about the error. Displaying the value of the object message
property returns the error message (Not enough input arguments). Your program can
access other properties to get information about the error.
List all the public properties of an object with the properties function:
properties(ME)
Properties for class MException:
identifier
1-3
message
cause
stack
shows that the value of the message property is an array of class char (a character
array). The stack property contains a MATLAB struct:
s = ME.stack
s =
file: [1x90 char]
name: 'surf'
line: 50
You can treat ME.stack as a structure and reference its fields without assigning the
value:
ME.stack.file
ans =
D:\myMATLAB\matlab\toolbox\matlab\graph3d\surf.m
The file field of the struct contained in the stack property is a character array:
class(ME.stack.file)
ans =
char
1-4
getReport
isequal
ne
rethrow
throw
throwAsCaller
Static methods:
last
You can use these methods like any other MATLAB statement when there is an
MException object in the workspace. For example:
ME.getReport
ans =
Error using ==> surf
Not enough input arguments.
Objects often have methods that overload (redefined for the particular class of the object)
MATLAB functions. Overloading enables you to use objects just like other values. For
example, MException objects have an isequal method. This method enables you
to compare these objects in the same way you would compare variables containing
numeric values. If ME1 and ME2 are MException objects, you can compare them with this
statement:
isequal(ME1,ME2)
1-5
However, what really happens in this case is MATLAB calls the MException isequal
method because you passed MException objects to isequal.
Similarly, the eq method enables you to use the == operator with MException objects:
ME == ME2
Objects should support only those methods that make sense. For example, it would
probably not make sense to multiply MException objects so the MException class does
not implement methods to do so.
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
1-6
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 Manage Internal State
Objects provide several useful features not available from structures and cell arrays. For
example, objects can:
Constrain the data values assigned to any given property
Calculate the value of a property only when it is queried
Broadcast notices when any property value is queried or changed
Restrict access to properties and methods
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
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 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
1-7
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.
Defining Consistent Interfaces
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:
Identify the requirements of a particular objective
Encode requirements into your program as an interface class
Reducing Complexity
Objects reduce complexity by reducing what you must know to use a component or
system:
Objects provide an interface that hides implementation details.
1-8
n1
n2
Properties
Next
Prev
n3
Properties
Next
Prev
n2.Prev
Properties
Next
Prev
n2
n2.Next
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:
First disconnect the nodes:
1
Now create the new node, connect it, and renumber the original nodes:
1
Link new.Prev to n1
Properties
Next
Prev
n2
Properties
Next
Prev
n3
Properties
Next
Prev
n4
Properties
Next
Prev
1-9
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:
Implemented in an optimal way by the class author
Always up to date with the current version of the class
Properly tested
Can automatically update old-versions of the objects when they are loaded from MATfiles.
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.
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 the object's own methods and those of the object's whose class has
been derived from this object's class can access this property or call this method.
Private Only the object's own methods can access this property or call this method.
Overloaded Functions and Operators
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.
1-10
More About
1-11
Using Handles
In this section...
What Is a Handle? on page 1-12
Copies of Handles on page 1-12
Handle Objects Modified in Functions on page 1-13
Determine If an Object Is a Handle on page 1-15
Deleted Handle Objects on page 1-15
This topic describes the behavior of handle objects for users of handle objects. For
information on defining handle classes, see Handle Classes.
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;
Using Handles
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.
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
sr =
8192
gongSound.SampleRate = sr*2;
function myFunc(var)
var = var + 1;
end
The myFunc function can return the modified value, which you could assign to the same
variable name (x) or another variable.
function out = myFunc(var)
out = var + 1;
end
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
1-14
Using Handles
The modifySampleRate function does not need to return a modified gongSound object
because audioplayer objects are handle objects.
longer exists. Calling delete on the object removes the object, but does not clear handle
variables.
For example, create an audioplayer object:
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:
delete(gongSound)
Size
1x1
1x1
42028x1
Bytes
8
104
336224
Class
Attributes
double
audioplayer
double
Note: The value for Bytes returned by the whos command does not include all 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 =
0
1-16
Using Handles
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.
You cannot access properties with the invalid handle variable:
gongSound.SampleRate
Invalid or deleted object.
Size
1x1
42028x1
Bytes
8
336224
Class
Attributes
double
double
More About
1-17
2
Basic Example
Basic Example
A Simple Class
In this section...
Define a Simple 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-5
Overload Functions on page 2-6
BasicClass Code Listing on page 2-6
2-2
A Simple Class
end
Create Object
Create an object of the class using the class name:
a = BasicClass
a =
BasicClass with properties:
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;
Call Methods
Call the roundOff method on object a:
roundOff(a)
2-3
Basic Example
ans =
1.0500
Pass the object as the first argument to a method that takes multiple arguments:
multiplyBy(a,3)
ans =
3.1416
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 method name.
For information on class methods, see Ordinary Methods on page 9-7
Add Constructor
Classes can define a special method to create objects, called a constructor. Constructor
methods enable you pass arguments to the constructor and to validate and assign
property values. Here is a constructor for the BasicClass class:
methods
function obj = BasicClass(val)
if nargin > 0
if isnumeric(val)
obj.Value = val;
else
error('Value must be numeric')
end
end
end
end
By adding this constructor to the class definition, you can create an object in one step:
a = BasicClass(pi/3)
a =
2-4
A Simple Class
This constructor also performs type checking on the input argument. For example:
a = BasicClass('A character array')
Error using BasicClass (line 11)
Value must be numeric
Vectorize Methods
MATLAB enables you to vectorize operations. For example, you can add a number to a
vector:
[1 2 3] + 2
ans =
3
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,
where obj is an object array.
[obj.Value] + 2
This syntax enables the method to work with arrays of object. For example, given objects
a1, a2, and a3:
[a1.Value,a2.Value,a3.Value] + 2
2-5
Basic Example
2.8000
0.8700
7.0000
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 you want
to add two BasicClass objects. It makes sense to add the values of the ObjectValue
properties of each object.
Here is an overload of the MATLAB plus function. It defines addition for this 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
Related Information
For information on overloading functions, see Overload Functions in Class Definitions
on page 9-30.
For information on overloading operators, see Operator Overloading on page 17-48.
2-6
A Simple Class
Value
end
methods
function obj = BasicClass(val)
if nargin == 1
if isnumeric(val)
obj.Value = val;
else
error('Value must be numeric')
end
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
2-7
3
MATLAB Classes Overview
Role of Classes in MATLAB on page 3-2
Developing Classes Typical Workflow on page 3-8
Class to Manage Writable Files on page 3-19
Class to Represent Structured Data on page 3-24
Class to Implement Linked Lists on page 3-36
Class for Graphing Functions on page 3-53
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
a
b
s
Size
1x1
1x9
1x1
Bytes
8
18
370
Class
Attributes
double
char
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 class that comprise the basic types used by the language.
For more information, see Fundamental MATLAB Classes.
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:
3-2
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 Class Design for Polynomials on page 19-2 for an example that creates just
such a class.
MATLAB Classes Key Terms
MATLAB classes use the following words to describe different parts of a class definition
and related concepts.
Class definition Description of what is common to every instance of a class.
Properties Data storage for class instances
Methods Special functions that implement operations that are usually performed
only on instances of the class
Events Messages that are defined by classes and broadcast by class instances when
some specific action occurs
Attributes Values that modify the behavior of properties, methods, events, and
classes
Listeners Objects that respond to a specific event by executing a callback function
when the event notice is broadcast
Objects Instances of classes, which contain actual data values stored in the objects'
properties
Subclasses Classes that are derived from other classes and that inherit the
methods, properties, and events from those classes (subclasses facilitate the reuse of
code defined in the superclass from which they are derived).
Superclasses Classes that are used as a basis for the creation of more specifically
defined classes (i.e., subclasses).
Packages Folders that define a scope for class and function naming
These are general descriptions of these components and concepts. This documentation
describes all of these components in detail.
3-3
3-4
All
Numbers
Integers
Positive
Integers
Positives
Reals
Objects
A class is like a template for the creation of a specific instance of the class. This instance
or object contains actual data for a particular entity that is represented by the class. For
example, an instance of a bank account class is an object that represents a specific bank
account, with an actual account number and an actual balance. This object has built into
it the ability to perform operations defined by the class, such as making deposits to and
withdrawals from the account balance.
Objects are not just passive data containers. Objects actively manage the data contained
by allowing only certain operations to be performed, by hiding data that does not need
to be public, and by preventing external clients from misusing data by performing
operations for which the object was not designed. Objects even control what happens
when they are destroyed.
Encapsulating Information
An important aspect of objects is that you can write software that accesses the
information stored in the object via its properties and methods without knowing
anything about how that information is stored, or even whether it is stored or calculated
when queried. The object isolates code that accesses the object from the internal
implementation of methods and properties. You can define classes that hide both data
and operations from any methods that are not part of the class. You can then implement
whatever interface is most appropriate for the intended use.
References
[1] Shalloway, A., J. R. Trott, Design Patterns Explained A New Perspective on ObjectOriented 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.
Related Examples
3-6
External Websites
3-7
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.)
You must perform certain operations on a bank account:
Create an object for each bank account
Deposit money
Withdraw money
Generate a statement
Save and load the BankAccount object
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.
3-8
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:
open Account balance is a positive value
overdrawn Account balance is overdrawn, but by $200 or less.
closed Account balance is overdrawn by more than $200.
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.
Class Operations
These methods implement the operations defined in the class formulation:
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-10
Discussion
Handle class because there should
be only one copy of any instance of
BankAccount.Comparison of Handle
and Value Classes on page 7-2
BankAccount Class
Discussion
events
InsufficientFunds
end
methods
function BA = BankAccount(AccountNumber,InitialBalance)
Constructor initializes property values
BA.AccountNumber = AccountNumber;
with input arguments.
BA.AccountBalance = InitialBalance;
BA.AccountListener = AccountManager.addAccount(BA);
end
AccountManager.addAccount is
3-11
BankAccount Class
Discussion
function deposit(BA,amt)
deposit adjusts value of
BA.AccountBalance = BA.AccountBalance + amt;
AccountBalance property.
if BA.AccountBalance > 0
BA.AccountStatus = 'open';
end
If AccountStatus is closed
end
function withdraw(BA,amt)
Updates AccountBalance property. If
if (strcmp(BA.AccountStatus,'closed')&& ...
value of account balance is negative as
BA.AccountBalance < 0)
disp(['Account ',num2str(BA.AccountNumber),...
result of the withdrawal, notify triggers
' has been closed.'])
InsufficentFunds event.
return
end
newbal = BA.AccountBalance - amt;
For more information on listeners, see
BA.AccountBalance = newbal;
Events and Listeners Syntax on page
if newbal < 0
11-21.
notify(BA,'InsufficientFunds')
end
end
function getStatement(BA)
Display selected
disp('-------------------------')
account.
disp(['Account: ',num2str(BA.AccountNumber)])
ab = sprintf('%0.2f',BA.AccountBalance);
disp(['CurrentBalance: ',ab])
disp(['Account Status: ',BA.AccountStatus])
disp('-------------------------')
end
end
methods (Static)
source.
3-12
BankAccount Class
end
end
Discussion
End of static methods block
End of classdef
3-13
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
methods (Static)
function assignStatus(BA)
if BA.AccountBalance < 0
if BA.AccountBalance < -200
BA.AccountStatus = 'closed';
else
BA.AccountStatus = 'overdrawn';
end
end
end
Discussion
This class defines the
InsufficentFunds event listener and
the listener callback.
There is no need to create an instance
of this class so the methods defined are
static. See Static Methods on page
9-28.
The assignStatus method is the
callback for the InsufficentFunds
event listener. It determines the value of
a BankAccount object AccountStatus
property based on the value of the
AccountBalance property.
The BankAccount class constructor
calls the AccountManager addAccount
method to create and store this listener.
3-15
AccountManager Class
Discussion
function lh = addAccount(BA)
addAccount creates the listener for
lh = addlistener(BA, 'InsufficientFunds', ...
the InsufficentFunds event that the
@(src, ~)AccountManager.assignStatus(src));
end
BankAccount class defines.
3-16
AccountNumber: 1234567
AccountBalance: 500
AccountListener: [1x1 event.listener]
The $600 withdrawal triggered the InsufficientsFunds event. The current criteria
defined by the AccountManager class results in a status of overdrawn.
Make another withdrawal of $200:
withdraw(BA,200)
getStatement(BA)
------------------------Account: 1234567
CurrentBalance: -300.00
Account Status: closed
-------------------------
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)
Account 1234567 has been closed.
3-17
3-18
Flexible Workflow
The MATLAB language does not require you to define classes for all the code you write.
You can use objects along with ordinary functions. This section illustrates the use of an
object that implements the basic task of writing text to a file.
Also, handle classes define a delete method, which is called automatically when
MATLAB destroys a handle object. This example overrides the delete method. This
method closes the file before deleting the object and losing file identifier.
The Filewriter Class
classdef Filewriter < handle
properties (Access = private)
FileID
end
methods
function obj = Filewriter(filename)
obj.FileID = fopen(filename,'a');
end
function writeToFile(obj,text_str)
fprintf(obj.FileID,'%s\n',text_str);
end
function delete(obj)
fclose(obj.FileID);
end
end
end
Discussion
This class derives from handle to provide
a single reference to the file identifier and
use the class destructor to close the file.
For general information on class
destructors, see Handle Class
Destructor on page 7-16
methods
3-20
Filewriter Class
function obj = Filewriter(filename)
if nargin < 1
error('You must specify a filename')
else
obj.FileID = fopen(filename,'a');
end
end
Discussion
Class constructor opens file for writing
and saves file identifier in private
property. See fopen and Rules for
Constructors on page 9-20
function writeToFile(obj,text_str)
fprintf(obj.FileID,'%s\n',text_str);
end
function delete(obj)
fclose(obj.FileID);
end
end
end
Filewriter objects provide functionality that you can use from functions and
within other classes. You can create an ordinary function that uses this object, as the
writeClassFile function does below.
This example creates only one simple class template, but another version could accept a
cell array of attribute name/value pairs, method names, and so on.
function writeClassFile(classname,superclass)
fw = Filewriter([classname '.m']);
3-21
if nargin > 1
writeToFile(fw,['classdef ' classname ' < ' superclass])
else
writeToFile(fw,['classdef ' classname])
end
writeToFile(fw,'
properties ')
writeToFile(fw,' ')
writeToFile(fw,'
end')
writeToFile(fw,' ')
writeToFile(fw,'
methods ')
writeToFile(fw,'
function')
writeToFile(fw,' ')
writeToFile(fw,'
end')
writeToFile(fw,'
end')
writeToFile(fw,'end')
end
To create a class file template, call writeClassFile with the name of the new class and
its superclass. Use the type command to display the contents of the file:
writeClassFile('MyNewClass','handle')
edit MyNewClass
3-22
See Also
More About
3-23
Data
Description
Material
SampleNumber
Stress
Strain
Modulus
3-25
would simply add a new field to a structure, but returns an error when td is an
instance of the TensileData class.
A class is easy to reuse. Once you have defined the class, you can easily extend it with
subclasses that add new properties.
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-26
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';
Error using TensileData/set.Material
Invalid Material
3-27
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]);
3-28
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.
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
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 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-30
properties
Material
SampleNumber
Stress
Strain
end
Discussion
Value class enables independent copies
of object. For more information, see
Comparison of Handle and Value
Classes on page 7-2
See Structure of the Data on page
3-24
3-31
Example Code
properties (Dependent)
Modulus
end
Discussion
Calculate Modulus when queried.
For information about this code, see
Calculate Data on Demand on page
3-28
For general information, see Access
Methods for Dependent Properties on
page 8-34
methods
function td = TensileData(material,samplenum,...
For information about this code, see
stress,strain)
Simplifying the Interface with a
if nargin > 0
td.Material = material;
Constructor on page 3-27
td.SampleNumber = samplenum;
td.Stress = stress;
For general information about
td.Strain = strain;
end
constructors, see Class Constructor
end
Methods on page 9-20
function obj = set.Material(obj,material)
Restrict possible values for Material
if (strcmpi(material,'aluminum') ||...
strcmpi(material,'stainless steel') ||...property.
strcmpi(material,'carbon steel'))
obj.Material = material;
For information about this code, see
else
Restrict Properties to Specific Values
error('Invalid Material')
end
page 3-26.
end
on
3-32
Example Code
Discussion
page 3-29
to display certain
function plot(td,varargin)
plot(td.Strain,td.Stress,varargin{:})
title(['Stress/Strain plot for Sample',...
num2str(td.SampleNumber)])
ylabel('Stress (psi)')
xlabel('Strain %')
end
end
end
3-33
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 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
function m = get.Modulus(obj)
ind = find(obj.Strain > 0);
m = mean(obj.Stress(ind)./obj.Strain(ind));
end
function obj = set.Modulus(obj,~)
fprintf('%s%d\n','Modulus is: ',obj.Modulus)
error('You cannot set Modulus property');
end
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
3-34
end
More About
3-35
Prev Contains the handle of the previous node in the list (SetAccess =
private)
This diagram shows a list with three-nodes n1, n2, and n3. It also shows how the nodes
reference the next and previous nodes.
n1
Properties
Next
Prev
n2.Prev
n2
Properties
Next
Prev
n3
Properties
Next
Prev
n2
n2.Next
Class Methods
The dlnode class implements the following 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
3-37
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
But each instance of a node is unique so there is only one node in the list that can satisfy
the conditions of being equal to n1.Next and having a Prev property that contains a
handle to n1. Therefore, x must point to the same node as n2.
This means there has to be a way for multiple variables to refer to the same object. The
MATLAB handle class provides a means for both x and n2 to refer to the same node.
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.
Discussion
Example Code
properties
Data
end
properties (SetAccess = private)
Next = dlnode.empty;
Prev = dlnode.empty;
end
Discussion
dlnode Class Design on page 3-36
Property Attributes on page 8-7:
SetAccess.
Initialize these properties to empty
dlnode objects.
For general information about properties,
see Property Syntax on page 8-4
methods
3-40
Example Code
function removeNode(node)
if ~isscalar(node)
error('Nodes 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)
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
methods (Access = private)
function delete(node)
clearList(node)
end
end
end
Discussion
Remove node and fix the list so that
remaining nodes are properly connected.
node argument must be scalar.
Once there are no references to node,
MATLAB deletes it.
Remove a Node on page 3-45
3-41
end
methods
function node = dlnode(Data)
% Construct a dlnode object
if nargin > 0
node.Data = Data;
end
end
function insertAfter(newNode, nodeBefore)
% Insert newNode after nodeBefore.
removeNode(newNode);
newNode.Next = nodeBefore.Next;
newNode.Prev = nodeBefore;
if ~isempty(nodeBefore.Next)
nodeBefore.Next.Prev = newNode;
end
nodeBefore.Next = newNode;
end
function insertBefore(newNode, nodeAfter)
% Insert newNode before nodeAfter.
removeNode(newNode);
newNode.Next = nodeAfter;
newNode.Prev = nodeAfter.Prev;
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;
3-42
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
methods (Access = private)
function delete(node)
clearList(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.
Here is how the dlnode class defines the properties:
properties
3-43
Data
end
properties(SetAccess = private)
Next = dlnode.empty;
Prev = dlnode.empty;
end
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.
function insertAfter(newNode, nodeBefore)
removeNode(newNode);
newNode.Next = nodeBefore.Next;
newNode.Prev = nodeBefore;
if ~isempty(nodeBefore.Next)
nodeBefore.Next.Prev = newNode;
end
nodeBefore.Next = newNode;
end
How insertAfter Works
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 you want to insert a new node, nnew, after an existing node, n1, in
a list containing n1n2n3.
First, create nnew:
nnew = dlnode(rand(3));
3-44
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:
Set nnew.Next to n1.Next (n1.Next is n2):
nnew.Next = n1.Next;
Set nnew.Prev to n1
nnew.Prev = n1;
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 the node is in a known state before assigning it to the Next
or Prev property:
function removeNode(node)
if ~isscalar(node)
3-45
n1
Properties
Next
Prev
n2
Properties
Next
Prev
n3
Properties
Next
Prev
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 (i.e., n2 is not connected):
n2.Next = dlnode.empty;
3-46
n2.Prev = dlnode.empty;
Now remove the third node (Data property assigned the value 3):
removeNode(head.Next.Next)
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.
3-47
n1
Properties
Next
Prev
n2
Properties
Next
Prev
n3
Properties
Next
Prev
>> removeNode(n2)
n2
Properties
Next
Prev
>> clear(n2)
MATLAB calls delete(n2)
Delete the List
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-48
removeNode(node);
end
while ~isempty(prev)
node = prev;
prev = node.Prev;
removeNode(node)
end
end
For example, suppose you create a list with a large number of 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 =
dlnode with properties:
Data: 1
Next: [1x1 dlnode]
Prev: []
head.Next
ans =
dlnode with properties:
Data: 2
Next: [1x1 dlnode]
Prev: [1x1 dlnode]
The only nodes that have not been deleted by MATLAB are those for which there exists
an explicit reference. In this case, those references are head and nextNode:
3-49
head
head =
dlnode with properties:
Data: 1
Next: []
Prev: []
nextNode
nextNode =
dlnode with properties:
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 (i.e., 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.
NamedNode Class Definition
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:
classdef NamedNode < dlnode
properties
Name = '';
end
methods
function n = NamedNode (name,data)
if nargin == 0
name = '';
data = [];
end
n = n@dlnode(data);
n.Name = name;
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 NamedNode to Create a Doubly Linked List
Use the NamedNode class like the dlnode class, except that you specify a name for each
node object. For example:
n(1) = NamedNode('First Node',100);
n(2) = NamedNode('Second Node',200);
n(3) = NamedNode('Third Node',300);
3-51
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 =
NamedNode with properties:
Name:
Data:
Next:
Prev:
'Second Node'
200
[1x1 NamedNode]
[1x1 NamedNode]
n(1).Next.Next
ans =
NamedNode with properties:
Name:
Data:
Next:
Prev:
'Third Node'
300
[]
[1x1 NamedNode]
n(3).Prev.Prev
ans =
NamedNode with properties:
Name:
Data:
Next:
Prev:
'First Node'
100
[1x1 NamedNode]
[]
More About
3-52
3-53
obj.Lm = lim;
end
end % set.Lm
function data = get.Data(obj)
% get function calculates Data
% Use class name to call static method
[x,y] = topo.grid(obj.Lm);
matrix = obj.FofXY(x,y);
data.X = x;
data.Y = y;
data.Matrix = matrix;% Return value of property
end % get.Data
function surflight(obj)
% Graph function as surface
obj.FigHandle = figure;
surfc(obj.Data.X,obj.Data.Y,obj.Data.Matrix,...
'FaceColor',[.8 .8 0],'EdgeColor',[0 .2 0],...
'FaceLighting','gouraud');
camlight left; material shiny; grid off
colormap copper
end % surflight method
function delete(obj)
% Delete the figure
h = obj.FigHandle;
if ishandle(h)
delete(h);
else
return
end
end % delete
end % methods
methods (Static = true) % Define static method
function [x,y] = grid(lim)
inc = (lim(2)-lim(1))/35;
[x,y] = meshgrid(lim(1):inc:lim(2));
end % grid
end % methods Static = true
end % topo class
3-54
To create an instance of the class, passing a function handle and a vector of limits to the
constructor. The easiest way to create a function handle for these functions is to use an
anonymous function:
tobj = topo(@(x,y) x.*exp(-x.^2-y.^2),[-2 2]);
The class surflight method uses the object to create a graph of the function. The actual
data required to create the graph is not stored. When the surflight method accesses
the Data property, the property's get function performs the evaluation and returns the
data in the Data property structure fields. This data is then plotted. The advantage of
not storing the data is the reduced size of the object.
3-55
Now suppose you change the FofXY property so that it contains a function handle that
points to another function:
tobj.FofXY = @(x,y) y.*exp(-x.^2-y.^2);
surflight(a)
Because a is a copy of the handle object tobj, changes to the data referenced by tobj
also change the data referenced by a.
How a Value Class Differs
If topo were a value class, the objects tobj and a would not share data; each would have
its own copy of the property values.
3-56
4
Static Data
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-5
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)
4-2
Static Data
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:
a = StoreData.setgetVar
a =
10
Add a method like setgetVar to any class in which you want the behavior of a static
property.
Static Data
Implementation
The SharedData class is a handle class, which enables you to reference the same object
data from multiple handle variables:
classdef SharedData < handle
properties
Data1
Data2
end
end
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
h =
SharedData with properties:
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:
4-4
Static Data
a1 = UseData;
a2 = UseData;
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 =
0.8147
0.9058
0.1270
0.9134
0.6324
0.0975
0.2785
0.5469
0.9575
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-5
Static Data
Related Examples
More About
4-6
5
Class DefinitionSyntax Reference
Class Files and Folders on page 5-2
Class Components on page 5-5
Classdef Block on page 5-10
Properties on page 5-12
Methods and Functions on page 5-15
Events and Listeners on page 5-20
Attribute Specification on page 5-22
Call Superclass Methods on Subclass Objects on page 5-25
Representative Class Code on page 5-27
MATLAB Code Analyzer Warnings on page 5-32
Objects In Conditional Statements on page 5-34
Operations on Objects on page 5-41
Use of Editor and Debugger with Classes on page 5-45
Automatic Updates for Modified Classes on page 5-47
Compatibility with Previous Versions on page 5-55
Comparison of MATLAB and Other OO Languages on page 5-58
Class folders are not directly on the MATLAB path. The path folder that contains the
class folder is on the MATLAB path.
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.
pathfolder
ClassNameA.m
ClassNameB.m
ClassNameC.m
...
ordinaryFunction.m
Contains classdef
Class method in separate file
Contains entire class definition
A path folder can contain classes defined in both class folders and single files without a
class folder.
pathfolder
+packagefld1
@ClassNameA
ClassNameA.m
classMethod.m
ClassNameB.m
+packagefld2
Contains classdef
Class method in separate file
Contains entire class definition
Defines a new name space
packageFunction.m
ClassNameA.m
ClassNameB.m
More About
5-4
Class Components
Class Components
In this section...
Class Building Blocks on page 5-5
Class Definition Block on page 5-5
Properties Block on page 5-6
Methods Block on page 5-6
Events Block on page 5-7
A Complete Class on page 5-7
Enumeration Classes on page 5-8
Related Information on page 5-9
5-5
For example, this classdef defines a class called MyClass that subclasses the handle
class, but cannot be used to derive subclasses:
classdef (Sealed) MyClass < handle
...
end
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 (Access = 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
5-6
Class Components
...
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.
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.
5-7
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.
classdef ClassName < SuperClass
enumeration
EnumerationMember
end
...
end
For example, this class defines two enumeration members that represent logical false
and true:
classdef Boolean < logical
enumeration
5-8
Class Components
No (0)
Yes (1)
end
end
Related Information
Folders Containing Class Definitions on page 6-16
5-9
Classdef Block
In this section...
How to Specify Attributes and Superclasses on page 5-10
Class Attribute Syntax on page 5-10
Superclass Syntax on page 5-11
Local Functions in Class File on page 5-11
For example, the TextString class specifies that it cannot be used to derive subclasses:
classdef TextString (Sealed)
...
5-10
Classdef Block
end
See Class Attributes on page 6-6 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:
classdef ClassName < SuperclassName
...
end
For example, the LinkedList class inherits from classes called Array and handle:
classdef LinkedList < Array & handle
...
end
Related Examples
Local Functions
5-11
Properties
In this section...
The Properties Block on page 5-12
Access to Property Values on page 5-13
Property attributes apply to all properties defined within the block. To define properties
with different attributes, use multiple properties block. All property attributes
have default values. For a list of property attributes, see Property Attributes on page
8-7.
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.
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-12.
Properties with Different Attributes
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.
5-12
Properties
classdef NewCar
properties
Model
Color
end
properties (SetAccess = private, GetAccess = public)
SerialNumber
end
methods
...
end
end
5-13
obj.Model = model;
obj.Color = color;
obj.SerialNumber = datenum(datetime('now'));
end
end
end
A = NewCar('XGT7000','Red')
A =
NewCar with properties:
Model: 'XGT7000'
Color: 'Red'
SerialNumber: 7.362456078531134e+05
Related Examples
5-14
method. The left most argument does not need to be the class object, and the argument
list can have multiple objects. MATLAB dispatches to the method defined by the class of
the dominant argument. For more information, see Method Invocation on page 9-14.
Methods must 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,
MATLAB errors when you to call that method.
Always use case sensitive method names in your MATLAB code.
Ordinary Methods
Call ordinary methods using MATLAB function syntax or dot notation. For example,
suppose 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
5-16
See Static Methods on page 9-28 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.
See Method Attributes on page 9-5 for a list of method attributes.
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 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
5-17
function myUtilityFcn
...
end
You also can create package functions, which require the use of the package name when
calling these functions.
More About
5-19
Related Examples
5-20
5-21
Attribute Specification
In this section...
Attribute Syntax on page 5-22
Attribute Descriptions on page 5-22
Attribute Values on page 5-23
Simpler Syntax for true/false Attributes on page 5-23
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:
properties (SetAccess = private)
ScreenSize = getScreenSize;
end
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:
Class Attributes on page 6-6
Property Attributes on page 8-7
Method Attributes on page 9-5
Event Attributes on page 11-19
5-22
Attribute Specification
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:
AccountBalance property SetObservable attribute to true
SSNumber and CreditCardNumber properties' Hidden attribute to true and
SetAccess attribute to private.
Defining properties with different attribute settings requires multiple properties
blocks.
properties (SetObservable = true)
AccountBalance
end
properties (SetAccess = private, Hidden = true)
SSNumber
CreditCardNumber
end
5-23
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.
Related Examples
5-24
obj = obj@MySuperClass(SuperClassArguments);
Object returned
from superclass
Name of superclass
Object being
constructed
Superclass constructor
arugment list
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.
classdef MySub < MySuperClass
methods
function obj = MySub(arg1,arg2,...)
obj = obj@MySuperClass(SuperClassArguments);
...
end
5-25
end
end
superMethod@MySuperClass(obj)
Superclass name
Superclass method
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:
classdef MySub < MySuperClass
methods
function disp(obj)
disp@MySuperClass(obj)
...
end
end
end
Related Examples
5-26
5-27
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)])
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.Area
ans =
164.2202
5-29
Define the Radius property within the properties-end keywords. Use default
attributes:
properties
Radius
end
Define the Area property as Dependent because its value depends on the Radius
property.
properties (Dependent)
Area
end
methods % Begin defining methods
The CircleArea class constructor method has the same name as the class and
accepts the value of the circle radius as an argument. This method also allows no input
arguments. (Class Constructor Methods on page 9-20)
function obj = CircleArea(r)
if nargin > 0
obj.Radius = r;
else
obj.Radius = 0;
end
end
Because the Area property is Dependent, it does not store its value. The get.Area
method calculates the value of the Area property whenever it is queried. (Access
Methods for Dependent Properties on page 8-34)
function val = get.Area(obj)
val = obj.P*obj.Radius^2;
end
The set.Radius method tests the value assigned to the Radius property to ensure
the value is not less than zero. MATLAB calls set.Radius to assign a value to Radius.
(Property Set Methods on page 8-29.
5-30
The CircleArea class overloads the plot function. The plot method uses the
rectangle function to create a circle and draws the radius. (Overload Functions in
Class Definitions on page 9-30
function plot(obj)
r = obj.Radius;
d = r*2;
pos = [0 0 d d];
curv = [1 1];
rectangle('Position',pos,'Curvature',curv)
line([0,r],[r,r])
text(r/2,r+.5,['r = ',num2str(r)])
axis equal
end
The CircleArea class overloads the disp function to change the way MATLAB
displays objects in the command window.
function disp(obj)
rad = obj.Radius;
disp(['Circle with radius: ',num2str(rad)])
end
end
methods (Static)
The CircleArea class defines a Static method that uses a dialog box to create an
object. (Static Methods on page 9-28
function obj = createObj
prompt = {'Enter the Radius'};
dlgTitle = 'Radius';
rad = inputdlg(prompt,dlgTitle);
r = str2double(rad{:});
obj = CircleArea(r);
end
5-31
While the previous function is legal MATLAB code, it results in Code Analyzer warnings
for two reasons:
The value of EmployeeName is never used
EmployeeName is the name of a property that is used as a variable
If the function someMethod contained the following statement instead:
obj.EmployeeName = n;
5-32
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:
EN = obj.EmployeeName;
The Code Analyzer does not warn when a variable name is the same as a property name
when the variable is:
An input or output variable
A global or persistent variable
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:
function EmployeeName = someMethod(obj)
EmployeeName = EmployeeName; % Forgot to include obj.
end
Related Examples
5-35
end
In this case, h1 is not scalar. Use isscalar to determine if an object is scalar before
entering a switch statement.
Implementation of eq
Here is a class that implements an eq method. Ensure 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
if ns(kk).Version == s.Version
5-37
ret(kk) = true;
else
ret(kk) = false;
end
end
end
end
end
end
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
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
The switchEnum function switches on the input argument, which can be a FlowRate
enumeration value.
function switchEnum(inpt)
5-39
switch inpt
case 10
disp('Flow = 10 cfm')
case 50
disp('Flow = 50 cfm')
case 100
disp('Flow = 100 cfm')
end
end
5-40
Operations on Objects
Operations on Objects
In this section...
Object Operations on page 5-41
Help on Objects on page 5-42
Functions to Test Objects on page 5-44
Functions to Query Class Components on page 5-44
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)
5-41
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.
Help on Objects
Suppose you use an audioplayer object to play audio with MATLAB. To do this, load
audio data into MATLAB and create an audioplayer:
load('handel','Fs','y')
chorus = audioplayer(y,Fs);
5-42
Operations on Objects
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 thechorus instance of the audioplayer:
chorus
chorus =
The objects 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)
Methods for class audioplayer:
audioplayer
getdisp
pause
resume
stop
5-43
delete
get
horzcat
isplaying
play
playblocking
set
setdisp
vertcat
Description
isa
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)
isobject
5-44
Function
Description
class
enumeration
events
methods
methodsview
properties
To open myclass.m in the MATLAB editor, you could reference the file using dotseparated package names:
edit PackFld1.PackFld2.myclass
To refer to a function defined in its own file inside of a class folder, use:
5-45
edit +PackFld1/+PackFld2/@myclass/myMethod
Related Examples
5-46
5-47
Note: Using an editor other than the MATLAB editor or using MATLAB Online can
result in delays to automatic updating.
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.
Effect
5-50
Change ConstructOnLoad
Change HandleCompatible
Change Hidden
Change
Effect
Change InferiorClasses
Effect
Add property
Remove property
Change property default value Does not apply the new default value to existing objects
of the class.
Move property between
subclass and superclass
Change
Effect
the property value, add a property get method for
the property.
Transient If changed to true, objects already
saved, reload this property value. If changed to
false, objects already saved reload this property
using the default value.
Effect
Add method
Modify method
Remove method
5-52
Change
Effect
MATLAB returns an error because the new class
definition cannot be applied to existing subclasses.
Effect
Add event
Remove event
Change
Effect
you remove classes, objects of those classes are not
able to trigger this event.
Related Examples
5-54
Write the same Stock class constructor as shown here. Define the inheritance on the
classdef line and define the constructor within a methods block.
Constructor Function for Version 7.6
classdef Stock < Asset
...
methods
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
end % End of methods block
end % End of classdef block
5-57
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-23 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.
5-58
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 left-most 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.
See Class Precedence on page 6-22 for more information.
Calling Superclass Method
In C++, you call a superclass method using the scoping operator:
superclass::method
In Java code, you use: superclass.method
The equivalent MATLAB operation is method@superclass.
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.
The sections that follow describe this behavior in more detail.
Objects Passed to Functions
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.
5-59
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
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
5-60
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.
Overwriting the original variable actually replaces it with a new object:
obj = g(obj);
Passing Handle Objects
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 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-61
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
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
function y = g2(x)
x = SimpleHandleClass('green');
y = x;
end
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.
Expressions of this form
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.
5-63
5-64
Technique
Operator overloading
Multiple inheritance
Subclassing
Destructor
Packages (scoping
classes)
Named constants
Enumerations
Static methods
Technique
Static properties
Constructor
Copy constructor
No direct equivalent
Reference/reference
classes
Abstract class/Interface
Garbage collection
Instance properties
Importing classes
5-65
6
Defining and Organizing Classes
User-Defined Classes on page 6-2
Class Attributes on page 6-6
Evaluation of Expressions in Class Definitions on page 6-9
Folders Containing Class Definitions on page 6-16
Class Precedence on page 6-22
Packages Create Namespaces on page 6-24
Import Classes on page 6-29
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-3
Constructing Objects on page 6-3
Class Hierarchies on page 6-3
classdef Syntax on page 6-3
Class Code on page 6-4
User-Defined Classes
Kinds of Classes
There are two kinds of MATLAB classeshandle 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 callers workspace without returning the object.
For more information, see Comparison of Handle and Value Classes on page 7-2.
Constructing Objects
For information on class constructors, see Class Constructor Methods on page 9-20.
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.
6-3
Class attribute
Attribute value
(logical true)
Class name
Super classes
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
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);
User-Defined Classes
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-22.
For more information on the components of a class definition, see Class Components on
page 5-5
Related Examples
6-5
Class Attributes
In this section...
Specifying Class Attributes on page 6-6
Specifying Attributes on page 6-7
For more information on attribute syntax, see Attribute Specification on page 5-22.
Class Attributes
Attribute Name
Class
Description
Abstract
logical
(default =
false)
AllowedSubclassesmeta.class
object or
cell array of
meta.class
objects
6-6
Class Attributes
Attribute Name
Class
Description
ConstructOnLoad
logical
(default =
false)
logical
(default =
false)
InferiorClasses
meta.class
object or
cell array of
meta.class
objects
Sealed
logical
(default =
false)
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 definition blocks to apply
different attribute setting to different properties.
6-7
More About
6-8
6-9
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-23 for
information about these special methods.)
Enumerations that derived from MATLAB types can use expression to assign a value:
classdef FlowRate < int32
enumeration
Low
(10)
Medium (FlowRate.Low*5)
High
(FlowRate.Low*10)
end
end
MATLAB evaluates these expressions only once when enumeration members are first
accessed.
Expressions in Attribute Specifications
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)
classdef
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.
6-10
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
6-11
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)
6-13
ans =
08-Oct-2003 17:22:49
Creating two instances of the ClassExp class shows that MATLAB created an object
when it initialized the ContClass. MATLAB used a copy of the objects 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
6-14
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
More About
6-15
.../path_folder/MyClass1.m
.../path_folder/MyClass2.m
.../path_folder/MyClass2.m
Define only one class per folder. All files must have a .m extension.
Use a class folder when you want to use more than one file for your class definition.
MATLAB treats any .m file in the class folder as a method of the class. 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-19.
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-10.
If you want a subclass to have access to the private functions of the superclass, a better
approach is to define the functions as protected methods of the superclass. Define the
methods with the Access attribute set to protected.
No Class Definitions in Private Folders
You cannot put class definitions in private folders because doing so would not meet the
requirements for class or path folders.
File Defines
fldr1/Foo.m
Class Foo
fldr2/Foo.m
Function Foo
fldr3/@Foo/Foo.m
Class Foo
fldr4/@Foo/bar.m
Method bar
fldr5/Foo.m
Class Foo
Here is the logic that MATLAB applies to determine which version of Foo to call:
Class fldr1/Foo.m takes precedence over the class fldr3/@Foo because:
fldr1/Foo.m is before fldr3/@Foo on the path
Class fldr3/@Foo takes precedence over function fldr2/Foo.m because:
fldr3/@Foo is a class in a class folder
fldr2/Foo.m is not a class
Classes in class folders take precedence over functions
Function fldr2/Foo.m takes precedence over class fldr5/Foo.m because:
6-18
6-19
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.
Class Definitions in Path Folders
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
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.
To use the definition of FooPkg.Foo in foldB, clear FooPkg.Foo.
6-20
clear FooPkg.Foo
MATLAB automatically updates the existing objects to conform to the class definition in
fldB. In most cases, clearing instance variables is unnecessary.
More About
6-21
Class Precedence
In this section...
Use of Class Precedence on page 6-22
Why Mark Classes as Inferior on page 6-22
InferiorClasses Attribute on page 6-22
If arguments are of equal precedence, use the leftmost argument as the dominant
argument.
If the class of the dominant argument does not define a method with the name of the
called function, call the first function on the path with that name.
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.
6-22
Class Precedence
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.
MATLAB built-in classes are always inferior to user-defined classes and should not be
used in this list.
The built-in classes include: double, single, char, logical, int64, uint64, int32,
uint32, int16, uint16, int8, uint8, cell, struct, and function_handle.
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.
More About
6-23
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 prior to MATLAB Version 7.6 (that
is, classes that do not use classdef).
Package folders always begin with the + character. For example,
+mypack
+mypack/pkfcn.m % a package function
+mypack/@myClass % class folder in a package
The parent of the top-level package folder must be on the MATLAB path.
Listing the Contents of a Package
List the contents of a package using the help command:
help event
Contents of event:
EventData
6-24
- event.EVENTDATA
PropertyEvent
listener
proplistener
- event.PROPERTYEVENT
Event data for object property
- event.LISTENER
Listener object
- event.PROPLISTENER
Listener object for property eve
PropertyEvent
listener
proplistener
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. 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.
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)
6-25
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)
obj1 = mypack.MyFirstClass;
obj2 = mypack.MySecondClass(arg);
If mypack.MyFirstClass has a method called myFcn, call it like any method call on an
object:
obj = mypack.MyFirstClass;
myFcn(obj,arg);
6-27
A call to which foo returns the path to the executable class constructor:
>> which foo
fldr_2/@foo/foo.m
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.
Package Functions vs. Static Methods
In cases where a package and a class have the same name, a static method takes
precedence over a package function. 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
In cases where the same path folder contains both package and class folders with the
same name, the class static method takes precedence over the package function.
fldr/@foo/bar.m % bar is a static method of class foo
fldr/+foo/bar.m % bar is a function in package foo
More About
6-28
Import Classes
Import Classes
In this section...
Syntax for Importing Classes on page 6-29
Import Package Functions on page 6-29
Package Function and Class Method Name Conflict on page 6-30
Clearing Import List on page 6-30
6-29
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.
More About
6-30
7
Value or Handle Class Which to
Use
Comparison of Handle and Value Classes on page 7-2
Which Kind of Class to Use on page 7-11
The Handle Superclass on page 7-13
Handle Class Destructor on page 7-16
Find Handle Objects and Properties on page 7-24
Implement Set/Get Interface for Properties on page 7-25
Customize Class Copy Behavior on page 7-32
Control Number of Instances on page 7-38
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 for the purpose of modifying it, the
function must return the modified object as an output argument.
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.
Create a Value Class
By default, MATLAB classes are value classes. The following definition creates a value
class named MyValueClass:
classdef MyValueClass
...
end
7-2
...
end
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
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')
Error using matlab.graphics.primitive.Line/set
Invalid or deleted object.
7-3
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 Using Handles on page
1-12.
7-4
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 =
NumValue with properties:
Number: 7
b
b =
NumValue with properties:
Number: 1
original handle. If you change a property value on the original object, the copied handle
references the same change.
Handle Object Behavior
Here is a handle class that stores a value in its Number property. The default property
value is the number 1.
classdef NumHandle < handle
properties
Number = 1;
end
end
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 =
NumHandle with properties:
Number: 7
7-6
b
b =
NumHandle with properties:
Number: 7
Calling delete on a handle object invokes the destructor function or functions for that
object. See Handle Class Destructor on page 7-16 for more information.
Initialize Properties to Contain Handle Objects
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-10.
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.
Equality of Value Objects
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 =
1
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)
ans =
0
a = NumHandle;
b = a;
Create two instances of the NumHandle class using the default values.
a = NumHandle;
b = NumHandle;
Related Examples
7-10
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.
Related Examples
7-12
7-13
findobj
findprop
ge
gt
isvalid
le
lt
ne
notify
Relational Methods
TF
TF
TF
TF
TF
TF
=
=
=
=
=
=
eq(H1,H2)
ne(H1,H2)
lt(H1,H2)
le(H1,H2)
gt(H1,H2)
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 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.
Related Examples
7-15
Basic Knowledge
Terms and Concepts
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.
Object Lifecycle on page 7-18
Method Attributes on page 9-5
7-17
For a sample class, see Class to Manage Writable Files on page 3-19.
Object Lifecycle
MATLAB invokes the delete method when the lifecycle of an object ends. The lifecycle
of an object ends when the object is:
No longer referenced anywhere
Explicitly deleted by calling delete on the handle
7-18
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.
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.
Sequence During Handle Object Destruction
MATLAB invokes the delete methods in the following sequence when destroying an
object:
1
The delete method of each superclass class, starting with the immediate
superclasses and working up the hierarchy to the most general superclasses
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.
classdef myClass < supclass1 & 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.
Destruction of Objects with Cyclic References
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
7-19
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.
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 objects delete method when
destroying the object regardless of methods Access attribute.
Inherited Private Delete Methods
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 objects 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.
A delete method defined by a value class cannot be a class destructor.
7-21
end
end
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.
any of its superclasses.
To avoid causing inaccessible objects, call the delete explicitly before losing the handle to
the MATLAB object.
function testDestructor
cwj = CallbackWithJava
...
delete(cwj)
end
More About
7-23
The findobj method returns an array of handles matching the conditions specified.
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
7-24
Subclass matlab.mixin.SetGet
Classes inherit set and get methods from matlab.mixin.SetGet:
classdef MyClass < matlab.mixin.SetGet
...
end
Because matlab.mixin.SetGet derives from the handle class, your subclass is also a
handle class.
7-25
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:
CV = get(H,'PropertyName');
You can pass a cell array of property names and a cell array of property values to set:
7-26
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-27
if ~(strcmpi(val,'-') ||...
strcmpi(val,'--') ||...
strcmpi(val,'..'))
error('Invalid line style ')
end
obj.Style = val;
end
function obj = set.Marker(obj,val)
if ~isstrprop(val,'graphic')
error('Marker must be a visible character')
end
obj.Marker = val;
end
end
end
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')
For more information on property access methods, see Property Access Methods on
page 8-23
7-28
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.
Using get with Arrays of Handles
Suppose that you create an array of LineType objects:
H = [LineType('..','z'),LineType('--','q')]
H =
1x2 LineType with properties:
Style
Marker
Units
7-29
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 =
2x1 struct array with fields:
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 =
q
7-30
Style: '..'
Marker: 'o'
Units: 'points
H(2)
ans =
LineType with properties:
Style: '--'
Marker: 'x'
Units: 'points'
See Also
get | set
More About
7-31
7-32
end
methods(Access = protected)
function cp = copyElement(obj)
cp = SpecializedCopy;
cp.Prop1 = obj.Prop1;
cp.Prop2 = datestr(now);
end
end
end
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.
Make a copy of the object using the copy method inherited from
matlab.mixin.Copyable:
b = copy(a);
Demonstrate that the handle object contained by object 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
Prop1 % Shallow copy
Prop2 % Handle copy
7-34
end
methods (Access = protected)
function cp = copyElement(obj)
% Shallow copy object
cp = copyElement@matlab.mixin.Copyable(obj);
% Get handle from Prop2
hobj = obj.Prop2;
% Create default object
new_hobj = eval(class(hobj));
% Add public property values from orig object
HandleCopy.propValues(new_hobj,hobj);
% Assign the new object to property
cp.Prop2 = new_hobj;
end
end
methods (Static)
function propValues(newObj,orgObj)
pl = properties(orgObj);
for k = 1:length(pl)
if isprop(newObj,pl{k})
newObj.(pl{k}) = orgObj.(pl{k});
end
end
end
end
end
ColorProp
The ColorProp class defines a color by assigning an RGB value to its Color property.
classdef ColorProp < handle
properties
Color = 'blue';
end
end
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.
classdef CopiedClass < matlab.mixin.Copyable
properties (NonCopyable)
Prop1
Prop2 = datestr(now); % Assign current time
end
end
7-36
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.
Objects with Dynamic Properties
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');
p.NonCopyable = false;
obj2 = copy(obj);
See Also
matlab.mixin.Copyable
Related Examples
7-37
Limit Instances
You can limit the number of instances of a class that can exist at any one time. For
example, a singleton class can have only one instance and must provide a way to access
this instance. Create a singleton class using a:
Persistent variable to contain the instance
Sealed class to prevent subclassing (class Sealed attribute set to true)
Private constructor (method Access attribute set to private)
Static method to return the handle to the instance, if one exists, or to create the
instance when needed.
7-38
The getInstance static method returns a handle to the object, which the class stores
in a persistent variable. getInstance creates an instance only the first time called in a
session or when the object becomes invalid. For example:
sobj = SingleInstance.getInstance
sobj =
SingleInstance with no properties
As long as sobj exists as a valid handle, calling getInstance returns a handle to the
same object. If you delete sobj, then calling getInstance creates an object and returns
the handle.
delete(sobj)
isvalid(sobj)
ans =
0
See Also
persistent
More About
7-39
8
Properties Storing Class Data
How to Use Properties on page 8-2
Property Syntax on page 8-4
Property Attributes on page 8-7
Defining Properties on page 8-13
Mutable and Immutable Properties on page 8-18
Restrict Class of Properties on page 8-20
Property Access Methods on page 8-23
Property Set Methods on page 8-29
Property Get Methods on page 8-32
Access Methods for Dependent Properties on page 8-34
Properties Containing Objects on page 8-38
Dynamic Properties Adding Properties to an Instance on page 8-41
Access Methods for Dynamic Properties on page 8-45
Dynamic Property Events on page 8-47
Dynamic Properties and ConstructOnLoad on page 8-51
Types of Properties
There are two types of properties:
Stored properties Use memory and are part of the object
8-2
Dependent properties No allocated memory and the get access method calculates
the value when queried
Features of Stored Properties
Can assign an initial value in the class definition
Property value is stored when you save the object to a MAT-file
Can use a set access method to control possible values, but you are not required to use
such methods.
When to Use Stored Properties
You want to be able to save the property value in a MAT-file
The property value is not dependent on other property values
Features of Dependent Properties
Dependent properties save memory because property values that depend on other values
are calculated only when needed.
When to Use Dependent Properties
Define properties as dependent when you want to:
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).
Related Examples
8-3
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-6
Specify Property Attributes on page 8-6
Default value
Property Syntax
Assign values to properties by putting the property reference on the left side of the equal
sign:
obj.PropertyName = val
8-5
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 more than one subclass use.
properties
Coefficients = [0 0 1];
end
properties (SetAccess = private)
IndependentVar
Order = 0;
end
These properties (and any others placed in
this block) have private set access
For information about the properties of a specific class, use the properties function.
Related Examples
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-22.
Attribute Name
Class
Description
AbortSet
logical
default = false
logical
default = false
Access
8-8
Property Attributes
Attribute Name
Class
Description
List of classes that have get and set
access to this property. Specify classes as
meta.class objects in the form:
A single meta.class object
A cell array of meta.class objects.
An empty cell array, {}, is the same as
private access.
See Control Access to Class Members on
page 12-25
Use Access to set both SetAccess and
GetAccess to the same value. Query the
values of SetAccess and GetAccess
directly (not Access).
Constant
logical
default = false
Dependent
logical
default = false
8-9
Attribute Name
Class
Description
Calculate Data on Demand on page
3-28
Property Get Methods on page
8-32
Avoid Property Initialization Order
Dependency on page 13-10
GetAccess
enumeration
default = public
GetObservable
logical
default = false
8-10
Property Attributes
Attribute Name
Class
Description
whenever property values are queried. See
Property-Set and Query Events on page
11-17
Hidden
logical
default = false
logical
default = false
SetAccess
enumeration
default = public
8-11
Attribute Name
Class
Description
A cell array of meta.class objects.
An empty cell array, {}, is the same as
private access.
See Control Access to Class Members on
page 12-25
SetObservable
logical
default = false
Transient
logical
default = false
8-12
Defining Properties
Defining Properties
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
Assign Property Values from Constructor on page 8-14
Initialize Properties to Unique Values on page 8-15
Property Attributes on page 8-15
Property Access Methods on page 8-16
Reference Object Properties Using Variables on page 8-17
If the class definition does not specify a default property value, MATLAB sets the
property value to empty double ([]).
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-9 and
Properties Containing Objects on page 8-38.
Defining Properties
classdef MyClass
properties
Prop1
end
methods
function obj = MyClass(intval)
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 you want to assign a unique handle object to the property of
another object each time you create one of those 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.
For more information on constructor methods, see Referencing the Object in a
Constructor on page 9-22.
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
8-15
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.
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 less than seven characters in the value
assigned to the property, MATLAB returns the error. Otherwise, MATLAB assigns the
specified value to the property.
8-16
Defining Properties
For more information on property access methods, see Property Access Methods on
page 8-23.
Related Examples
8-17
8-18
end
end
a = Immute
a =
Immute with properties:
CurrentDate: '19-Oct-2005'
Related Examples
8-19
If you do not specify a default value, MATLAB assigns an empty object of the restricting
class to the property.
8-20
MATLAB performs conversions from any compatible type to the restricting class. For
example, assign a datetime array to the Today property.
p.Today = [datetime('now'),datetime('tomorrow')];
class(p.Today)
ans =
char
Because the datetime class has a char converter, you can assign a datetime array to
the Today property.
Assigning a noncompatible value to a restricted property causes an error.
p.Number = datetime('now');
While setting the 'Number' property of 'RestrictProp':
8-21
Related Examples
8-22
Execute code before assigning property values to perform actions such as:
Impose value range restrictions (Restrict Properties to Specific Values on page
3-26)
Check for proper types and dimensions
Provide error handling
Execute code before returning the current values of properties to perform actions such
as:
Calculate the value of properties that do not store values (see Calculate Data on
Demand on page 3-28)
Change the value of other properties
Trigger events (see Overview Events and Listeners on page 11-2)
To control what code can access properties, see Property Attributes on page 8-7.
MATLAB Calls Access Methods
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.
Restrictions on Access Methods
Define property access methods only:
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).
8-24
MATLAB has no default set or get property access methods. Therefore, if you do not
define property access methods, MATLAB software does not invoke any methods before
assigning or returning property values.
Once defined, only the set and get methods can set and query the actual property values.
See Set Method Behavior on page 8-30 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-25 for information on usercallable set and get methods.
Access Methods Cannot Call Functions to Access Properties
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.
Defining 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.
Access Method Function Handles
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.
8-25
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.
For information on defining function handles, see Create Function Handle
MATLAB:
Invokes the get method to get the property value
Performs the indexed assignment on the returned property
Passes the new property value to the set method
8-27
scalingFactor = 0.001;
end
methods
function obj = set.expectedResult(obj,erIn)
if erIn >= 0 && erIn <= 100
erIn = erIn.*obj.scalingFactor;
obj.expectedResult = erIn;
else
obj.expectedResult = NaN;
end
end
function er = get.expectedResult(obj)
er = obj.expectedResult/obj.scalingFactor;
end
end
end
More About
8-28
8-29
Use default method attributes for property set methods. The methods block defining the
set method cannot specify attributes.
For an example of a property set method, see Restrict Properties to Specific Values on
page 3-26 .
Assigning a property value that is the same as the current value when the propertys
AbortSet attribute is true. See Abort Property Set Events on page 11-41 for
more information on this attribute.
A set method for one property can assign values to other properties of the object. These
assignments do call any set methods defined for the other properties. For example, a
graphics window object can have a Units property and a Size property. Changing the
Units property can also require a change to the values of the Size property to reflect the
new units.
8-31
8-32
Area
end
methods
function a = get.Area(obj)
a = obj.Width * obj.Height;
end
end
end
Related Examples
8-33
8-34
case 'E'
v = obj.DollarAmount / 1.3;
case 'P'
v = obj.DollarAmount / 1.5;
otherwise
v = obj.DollarAmount;
end
format bank
value = v;
end
end
end
Now the get method for the PropertyName property determines the value of that
property and assigns it to the object from within the method:
function value = get.PropertyName(obj)
value = calculateValue;
...
end
The get method calls a function or static method calculateValue to calculate the
property value and returns value to the code accessing the property. The property get
method can take whatever action is necessary within the method to produce the output
value.
Calculate Data on Demand on page 3-28 provide an example of a property get method.
For example, suppose that you have a class that changes the name of a property from
OldPropName to NewPropName. To continue to allow the use of the old name without
exposing it to new users, make 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, and code that
accesses OldPropName continues to work as expected.
It is sometimes useful for a set method of a dependent property to assign values to
other properties of the object. Assignments made from property set methods cause
the execution of any set methods defined for those properties. See Calculate Data on
Demand on page 3-28 for an example.
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:
8-36
Related Examples
8-37
Assignment Behavior
These classes illustrate the assignment behavior:
8-38
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;
obj.PropValue = ValClass;
end
end
end
classdef HanClass < handle
properties
Hprop
end
end
classdef ValClass
properties
Vprop
end
end
8-39
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;
You cannot set the read-only property 'PropValue' of ReadOnlyProps.
More About
8-40
Access dynamic property values from object arrays, with restricted syntax. (See
Object Arrays with Dynamic Properties on page 10-13.)
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.
where:
P is an array of meta.DynamicProperty objects
H is an array of handles
PropertyName is the name of the dynamic property you are adding to each object
Name Dynamic Properties
Use only valid names when naming dynamic properties (see Variable Names). In
addition, do not use names that:
Are the same as the name of a class method
Are the same as the name of a class event
Contain a period (.)
Set Dynamic Property Attributes
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 propertys 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.
8-42
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
8-43
ans =
2
Related Examples
8-44
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;
8-45
MATLAB calls the property set function whenever you set this property:
b1.myCoord = [1 2 3] % length must be two
Error using button.set_myCoord
myCoords require two values
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.
Related Examples
8-46
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.
8-47
These events have public listen access (ListenAccess attribute) and private notify
access (NotifyAccess attribute).
The PropertyAdded and PropertyRemoved events pass an
event.DynamicPropertyEvent object to listener callbacks. The event data object has three
properties:
PropertyName Name of the dynamic property that is added or removed
Source Handle to the object that is the source of the event
EventName Name of the event (PropertyAdded, PropertyRemoved, or
ObjectBeingDestroyed)
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
8-48
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-49
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 =
1
Related Examples
8-50
Related Examples
8-51
9
Methods Defining Class Operations
How to Use Methods on page 9-2
Method Attributes on page 9-5
Ordinary Methods on page 9-7
Methods In Separate Files on page 9-10
Method Invocation on page 9-14
Class Constructor Methods on page 9-20
Static Methods on page 9-28
Overload Functions in Class Definitions on page 9-30
Class Support for Array-Creation Functions on page 9-34
Object Precedence in Method Invocation on page 9-44
Dominant Argument in Overloaded Graphics Functions on page 9-46
Class Methods for Graphics Callbacks on page 9-49
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 encapsulationclass
instances contain data in properties and class methods operate on that data. This allows
the internal workings of classes to be hidden from code outside of the class, and thereby
enabling the class implementation to change without affecting code that is external to
the class.
Methods have access to private members of their class including other methods and
properties. This enables you to hide data and create special interfaces that must be used
to access the data stored in objects.
See Methods That Modify Default Behavior on page 17-2 for a discussion of how to
create classes that modify standard MATLAB behavior.
See Class Files and Folders on page 5-2 for information on the use of @ and path
directors and packages to organize your class files.
See Methods In Separate Files on page 9-10 for the syntax to use when defining
classes in more than one file.
Kinds of Methods
There are specialized kinds of methods that perform certain functions or behave in
particular ways:
Ordinary methods are functions that act on one or more objects and return some new
object or some computed value. These methods are like ordinary MATLAB functions
that cannot modify input arguments. Ordinary methods enable classes to implement
arithmetic operators and computational functions. These methods require an object of
the class on which to operate. See Ordinary Methods on page 9-7.
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
9-2
property values with data obtained from input arguments. The class constructor
method must return the object it creates. See Class Constructor Methods on page
9-20
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-16
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-23
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-28
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 17-11 for more information.
Abstract methods serve to define a class that cannot be instantiated itself, but serves
as a way to define a common interface used by a number of subclasses. Classes that
contain abstract methods are often referred to as interfaces. See Abstract Classes on
page 12-82 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-23)
Conversion method that converts to a package-qualified class, which requires the use
of the package name (see Packages Create Namespaces on page 6-24)
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.
Related Examples
9-4
Method Attributes
Method Attributes
In this section...
Purpose of Method Attributes on page 9-5
Specifying Method Attributes on page 9-5
Table of Method Attributes on page 9-5
For more information on attribute syntax, see Attribute Specification on page 5-22.
Description
logical Default = If true, the method has no implementation. The method has
false
a syntax line that can include arguments, which subclasses
use when implementing the method:
9-5
Description
Subclasses are not required to define the same number
of input and output arguments. However, subclasses
generally use the same signature when implementing
their version of the method.
The method can have comments after the function line.
The method does not contain function or end keywords,
only the function syntax (e.g., [a,b] = myMethod(x,y))
Access
enumeration,
default =
public
meta.class
object
cell array of
meta.class
objects
Hidden
logical Default = When false, the method name shows in the list of methods
false
displayed using the methods or methodsview commands. If
set to true, the method name is not included in these listings
and ismethod does not return true for this method name. .
Sealed
Static
logical Default = Specify as true to define a method that does not depend
false
on an object of the class and does not require an object
argument. Use the class name to call the method:
classname.methodname or an instance of the class:
obj.methodname
Static Methods on page 9-28 provides more information.
9-6
Ordinary Methods
Ordinary Methods
In this section...
Ordinary Methods Operate on Objects on page 9-7
Methods Inside classdef Block on page 9-7
Method Files on page 9-8
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.
9-7
Sample Method
The addData method adds a value to the Data property of MyData objects. The Data
property has a default value of 0.
classdef MyData
properties
Data = 0;
end
methods
function obj = addData(obj,val)
newData = obj.Data + val;
obj.Data = newData;
end
end
end
a = MyData;
a = addData(a,75)
a =
MyData with properties:
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:
Inside the class definition block
In a separate file in the class folder (that is, @ClassName folder)
For more information on class folders, see Folders Containing Class Definitions on page
6-16.
9-8
Ordinary Methods
More About
9-9
Class Folders
You can define class methods in files that are separate from the class definition file, with
certain exceptions (see Methods That You Must Define In the classdef File on page
9-12).
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
Note: MATLAB treats any .m file in the class folder as a method of the class. 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.
9-10
It is a good practice to declare the function signature in the classdef file in a methods
block:
classdef MyClass
methods
output = myFunc(obj,arg1,arg2)
end
...
end
9-11
end
Define the functions in separate files using the same function signature. For example, in
the file @MyClass/staticFunc1.m:
function output = staticFunc1(arg1,arg2)
...
end
and in @Myclass/staticFunc2.m:
function staticFunc2
...
end
Related Information
Converters for Package Classes on page 17-11
Property Access Methods on page 8-23
Related Examples
9-13
Method Invocation
In this section...
Determining Which Method Is Invoked on page 9-14
Referencing Names with ExpressionsDynamic Reference on page 9-16
Controlling Access to Methods on page 9-17
Invoking Superclass Methods in Subclass Methods on page 9-18
Invoking Built-In Functions on page 9-19
actually calls the combine method of classA because A is the dominant argument.
9-14
Method Invocation
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.
Case Where Result is Different
Here is an example of a case where dot and function notation can give different results.
Suppose 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
classdef classB (InferiorClasses = {?classA})
...
end
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)
...
9-15
end
end
classB does not define a method with the same name as methodA. Therefore, the
following syntax causes the MATLAB runtime to search the path for a function with
the same name as methodA because the second argument is an object of a dominant
class. If a function with that name exists on the path, then MATLAB attempts to call this
function instead of the method of classA and most likely returns a syntax error.
obj = classA(...);
methodA(obj,obj_classB)
Dot notation is stricter in its behavior. For example, this call to methodA:
obj = classA(...);
obj.methodA(obj_classB)
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.
9-16
Method Invocation
As an example, suppose 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 you write a function in which you want to call the correct
method for the current day.
Use an expression created with the date and datestr functions:
obj.(datestr(date,'dddd'))(datestr(date,'dd'))
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')
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
9-18
Method Invocation
A class that is a subclass of the superclass whose method you are invoking
More About
9-19
assign the output argument, you can clear the object variable in the constructor (see
Output Object Not Assigned on page 9-27).
If you create a class constructor, provide a syntax to support no input arguments. See
No Input Argument Constructor Requirement on page 9-22.
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 Sequence of Constructor Calls in Class
Hierarchy on page 12-13
If your constructor makes an explicit call to a superclass constructor, this call must
occur before any other reference to the constructed object.
Calls to superclass constructors cannot be conditional. You cannot place superclass
construction calls in loops, conditions, switches, try/catch, or nested functions. See No
Conditional Calls to Superclass Constructors on page 9-24 for more information.
A class does not need to define a constructor method unless it is a subclass of a
superclass whose constructor requires arguments. In this case, you must explicitly
call the superclass constructor with the required arguments. See Constructing
Subclasses on page 9-23
If a class does not define a constructor, MATLAB supplies a constructor that takes no
arguments and returns a scalar object whose properties are initialized to empty or the
values specified as defaults in the property definitions. The constructor supplied by
MATLAB also calls all superclass constructors with no arguments.
Restrict access to constructors using method attributes, as with any method.
Related Information
For information specific to constructing enumerations, see Enumeration Class
Constructor Calling Sequence on page 14-8.
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 valueseither
empty ([]) or the default value specified in the property definition block.
For example, the following code calls the class method CalculateValue to assign the
value of the property Value.
function obj = myClass(a,b,c)
obj.Value = obj.CalculateValue(a,b);
...
end
For more information on defining default property values, see Property Default Values
on page 8-14.
For ways to handle superclass constructors, see Basic Structure of Constructor Methods
on page 9-26.
Constructing Subclasses
Subclass constructor functions must explicitly call superclass constructors if the
superclass constructors require input arguments. The subclass constructor must specify
these arguments in the call to the superclass constructor using the constructor output
argument. Here is the syntax:
classdef MyClass < SuperClass
function obj = MyClass(arg)
obj@SuperClass(ArgumentList);
...
end
end
The class constructor must make all calls to superclass constructors before any other
references to the object. These changes include assigning property values or calling
ordinary class methods. Also, a subclass constructor can call a superclass constructor
only once.
Reference Only Specified Superclasses
If the classdef does not specify the class as a superclass, the constructor cannot call a
superclass constructor with this syntax .
9-23
MATLAB calls any uncalled constructors in the left-to-right order in which they are
specified in the classdef line. MATLAB passes no arguments to these functions.
No Conditional Calls to Superclass Constructors
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).
If you must call superclass constructors with different arguments that depend on some
condition, you can 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, upvector and viewangle can be
passed to the superclass constructor:
classdef Cube < Shape
properties
SideLength = 0;
Color = [0 0 0];
end
methods
function cubeObj = Cube(length,color,upvector,viewangle)
if nargin == 0
super_args{1} = [0 0 1];
super_args{2} = 10;
elseif nargin == 4
super_args{1} = upvector;
super_args{2} = viewangle;
else
error('Wrong number of input arguments')
end
cubeObj@Shape(super_args{:});
if nargin > 0 % Use value if provided
cubeObj.SideLength = length;
cubeObj.Color = color;
end
...
end
...
9-24
end
end
More on Subclasses
See Create Subclasses Syntax and Techniques on page 12-7 for information on
creating subclasses.
For information on how objects are destroyed, see Handle Class Destructor on page
7-16.
9-26
end
...
end
...
end
See Construct Object Arrays on page 10-2 for information on creating object arrays
in the constructor.
Related Examples
9-27
Static Methods
In this section...
What Are Static Methods on page 9-28
Why Define Static Methods on page 9-28
Defining Static Methods on page 9-28
Calling Static Methods on page 9-29
Inheriting Static Methods on page 9-29
9-28
Static Methods
p = n/d;
end
end
end
Calling the pi method of MyClass in the previous section would require this statement:
value = MyClass.pi(.001);
You can also invoke static methods using an instance of the class, like any method:
obj = MyClass;
value = obj.pi(.001);
Related Examples
9-29
Perform the necessary steps in the method to implement the function. For example,
access the object properties to manipulate data, and so on.
Generally, the method that overloads a function produces results similar to the MATLAB
function. However, there are no requirements with regard to 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.
Overload the bar Function
It is convenient to overload commonly used functions to work with objects of your class.
For example, suppose 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.
To use the bar method, create an object:
9-31
y = rand(1,10);
md = MyData(y);
Related Examples
9-32
9-33
After adding support for these functions to a class named MyClass, you can use similar
syntax with that class:
zArray = zeros(2,3,'MyClass');
9-34
MATLAB uses these arguments to dispatch to the appropriate method in your class.
Array-Creation Functions That Support Overloading
The following functions support this kind of overloading.
Array-Creation Functions
ones
zeros
eye
nan (lower case)
inf
true
false
cast
rand
randn
randi
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.
As a Static method:
methods (Static)
function z = zeros(varargin)
...
end
end
As a Hidden method with the char vector 'Like' appended to the name.
methods (Hidden)
function z = zerosLike(obj,varargin)
...
9-36
end
end
One or more dimension 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');
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.
This enables you to implement your methods with signatures like these:
zeros(varargin) for class name methods
9-37
9-38
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
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 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 to 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');
9-39
for k = 1:prod(dims)
r(k) = Color('RGB',randi(varargin{1},[1,3]));
end
end
end
end
end
9-40
obj = Color(obj.ColorSpace,zeros(1,3,'like',obj.ColorValues));
z = repmat(obj,varargin{:});
end
end
end
end
9-41
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
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
9-42
Related Examples
9-43
Ordinarily, objects have equal precedence and the method associated with the left-most
object is called. However, there are two exceptions:
User-defined classes have precedence over MATLAB fundamental classes (see
Fundamental MATLAB Classes) and certain built-in classes.
User-defined classes can specify their relative precedence with respect to other userdefined classes using the InferiorClasses attribute.
In Class Design for Polynomials on page 19-2, the polynom 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 user-defined
DocPolynom class has precedence over the built-in double class.
9-44
This attribute establishes a relative priority of the class being defined with the order of
the classes listed.
Location in the Hierarchy
If objectA is above objectB in the precedence hierarchy, then the expression
objectA + objectB
More About
9-45
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.
Here is how MATLAB dispatches in response to a function call:
Determine the dominant argument based on the class of arguments.
If there is a dominant argument, call the method of the dominant class.
If arguments are of equal precedence, use the left-most argument as the dominant
argument.
If the class of the dominant argument does not define a method with the name of the
called function, call the first function on the path with that name.
plot(obj)
plot(ax,obj)
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;
9-47
ax = axes;
td = TemperatureData(x,y);
plot(ax,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
More About
9-48
Where your class defines a method called sliderCallback and obj is an instance of
your class.
To use a static methods 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)
9-49
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
The function signature would be of this form:
function methodName(src,eventData)
The uicontrol callback uses dot notation to reference the callback method:
...'Callback',@obj.sliderCallback.
classdef SeaLevelSlider < handle
properties
Figure
Axes
CLimit
end
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),...
'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
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.
50
100
150
200
250
300
350
50
100
150
200
More About
9-52
250
300
350
10
Object Arrays
Construct Object Arrays on page 10-2
Initialize Object Arrays on page 10-5
Empty Arrays on page 10-8
Initialize Arrays of Handle Objects on page 10-10
Object Arrays with Dynamic Properties on page 10-13
Concatenating Objects of Different Classes on page 10-15
Heterogeneous Arrays on page 10-21
Heterogeneous Array Constructors on page 10-31
10
Object Arrays
To preallocate the object array, assign the last element of the array first. MATLAB fills
the first to penultimate array elements with default ObjectArray objects.
After preallocating the array, assign each object Value property to the corresponding
value in the input array F. To use the class:
10-2
Size
A
F
5x5
5x5
Bytes
304
200
Class
Attributes
ObjectArray
double
Create an array of ObjProp objects and access the RegProp property of each object:
for k = 1:5
a(k) = ObjProp;
end
91
13
92
64
10-3
10
Object Arrays
size(PropArray)
ans =
1
Index the array to access specific values. For example, to access the second array
element, use,
PropArray(2)
ans =
91
Related Examples
10-4
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
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)
10-5
10
Object Arrays
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 =
1x7 SimpleValue array with properties:
Value
The object assigned to array element a(1,7) uses the input argument passed to the
constructor as the value assigned to the property:
a(1,7)
ans =
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.
Related Examples
10-7
10
Object Arrays
Empty Arrays
In this section...
Creating Empty Arrays on page 10-8
Assigning Values to an Empty Array on page 10-8
Empty Arrays
every other array element. Once you assign a nonempty object to an array, all array
elements must be nonempty objects.
Note: A class constructor must avoid returning empty objects by default.
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)
ans =
SimpleValue
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).
Related Examples
10
Object Arrays
The element in the index location A(4,5) is an instance of the InitHandleArray class.
Element A(1,1) is also an instance of the InitHandleArray class, but its RandNumb
property is set to a different random number. MATLAB called the class constructor to
create a single object, which MATLAB then copied to all the remaining array elements.
Calling the constructor resulted in another call to the randi function, which returns a
new random number:
10-10
A(1,1).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 =
0
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
See Indexing Multidimensional Arrays and Reshaping Multidimensional Arrays for
information on array manipulation.
10-11
10
Object Arrays
See Initialize Properties to Unique Values on page 8-15 for information on assigning
values to properties.
See Object Array Indexing on page 17-14 for information on implementing
subsasgn methods for your class.
10-12
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;
10-13
10
Object Arrays
MATLAB returns an error if you try to access the dynamic properties of all array
elements using this syntax.
a.DynoProp
No appropriate method, property, or field 'DynoProp' for class
'ObjectArrayDynamic'.
For information about classes that can define dynamic properties, see Dynamic
Properties Adding Properties to an Instance on page 8-41 .
10-14
Basic Knowledge
The material presented in this section builds on an understanding of the information
presented in the following sections.
Construct Object Arrays on page 10-2
Valid Combinations of Unlike Classes
10
Object Arrays
Note: MATLAB does not convert objects to a common superclass unless those objects are
part of a heterogeneous hierarchy. For more information, see Heterogeneous Arrays on
page 10-21.
Concatenating Objects
Concatenation combines objects into arrays:
ary = [obj1,obj2,obj3,...,objn];
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
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]);
10-17
10
Object Arrays
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 =
HSVColor with properties:
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
10-18
Create an array of RGBColor and HSVColor objects with the revised superclass:
crgb = RGBColor([1 0 0]);
chsv = HSVColor([0 1 1]);
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 =
RGBColor with properties:
Color: [1 0 0]
ary(2).Color
ans =
1
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 = [chsv crgb]
ary =
1x2 HSVColor
10-19
10
Object Arrays
Properties:
Color
ary(2).Color
ans =
0
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:
classdef RGBColor < ColorClass
methods
function obj = RGBColor(rgb)
if nargin == 0
rgb = [0 0 0];
else
if ~(isa(rgb,'double')...
&& size(rgb,2) == 3 ...
&& max(rgb) <= 1 && min(rgb) >= 0)
error('Specify color as RGB values')
end
end
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.
More About
10-20
Heterogeneous Arrays
Heterogeneous Arrays
In this section...
MATLAB Arrays on page 10-21
Heterogeneous Hierarchies on page 10-21
Heterogeneous Arrays on page 10-22
Heterogeneous Array Concepts on page 10-22
Nature of Heterogeneous Arrays on page 10-23
Unsupported Hierarchies on page 10-26
Default Object on page 10-28
Conversion During Assignment and Concatenation on page 10-29
Empty Arrays of Heterogeneous Abstract Classes on page 10-29
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, like you can
in MATLAB.
Object arrays in MATLAB are typically homogeneous in class. Because of this
homogeneity, you can perform operations on whole arrays, such as multiplying numeric
matrices. Cell arrays provide an array type that can hold different kinds of unrelated
objects.
Heterogeneous Hierarchies
You can combine objects that are subclasses of a common superclass when these classes
are part of a heterogeneous hierarchy. A MATLAB heterogeneous class hierarchy:
Derives from matlab.mixin.Heterogeneous
Defines a single root superclass that derives directly from
matlab.mixin.Heterogeneous
10-21
10
Object Arrays
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 class 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.
Heterogeneous hierarchies are useful to:
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
Heterogeneous Arrays
10-23
10
Object Arrays
10-24
Heterogeneous Arrays
class(a1)
ans =
ClassA
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.
For example, suppose ClassA defines a property called Prop1.
10-25
10
Object Arrays
a1 = [SpecificA,SpecificB];
a1.Prop1
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.
Call the method on all objects in the array a2:
a2 = [SpecificA,SpecificB,SpecificC];
a2.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.
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).
This diagram shows a hierarchy that is not allowed:
10-26
Heterogeneous Arrays
10-27
10
Object Arrays
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);
10-28
Heterogeneous Arrays
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-29
10
Object Arrays
Related Examples
10-30
10
Object Arrays
that is called by the subclass constructor. Therefore, building an array in the superclass
constructor can create a heterogeneous array.
If a superclass constructor returns a heterogeneous array to the subclass constructor,
MATLAB generates an error (see Potential Error on page 10-35).
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
10-32
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:
TeamMembers Superclass for specific team member classes, like
ProjectEngineer. TeamMembers defines the Name and PhoneX properties and
derives from matlab.mixin.Heterogeneous.
ProjectEngineer Team members that are engineers. Each instance inherits a
Name and PhoneX property and defines a billing Rate property.
Other members Other types of team members not implemented for this example for
simplicity.
10-33
10
Object Arrays
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});
The ProjectEngineer class represents one type of team member. This class supports
array inputs and returns an array of objects.
classdef ProjectEngineer < TeamMembers
% Inputs: {Name}, [PhoneX], {Rate}
properties
Rate
end
methods
function obj = ProjectEngineer(varargin)
obj = obj@TeamMembers(varargin{1:2});
for k = 1:numel(varargin{1})
10-34
obj(k).Rate = varargin{3}{k};
end
end
end
end
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
px
rt
tm
=
=
=
=
{'Fred','Nancy','Claudette'};
[8112,8113,8114];
{'C2','B1','A2'};
ProjectEngineer(nm,px,rt)
tm =
1x3 ProjectEngineer array with properties:
Rate
Name
PhoneX
Potential Error
The TeamMembers constructor initializes the object array with this statement:
obj = repelem(obj,1,n);
10-35
10
Object Arrays
obj = obj@TeamMembers(varargin{1:2});
More About
10-36
11
Events Sending and Responding to
Messages
Overview Events and Listeners on page 11-2
Class with Custom Event Data on page 11-6
Class to Observe Property Changes on page 11-9
Implement Property Set Listener on page 11-11
Event and Listener Concepts on page 11-14
Event Attributes on page 11-19
Events and Listeners Syntax on page 11-21
Listener Lifecycle on page 11-27
Listener Callback Syntax on page 11-29
Callback Execution on page 11-32
Determine If Event Has Listeners on page 11-34
Listen for Changes to Property Values on page 11-37
Abort Property Set Events on page 11-41
Update Graphs Using Events and Listeners on page 11-45
11
Listener callback functions must define at least two input arguments the event
source object handle and the event data (See Listener Callback Syntax on page
11-29 for more information).
Modify the data passed to each listener callback by subclassing the event.EventData
class.
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-37.
All handle objects define an event named ObjectBeingDestroyed. MATLAB triggers
this event before calling the class destructor.
11-3
11
methods
function anyMethod(obj)
...
notify(obj,'EventName');
end
end
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:
classdef MyClass < handle
events
StateChange
end
methods
function triggerEvent(obj)
notify(obj,'StateChange')
end
end
end
Create Listener
Define a listener using the handle class addlistener method. Pass a function handle for
the listener callback function using a syntax like these:
addlistener(eventObject,'EventName',@functionName) for an ordinary
function.
addlistener(eventObject,'EventName',@Obj.methodName) for a method of
Obj.
addlistener(eventObject,'EventName',@ClassName.methodName) for a
static method of the class ClassName.
ListenerObject = addlistener(SourceOfEvent,'EventName',@listenerCallback);
SourceOfEvent An object of the class defining the event on which the event
occurred.
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.
For example, create a listener object for the StateChange 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:
function handleStateChange(src,eventData)
...
end
Related Examples
11-5
11
11-7
11
Related Examples
11-8
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:
metaProp a meta.property object for ObservedProp
eventData an event.PropertyEvent object contain event specific data.
These arguments provide information about the property and the event.
11-9
11
Use the PropLis class by creating an instance and calling its attachListener method:
plObj = PropLis;
plObj.ObservedProp
ans =
1
plObj.attachListener
plObj.ObservedProp = 2;
The ObservedProp property has changed.
The new value is: 2
Its default value is: 1
Related Examples
11-10
MATLAB executes the pressed method, which graphs a new set of data and
increments the ResultNumber property.
Attempting to set the value of the ResultNumber property triggers the PreSet
event, which executes the listener callback before setting the property value.
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.
The listener callback updates the axes Title property, after the callback completes
execution, MATLAB sets the ResultsNumber property to its new value.
11-11
11
AxHandle
end
methods
function buttonObj = PushButton
myFig = figure;
buttonObj.AxHandle = axes('Parent',myFig);
uicontrol('Parent',myFig,...
'Style','pushbutton',...
'String','Plot Data',...
'Callback',@(src,evnt)pressed(buttonObj));
addlistener(buttonObj,'ResultNumber','PreSet',...
@PushButton.updateTitle);
end
end
methods
function pressed(obj)
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 after three push-button clicks.
buttonObj = PushButton;
11-12
Related Examples
11-13
11
BankAccount
if AccountBalance <= 0
notify(obj,InsufficientFunds);
end
Properties
AccountNumber
AccountBalance
Methods
deposit
withdraw
Events
InsufficientFunds
InsufficientFunds
3. Listeners awaiting message
execute their callbacks.
(The broadcasting object
does not necessarily know
who is listening.)
Listener1
Properties
EventName = InsufficientFunds
FunctionHandle = @Callback1
InsufficientFunds
Listener2
Properties
EventName = InsufficientFunds
FunctionHandle = @Callback2
Limitations
There are certain limitations to the use of events:
The event source cannot guarantee that listeners exist when the 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.
11-15
11
Listeners should not modify the event data object passed to the listener callback,
because other listeners are passed this same handle object.
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:
11-17
11
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-58 for an example.
Recursive Allow listener to cause the same event that triggered the execution of
the callback
Recursive is false by default. If the callback triggers its own event, the listener
cannot execute recursively. Setting the Recursive to true can create a situation
where infinite recursion reaches the recursion limit and triggers an error.
Control Listener Lifecycle on page 11-27 provides more specific information.
11-18
Event Attributes
Event Attributes
Specify Event Attributes
The following table lists the attributes you can set for events. To specify a value
for an attribute, assign the attribute value on the same line as the event key word.
For example, all the events defined in the following events block have protected
ListenAccess and private NotifyAccess.
events (ListenAccess = 'protected', NotifyAccess = 'private')
EventName1
EventName2
end
To define other events in the same class definition that have different attribute settings,
create another events block.
Event Attributes
Attribute Name Class
Hidden
logical Default =
false
ListenAccess enumeration,
default = public
meta.class
object
cell array of
meta.class
objects
Description
If true, event does not appear in list of events returned
by events function (or other event listing functions or
viewers).
Determines where you can create listeners for the event.
public Unrestricted access
protected Access from methods in class or
subclasses
private Access by class methods only (not from
subclasses)
List classes that have listen access to this event. Specify
classes as meta.class objects in the form:
A single meta.class object
A cell array of meta.class objects. An empty cell
array, {}, is the same as private access.
See Control Access to Class Members on page
12-25
11-19
11
Description
NotifyAccess enumeration,
default = public
meta.class
object
cell array of
meta.class
objects
Related Examples
11-20
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-21.
A function or method to trigger the event when the action occurs Trigger Events
on page 11-22.
Listener objects to execute callback functions in response to the triggered event
Listen to Events on page 11-22.
Default or custom event data that the event passes to the callback functions
Define Event-Specific Data on page 11-25.
Name Events
Define an event by declaring an event name inside an events block. For example, this
class creates an event called ToggledState:
classdef ToggleButton < handle
properties
State = false
end
events
ToggledState
end
end
11-21
11
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.
classdef ToggleButton < handle
properties
State = false
end
events
ToggledState
end
methods
function OnStateChange(obj,newState)
if newState ~= obj.State
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 method or the event.listener class
constructor.
Use addlistener for Persistent Listeners
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.
This code defines a listener for the ToggleState event:
lh = addlistener(obj,'ToggleState',@RespondToToggle.handleEvnt);
For example, this code uses the ToggleState event discussed previously:
lh = event.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. These 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-25.
You must 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-29.
11-23
11
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
For example, this code creates objects of both classes:
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)
11-24
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)
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)
11
Note: To save and load objects that are subclasses of event.EventData, such as
ToggleEventData, enable the ConstructOnLoad class attribute for the subclass.
classdef (ConstructOnLoad) ToggleEventData < event.EventData
properties
NewState
end
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);
Related Examples
11-26
Listener Lifecycle
Listener Lifecycle
In this section...
Control Listener Lifecycle on page 11-27
Temporarily Deactivate Listeners on page 11-27
Permanently Delete Listeners on page 11-28
11-27
11
Related Examples
11-28
11-29
11
...
end
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
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
Related Examples
11-31
11
Callback Execution
In this section...
When Callbacks Execute on page 11-32
Listener Order of Execution on page 11-32
Callbacks That Call notify on page 11-32
Manage Callback Errors on page 11-33
Invoke Functions from Function Handles on page 11-33
Callback Execution
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')
Updated Event Triggered
Related Examples
11-33
11
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
11-34
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)
11
het = [SpecificA,SpecificB,SpecificC];
class(het)
ans
RootSuperclass
events(het)
Events for class RootSuperclass
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')
Error using event.hasListener
Event 'ClassAEvent' is not defined for class 'RootSuperclass'.
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
Heterogeneous Arrays on page 10-21.
Related Examples
11-36
11
If your listener callback is an ordinary method and not a static method, the syntax is:
addlistener(EventObject,'PropOne','PostSet',@obj.handlePropertyEvents);
where obj is the handle of the object defining the callback method.
If the listener callback is a function that is not a class method, you pass a function handle
to that function. Suppose the callback function is a package function:
addlistener(EventObject,'PropOne','PostSet',@package.handlePropertyEvents);
For more information on passing functions as arguments, see Create Function Handle.
11
Related Examples
11-40
Implement AbortSet
The following example shows how the AbortSet attribute works. The AbortTheSet
class defines a property, PropOne, that has listeners for the PreGet and PreSet events
and enables the AbortSet attribute. The behavior of the post set/get events is equivalent
so only the pre set/get events are used for simplicity:
11-41
11
Note: Save the AbortTheSet class in a file with the same name in a folder on your
MATLAB path.
classdef AbortTheSet < handle
properties (SetObservable, GetObservable, AbortSet)
PropOne = 7
end
methods
function obj = AbortTheSet(val)
obj.PropOne = val;
addlistener(obj,'PropOne','PreGet',@obj.getPropEvt);
addlistener(obj,'PropOne','PreSet',@obj.setPropEvt);
end
function propval = get.PropOne(obj)
disp('get.PropOne called')
propval = obj.PropOne;
end
function set.PropOne(obj,val)
disp('set.PropOne called')
obj.PropOne = val;
end
function getPropEvt(obj,src,evnt)
disp ('Pre-get event triggered')
% ...
end
function setPropEvt(obj,src,evnt)
disp ('Pre-set event triggered')
% ...
end
function disp(obj)
% Overload disp to avoid accessing property
disp (class(obj))
end
end
end
The class specifies an initial value of 7 for the PropOne property. Therefore, if you create
an object with the property value of 7, there is not need to trigger the PreSet event:
ats = AbortTheSet(7);
get.PropOne called
If you specify a value other than 7, then MATLAB triggers the PreSet event:
11-42
ats = AbortTheSet(9);
get.PropOne called
set.PropOne called
get.PropOne called
Similarly, if you set the PropOne property to the value 9, the AbortSet attribute
prevents the property assignment and the triggering of the PreSet event. Notice also,
that there is no PreGet event generated. Only the property get method is called:
ats.PropOne = 9;
get.PropOne called
Because a property set method might modify the value that is actually assigned to a
property, MATLAB must query the property value that would result from an assignment
after a call to the property set method. This results in multiple calls to a property get
method, if one is defined for that property.
11-43
11
Related Examples
11-44
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.
This class defines two events:
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-45
11
fcnview
Properties
fcneval object
graph
fcneval
Properties
FofXY
Lm observable
Data
Events
UpdateGraph
Listeners
Lm property
UpdateGraph
11-46
Property
Value
Purpose
FofXY
function
handle
Lm
two-element
vector
Data
Event
When Triggered
UpdateGraph
Method
Purpose
fcneval
set.FofXY
set.Lm
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
11
Property
Value
Purpose
FcnObject
fcneval object
HAxes
axes handle
HLUpdateGraph event.listener
object for
UpdateGraph event
11-48
HLLm
event.listener
Setting the event.listener object's
object for Lm property Enabled property to true enables the
event
listener, false disables listener.
HEnableCm
uimenu handle
HDisableCm
uimenu handle
HSurface
surface handle
Method
Purpose
fcnview
createLisn
lims
updateSurfaceData
listenUpdateGraph
listenLm
delete
createViews
Purpose
addlistener
Register a listener for a specific event and attach listener to eventdefining object.
notify
Use the createViews static method to create the graphs of the function. Note that you
must use the class name to call a static function:
fcnview.createViews(feobject);
The createView method generates four views of the function contained in the fcneval
object.
11-49
11
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:
feobject.FofXY = @(x,y) x.*exp(-x.^.5-y.^.5);
11-50
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.
feobject.Lm = [-8 3];
In this figure the listeners are re-enabled via the context menu for subplot 221. Because
the listener callback for the property PostSet event also updates the surface data, all
views are now synchronized
11-51
11
myfunceval
obj.FofXY = @(x,y)x^2+y^2
Properties
FofXY
function set.FofXY(obj,func)
obj.FofXY = func;
notify(obj,UpdateGraph);
end
Methods
set.FofXY
Events
UpdateGraph
UpdateGraph
Listener
Properties
EventName = UpdateGraph
FunctionHandle = @listenUpdateGraph
myfuncview
Methods
listenUpdateGraph
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.
The fcneval class defines an event name in an event block:
11-52
events
UpdateGraph
end
11
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.
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-37). Defining a class event provides more flexibility in this case because you can
better control event triggering.
For example, suppose you wanted to update the graph only if the new data is
significantly different. If the new expression produced the same data within some
tolerance, the set.FofXY method could not trigger the event and avoid updating the
graph. However, the method could still set the property to the new value.
Listener and Callback for UpdateGraph Event
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
11-54
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 generally 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-55
11
myfunceval
Properties (SetObservable)
Lm
PostSet
Listener
Properties
EventName = PostSet
FunctionHandle = @listenLm
myfuncview
Methods
listenLm
11-56
The set.Lm method executes to check whether the value is in appropriate range
if yes, it makes assignment, if no, it generates an error.
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.
Enable PostSet Property Event
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
The MATLAB runtime automatically triggers the event so it is not necessary to call
notify.
Specify Property Attributes on page 8-6 provides a list of all property attributes.
Listener and Callback for PostSet Event
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-58).
The fcnview object (obj) is added to the two default arguments (src, evnt) passed to
the listener callback. Keep in mind, the source of the event (src) is the fcneval object,
but the fcnview object contains the handle of the surface object that is updated by the
callback.
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
11-57
11
end
The disableLisn function is called when the user selects Don't Listen from the
context menu.
function disableLisn(obj,src,evnt)
obj.HLUpdateGraph.Enabled = false; % Disable listener
obj.HLLm.Enabled = false; % Disable listener
set(obj.HEnableCm,'Checked','off') % Unheck Listen
set(obj.HDisableCm,'Checked','on') % Check Don't Listen
end
11-58
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
11-59
11
11-60
properties
FcnObject
HAxes
HLUpdateGraph
HLLm
HEnableCm
HDisableCm
HSurface
end
%
%
%
%
%
%
%
fcneval object
subplot axes handle
UpdateGraph listener handle
Lm property PostSet listener handle
"Listen" context menu handle
"Don't Listen" context menu handle
Surface object handle
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,...
'XData',data.X,...
'YData',data.Y,...
'ZData',data.Matrix);
end
function listenUpdateGraph(obj,~,~)
if ishandle(obj.HSurface)
obj.updateSurfaceData
end
end
11-61
11
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',...
11-62
'Checked','off',...
'Callback',@(src,evnt)disableLisn(fcnviewobj(k),src,evnt));
az = p/k*deg;
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-63
12
How to Build on Other Classes
Hierarchies of Classes Concepts on page 12-2
Create Subclasses Syntax and Techniques on page 12-7
Sequence of Constructor Calls in Class Hierarchy on page 12-13
Modify Superclass Methods on page 12-15
Modify Superclass Properties on page 12-18
Subclass Multiple Classes on page 12-20
Specify Allowed Subclasses on page 12-22
Control Access to Class Members on page 12-25
Property Access List on page 12-33
Method Access List on page 12-34
Event Access List on page 12-35
Support Both Handle and Value Subclasses on page 12-36
Subclasses of MATLAB Built-In Types on page 12-44
Behavior of Inherited Built-In Methods on page 12-48
Subclasses of Built-In Types Without Properties on page 12-53
Subclasses of Built-In Types with Properties on page 12-61
Use of size and numel with Classes on page 12-69
Class to Represent Hardware on page 12-75
Determine Array Class on page 12-78
Abstract Classes on page 12-82
Define an Interface Superclass on page 12-87
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.
12-2
Base class
Employees
Employees
Sales
People
Properties
Name
Address
Department
Engineers
Derived classes
Test
Engineers
SalesPerson
(is an Employees)
Properties
Commission
Region
Engineer
(is an Employees)
Properties
Products
Team
TestEngineer
(is an Engineer)
Properties
TestStage
At the root of the hierarchy is the Employees class. It contains data and operations that
apply to the set of all employees. Contained in the set of employees are subsets whose
members, while still employees, are also members of sets that more specifically define
the type of employee. Subclasses like TestEngineer are examples of these subsets.
12
When designing classes, your abstraction should contain only those elements that are
necessary. For example, the employee hair color and shoe size certainly characterize the
employee, but are probably not relevant to the design of this employee class. Their sales
region is relevant only to some employee so this characteristic belongs in a subclass.
Two points about super and subclass behavior to keep in mind are:
Methods defined in the superclass can operate on subclass objects.
Methods defined in the subclass cannot operate on superclass objects.
Therefore, you can treat an Engineer object like any other Employees object, but an
Employee object cannot pass for an Engineer object.
Limitations to Object Substitution
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 matlab.mixin.Heterogeneous for information on defining heterogeneous class
hierarchies.
See Object Converters on page 17-11 for information on defining converter methods.
12
Related Examples
12-6
Subclass Definition
To define a class that is a subclass of another class, add the superclass to the classdef
line after a < character:
classdef ClassName < SuperClass
When inheriting from multiple classes, use the & character to indicate the combination of
the superclasses:
classdef ClassName < SuperClass1 & SuperClass2
See Class Member Compatibility on page 12-20 for more information on deriving
from multiple superclasses.
Class Attributes
Subclasses do not inherit superclass attributes.
12
Where obj is the output of the 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 stock
that is a subclass of a class called asset.
classdef stock < asset
methods
function s = stock(asset_args,...)
if nargin == 0
... % Assign values to asset_args
end
% Call asset constructor
s@asset(asset_args);
...
end
end
end
12-8
methods
function s = stock(asset_args,member_args,...)
if nargin == 0
...
end
% Call asset and member class constructors
s@financial.asset(asset_args)
s@trust.member(member_args)
...
end
end
end
12-9
12
SharePrice
end
methods
function s = stock(name,pps)
% Support no input argument case
if nargin == 0
name = '';
pps = 0;
end
% Call superclass constructor
s@financial.asset(name)
% Assign property value
s.SharePrice = pps;
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.
12-10
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:
classdef C < B
methods
function obj = C(x,y)
...
obj@B(x,y);
end
end
end
The old class constructor must be callable with zero input arguments.
This technique is useful when reloading objects that you saved using the old class name.
However, the class of the object reflects the new name. That is, this code returns the new
class name.
class(obj)
12-11
12
Related Examples
12-12
In cases of multiple inheritance, the subclass constructor can call each superclass
constructor. To ensure that a specific superclass constructor calling sequence is followed,
your most specific subclass constructor must explicitly call ALL superclass constructors:
12-13
12
If you do not explicitly call all direct superclass constructors, MATLAB does not
guarantee the order in which the superclass constructors are called.
Related Examples
12-14
12-15
12
% postprocessing steps
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 sub < super
...
methods (Access = protected)
function step1(obj)
% subclass version
end
...
12-16
end
end
Related Examples
12-17
12
12-18
Prop = 1;
end
end
If you create an instance of the subclass and use it to call the superclass method,
MATLAB access the private property of the superclass:
subObj = Sub
subObj =
Sub with properties:
Prop: 1
subObj.superMethod
ans =
2
More About
12-19
12
Only one superclass defines the method as Sealed, in which case, the subclass adopts
the sealed method definition.
The superclasses define the methods as Abstract and rely on the subclass to define
the method.
Event Conflicts
If two or more superclasses define events with the same name, then at least one of the
following must be true:
The event ListenAccess and NotifyAccess attributes must be private.
The event has the same definition in all superclasses (for example, when all
superclasses inherited the event from a common base class)
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 or inherited from the unrestricted superclass
In general, when using multiple inheritance, ensure that all superclasses remain free of
conflicts in definition.
Related Examples
12-21
12
Basic Knowledge
The material presented in this section builds on an understanding of the following
information:
Class Metadata on page 16-2
Attribute Specification on page 5-22
Specify a list of one or more allowed subclasses in the classdef statement by assigning
meta.class objects to the AllowedSubclasses attribute. Create the meta.class
object referencing a specific class using the ? operator and the class name:
classdef (AllowedSubclasses = ?ClassName) MySuperClass
...
end
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
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.
Result of Declaring Allowed Subclasses
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.
12-23
12
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.
Related Examples
12-24
Basic Knowledge
The material presented in this section builds on an understanding of the following
information:
Related Topics
Class Metadata on page 16-2
Attribute Specification on page 5-22
Terminology and Concepts
Class members Properties, methods, and events defined by a class
Defining class The class defining the class member for which access is being
specified
Get access Permission to read the value of a property; controlled by the property
GetAccess attribute
Set access Permission to assign a value to a property; controlled by the property
SetAccess attribute
Method access Determines what other methods and functions can call the class
method; controlled by the method Access attribute
Listen access Permission to define listeners; controlled by the event ListenAccess
attribute
Notify access Permission to trigger events; controlled by the event NotifyAccess
attribute
12-25
12
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.
12-26
Note: Specify the meta.class objects explicitly (created with the ? operator), not as
values returned by functions or other MATLAB expressions.
How MATLAB Interprets Attribute Values
Granting access to a list of classes restricts access to only:
The defining class
The classes in the list
Subclasses of the classes in the list
Including the defining class in the access list gives all subclasses of the defining class
access.
MATLAB resolves references to classes in the access list only when the class is
loaded. If MATLAB cannot find a class that is included in the access list, that class is
effectively removed from access.
MATLAB replaces unresolved meta.class entries in the list with empty
meta.class objects.
An empty access list (that is, an empty cell array) is equivalent to private access.
Specify Metaclass Objects
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
Specify these values explicitly, as shown in the example code in this section.
12-27
12
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 try to access the
property from outside the class definition. For example, from the command line:
a = GrantAccess;
a.Prop1
Getting the 'Prop1' property of the 'GrantAccess' class is not allowed.
classdef AcListSuper
methods (Access = {?AcListNonSub})
function obj = m1(obj)
disp ('Method m1 called')
end
end
end
Because AcListNonSub is in the access list of m1, its methods can call m1 using an
instance of AcListSuper:
classdef AcListNonSub
methods
function obj = nonSub1(obj,AcListSuper_Obj)
% Call m1 on AcListSuper class
AcListSuper_Obj.m1;
end
function obj = m1(obj)
% Define a method named m1
disp(['Method m1 defined by ',class(obj)])
end
end
end
12
Subclass methods cannot call the superclass method because it is effectively private.
Subclasses cannot override the superclass method.
Subclass methods can call the superclass method indirectly using an instance of a
class that is in the access list.
Methods of classes that are in the superclass method access list, but that are not
subclasses, can call the superclass method. To call the superclass method, use an
object of a subclass that is not in the superclass method access list.
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, which
would implicitly include all subclasses of AcListSuper in the access list:
classdef AcListSub < AcListSuper
methods
function obj = sub1(obj,AcListSuper_Obj)
% Access m1 via superclass object (NOT ALLOWED)
AcListSuper_Obj.m1;
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 results in an error because subclasses are
not in the access list for the method:
a = AcListSuper;
b = AcListNonSub;
c = AcListSub;
c.sub1(a);
Error using AcListSuper/m1
Cannot access method 'm1' in class 'AcListSuper'.
Error in AcListSub/sub1 (line 4)
AcListSuper_Obj.m1;
The AcListSub sub2 method can call a method of a class that is on the access list for m1,
and that method (nonSub1) does have access to the superclass m1 method:
c.sub2(b,a);
Method m1 called
12-30
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.
methods (Access = {?AcListNonSub})
function obj = m1(obj)
disp('AcListSub m1 method')
end
end
The AcListNonSub class, which is in the m1 method access list, can define a method that
calls the m1 method using an instance of the AcListSub class. While AcListSub is not
in the access list for method m1, it is a subclass of AcListSuper.
For example, add the following method to the AcListNonSub class:
methods
function obj = nonSub2(obj,AcListSub_Obj)
disp('Call m1 via subclass object:')
AcListSub_Obj.m1;
end
end
This behavior is consistent with the behavior of any subclass object, which can substitute
for an object of its superclass.
12-31
12
12-32
Related Examples
12-33
12
Related Examples
12-34
Related Examples
12-35
12
Basic Knowledge
The material presented in this section builds on knowledge of the following information.
Create Subclasses Syntax and Techniques on page 12-7
Subclass Multiple Classes on page 12-20
Comparison of Handle and Value Classes on page 7-2
Key Concepts
Handle-compatible class is a class that you can combine with handle classes when
defining a set of superclasses.
All handle classes are handle-compatible.
All superclasses of handle-compatible classes must also be handle compatible.
HandleCompatible the class attribute that defines nonhandle classes as handle
compatible.
12-37
12
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 Metadata for
information on using meta-data classes.
Return Modified Objects
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-59 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:
classdef PropertyDefaults < Utility
properties
p1 = datestr(rem(now,1)); % Current time
p2 = 'red';
% Character vector
p3 = pi/2;
% Result of division operation
end
end
Assign new values that are different from the default values:
12-38
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 =
PropertyDefaults with properties:
:
p1: ' 4:45 PM'
p2: 'green'
p3: 0.7854
Call the resetDefaults method, which is inherited from the Utility class. Because
the PropertyDefaults class is not a handle class, return the modified object.
pd = pd.resetDefaults
pd =
PropertyDefaults with properties:
p1: ' 4:54 PM'
p2: 'red'
p3: 1.5708
If the PropertyDefaults class was a handle class, then you would not need to save the
object returned by the resetDefaults method. To design a handle compatible class like
Utility, ensure that all methods work with both kinds of classes.
12
12-40
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.');
mc = metaclass(hv);
mc.HandleCompatible
ans =
0
12-41
12
TimeStamp
end
methods
function obj = setTime(obj)
obj.TimeStamp = now;
end
end
end
More About
12-43
12
A value of 0 indicates that the class is not Sealed and can be subclasses.
12-44
12
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.
Related Examples
12-47
12
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.
The DocSimpleDouble class subclasses the built-in double class.
classdef DocSimpleDouble < double
methods
function obj = DocSimpleDouble(data)
if nargin == 0
data = 0;
end
obj = obj@double(data);
end
end
end
12-48
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:
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
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
10
12
sc = DocSimpleDouble(1:10);
a = sin(sc);
class(a)
ans =
double
b = sort(sc)
b =
1x10 DocSimpleDouble:
double data:
1
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
10
12-51
12
ans =
1x20 DocSimpleDouble:
double data:
Columns 1 through 13
1
2
3
4
Columns 14 through 20
14
15
16
17
18
19
20
5
15
6
16
7
17
10
8
18
9
19
10
20
11
12
13
[sc1;sc2]
ans =
2x10 DocSimpleDouble:
double data:
1
2
3
4
11
12
13
14
10
12
13
14
15
16
17
18
19
20
(:,:,2) =
11
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.
Related Examples
12-52
12-53
12
methods
function obj = DocUint8(data)
if nargin == 0
data = uint8(0);
end
obj = obj@uint8(data); % Store data on superclass
end
function h = showImage(obj)
data = uint8(obj);
figure; colormap(gray(256))
h = imagesc(data,[0 255]);
axis image
brighten(.2)
end
end
end
12-54
50
100
150
200
250
50
100
150
200
250
Because DocUint8 subclasses uint8, you can use any uint8 methods. For example,
size(img1)
ans =
280
272
12
showImage(img1(100:200,1:160));
10
20
30
40
50
60
70
80
90
100
20
40
60
80
100
120
140
160
50
100
150
200
250
50
100
150
200
250
Concatenation Operations
Concatenation operations work on DocUint8 objects because this class inherits the
uint8 horzcat and vertcat methods, which return a DocUint8 object:
showImage([img1 img1]);
12-57
12
50
100
150
200
250
50
100
150
200
250
300
350
400
450
500
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:
a = img1.*1.8;
showImage(a);
Undefined function 'showImage' for input arguments of type 'uint8'.
When you override a uint8 method, MATLAB calls the subclass method, not the base
class method. The subclass method must:
Call the uint8 times method on the DocUint8 object data.
Construct a new DocUint8 object using the uint8 data.
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);
12-59
12
50
100
150
200
250
50
100
150
200
Related Examples
12-60
250
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.
12-61
12
Methods Implemented
The following methods modify the behavior of the ExtendDouble class:
ExtendDouble The constructor supports a no argument syntax that initializes
properties to empty values.
subsref Enables subscripted reference to the superclass part of the subclass, dot
notation reference to the DataString property, and dot notation reference the builtin data via the name Data.
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.
12-62
obj.DataString = str;
end
function sref = subsref(obj,s)
switch s(1).type
case '.'
switch s(1).subs
case 'DataString'
sref = obj.DataString;
case 'Data'
d = double(obj);
if length(s)<2
sref = d;
elseif length(s)>1 && strcmp(s(2).type,'()')
sref = subsref(d,s(2:end));
end
otherwise
error('Not a supported indexing expression')
end
case '()'
d = double(obj);
newd = subsref(d,s(1:end));
sref = ExtendDouble(newd,obj.DataString);
case '{}'
error('Not a supported indexing expression')
end
end
function obj = subsasgn(obj,s,b)
switch s(1).type
case '.'
switch s(1).subs
case 'DataString'
obj.DataString = b;
case 'Data'
if length(s)<2
obj = ExtendDouble(b,obj.DataString);
elseif length(s)>1 && strcmp(s(2).type,'()')
d = double(obj);
newd = subsasgn(d,s(2:end),b);
obj = ExtendDouble(newd,obj.DataString);
end
otherwise
error('Not a supported indexing expression')
12-63
12
end
case '()'
d = double(obj);
newd = subsasgn(d,s(1),b);
obj = ExtendDouble(newd,obj.DataString);
case '{}'
error('Not a supported indexing expression')
end
end
function newobj = horzcat(varargin)
d1 = cellfun(@double,varargin,'UniformOutput',false );
data = horzcat(d1{:});
str = horzcat(cellfun(@char,varargin,'UniformOutput',false));
newobj = ExtendDouble(data,str);
end
function newobj = vertcat(varargin)
d1 = cellfun(@double,varargin,'UniformOutput',false );
data = vertcat(d1{:});
str = vertcat(cellfun(@char,varargin,'UniformOutput',false));
newobj = ExtendDouble(data,str);
end
function str = char(obj)
str = obj.DataString;
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:
ed = ExtendDouble(1:10,'One to ten')
ed =
12-64
One to ten
1
2
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
10
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. The class can implement
This class implements the following subscripted indexing expressions for reference and
assignment.
obj.DataString access the DataString property.
obj.Data, obj.Data(ind) access the data using a property-style reference.
Reference returns values of type double.
12-65
12
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
10
11
12
The ExtendDouble inherits converter methods from the double class. For example,
MATLAB calls the char method to perform this assignment statement.
12-66
13
ed(11:13) = ['a','b','c']
ed =
one to thirteen
1
2
10
97
98
99
Size
Bytes
a
b
ed
1x1
1x1
1x10
132
8
204
Class
Attributes
ExtendDouble
double
ExtendDouble
12
'Ten to one'
Columns 1 through 13
1
10
10
Columns 14 through 20
7
whos
Name
Size
Bytes
ed1
ed2
hcat
1x10
1x10
1x20
204
204
528
Class
Attributes
ExtendDouble
ExtendDouble
ExtendDouble
2
9
'Ten to one'
3
8
4
7
5
6
6
5
7
4
8
3
9
2
10
1
Both horzcat and vertcat return a new object of the same class as the subclass.
Related Examples
12-68
12-69
12
10
numel(d)
ans =
10
dsub = d(7:end);
size(dsub)
ans =
1
12-70
10
The numel function returns the number of elements in the superclass part:
numel(sd)
ans =
10
10
numel([sd;sd])
ans =
20
The SimpleDouble class inherits the indexing behavior of the double class:
sdsub = sd(7:end);
size(sdsub)
ans =
1
12-71
12
size(vs)
ans =
1
numel(vs)
ans =
1
size([vs;vs])
ans =
2
numel([vs;vs])
ans =
2
10
12-72
double
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 =
0
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
10
vsArray(1).Value(6)
ans =
6
12
numel to behave differently, override them by defining a size or numel method in your
subclass.
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.
See Also
numArgumentsFromSubscript
Related Examples
12-74
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.
classdef MuxCard < int32
properties
InPutNames
OutPutName
end
properties (Dependent = true)
OutPutRate
12-75
12
end
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));
if isscalar(s)
x = base;
else
x = subsref(base, s(2:end));
end
else
x = subsref(int32(card), s);
end
end
end
end
12-76
'inp2'
'inp3'
'inp4'}
OutPutName: 'outp'
OutPutRate: 75
int32 data:
3
12
12
48
'inp3'
Indexing the MuxCard object accesses the int32 vector of input port rates:
omx(1:2)
ans =
3
12
The OutPutRate property get access method uses sum to sum the output port rates:
omx.OutPutRate
ans =
75
Related Examples
12-77
12
12-78
By definition, an instance of the SubInt class is also an instance of the int16 class:
aInt = SubInt;
isa(aInt,'int16')
ans =
1
12-79
12
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 of
objects does not affect the result of the comparison performed by strcmp:
aInt = SubInt;
strcmp(class(aInt),'int16')
ans =
0
12-80
Define a cell array that contains the character arrays double and single:
floatTypes = {'double','single'};
% Test for proper types
if any(strcmp(class(a),floatTypes)) && ...
any(strcmp(class(b),floatTypes))
outArray = myMexFcn(a,b);
else
% Try to convert inputs to avoid error
...
end
12-81
12
Abstract Classes
In this section...
Abstract Classes on page 12-82
Declare Classes as Abstract on page 12-83
Determine If a Class Is Abstract on page 12-84
Find Inherited Abstract Properties and Methods on page 12-85
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 Terminology
abstract class A class that cannot be instantiated, but that defines class components
used by subclasses.
abstract members Properties or methods declared in an abstract class, but
implemented in subclasses.
concrete members Properties or methods that are fully implement by a class.
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 must
implement. Each subclass can implement the concrete properties and methods in a way
that supports their specific requirements.
Abstract classes can define properties and methods that are not abstract, and do not
need to define any abstract members. Abstract classes pass on their concrete members
through inheritance.
12-82
Abstract Classes
12
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 Properties
Define an abstract property:
properties (Abstract)
AbsProp
end
Use the logical value of the meta.class Abstract property to determine if the class is
abstract:
12-84
Abstract Classes
mc = ?AbsClass;
if ~mc.Abstract
% not an abstract class
end
12-85
12
absMethodOne
% defined in AbsClass
The SubAbsClass class is abstract because it has not implemented the absMethodOne
method defined in AbsClass.
msub = ?SubAbsClass;
msub.Abstract
ans =
1
If you implement both methods defined in AbsClass, the subclass becomes concrete.
Related Examples
12-86
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.
12-87
12
+graphics/LineGraph.m
% concrete subclass
Changing any object property automatically updates the currently displayed plot
Allowing each specialized GraphInterface object to implement whatever additional
properties it requires to give class users control over those characteristics.
Define the Interface
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:
classdef GraphInterface < handle
% Abstract class for creating data graphs
% Subclass constructor should accept
% the data that is to be plotted and
% property name/property value pairs
properties (SetAccess = protected, GetAccess = protected)
Primitive
AxesHandle
end
properties
Data
end
methods (Abstract)
draw(obj)
% Use a line, surface,
% or patch graphics primitive
zoom(obj,factor)
% Change the CameraViewAngle
% for 2D and 3D views
% use camzoom for consistency
updateGraph(obj)
% Update the Data property and
% update the drawing primitive
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));
12-89
12
uicontrol(hfig,'Style','pushbutton','String','Zoom In',...
'Callback',@(src,evnt)zoom(gobj,2),...
'Position',[100 20 60 20]);
end
end
end
12-90
Add Properties
The LineGraph class implements the interface defined in the GraphInterface class
and adds two additional propertiesLineColor and LineType. This class defines initial
values for each property, so specifying property values in the constructor is optional. You
can create a LineGraph object with no data, but you cannot produce a graph from that
object.
properties
LineColor = [0 0 0];
LineType = '-';
end
12-91
12
gobj.AxesHandle = get(h,'Parent');
end
12-92
gobj.(varargin{k}) = varargin{k+1};
end
end
end
end
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 = h.Parent;
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-93
12
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];
Related Examples
13
Saving and Loading Objects
Save and Load Process for Objects on page 13-2
Reduce MAT-File Size for Saved Objects on page 13-4
Save Object Data to Recreate Graphics Objects on page 13-6
Improve Version Compatibility with Default Values on page 13-8
Avoid Property Initialization Order Dependency on page 13-10
Modify the Save and Load Process on page 13-14
Basic saveobj and loadobj Pattern on page 13-17
Maintain Class Compatibility on page 13-21
Initialize Objects When Loading on page 13-28
Save and Load Objects from Class Hierarchies on page 13-30
Restore Listeners on page 13-33
Save and Load Dynamic Properties on page 13-36
13
13-3
13
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.
13-4
Related Examples
13-5
13
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.
13-6
end
properties(Transient)
Chart
end
properties(Access = private)
ChartData
end
methods
function rf = YearlyRainfall(data)
setup(rf,data);
end
function set.ChartData(obj,V)
setup(obj,V);
end
function V = get.ChartData(obj)
V = obj.Chart.YData;
end
end
methods(Access = private)
function setup(rf,data)
rf.Chart = bar(data);
end
end
end
Related Examples
13
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.
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';
13-8
end
end
Related Examples
13-9
13
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
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
13-11
13
Suppose that you create an instance of Odometer and set the following property values:
odObj = Odometer;
odObj.Units = 'km';
odObj.TotalDistance = 16;
13-12
end
methods
function distance = get.TripDistance(obj)
distance = obj.TotalDistance - obj.TripMarker;
end
end
end
Related Examples
13-13
13
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.
Use a loadobj method when:
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, perhaps 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-30.
The load function does not call the constructor by default. For more information, see
Initialize Objects When Loading on page 13-28.
13-15
13
Related Examples
13-16
13-17
13
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
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.
13-18
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
If the load function cannot create the object and passes a struct to loadobj, loadobj
attempts to create an object with the data supplied.
13-19
13
Related Examples
13-20
Rename Property
Suppose 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
13
classdef EmployeeList
properties
Name
Email
Location
end
properties (Dependent, Hidden)
OfficeNumber
end
methods
function obj = set.OfficeNumber(obj,val)
obj.Location = val;
end
function val = get.OfficeNumber(obj)
val = obj.Location;
end
end
end
13-22
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
13-23
13
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.
However, in future releases, the class will add more properties. To provide flexibility,
PhoneBookEntry saves property data in a struct using its saveobj method.
13-24
methods
function s = saveobj(obj)
s.Name = obj.Name;
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
13
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
properties (Dependent, SetAccess=private)
Address
end
properties (Transient)
SaveInOldFormat = false;
end
methods (Static)
function obj = loadobj(s)
if isstruct(s)
obj = PhoneBookEntry;
obj.Name = s.Name;
obj.Address = s.Address;
obj.PhoneNumber = s.PhoneNumber;
else
obj = s;
end
end
end
methods
function address = get.Address(obj)
address = [obj.StreetAddress,obj.Sep,obj.City,obj.Sep,...
obj.State,obj.Sep,obj.ZipCode];
end
function obj = set.Address(obj,address)
addressItems = regexp(address,obj.Sep,'split');
if length(addressItems) == 4
13-26
obj.StreetAddress = addressItems{1};
obj.City = addressItems{2};
obj.State = addressItems{3};
obj.ZipCode = addressItems{4};
else
error('PhoneBookEntry:InvalidAddressFormat', ...
'Invalid address format.');
end
end
function s = saveobj(obj)
if obj.SaveInOldFormat
s.Name = obj.Name;
s.Address = obj.Address;
s.PhoneNumber = obj.PhoneNumber;
end
end
end
end
Related Examples
13-27
13
13-28
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';
elseif v >= 10 && v < 100
obj.Status = 'In range';
else
obj.Status = 'Too high';
end
end
end
methods (Static)
function obj = loadobj(s)
if isstruct(s)
cv = s.CurrentValue;
obj = LabResults(cv);
else
obj = assignStatus(s);
end
end
end
end
The LabResults class uses loadobj to determine the status of a given test value. This
approach provides a way to:
Modify the criteria for determining status
Ensure that objects always use the current criteria
You do not need to implement a saveobj method.
Related Examples
13-29
13
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
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.
classdef MySub < MySuper
properties
Z
end
methods
function S = saveobj(obj)
S = saveobj@MySuper(obj);
S.PointZ = obj.Z;
13-31
13
end
function obj = reload(obj,S)
obj = reload@MySuper(obj,S);
obj.Z = S.PointZ;
end
end
methods (Static)
function obj = loadobj(S)
if isstruct(s)
obj = MySub;
obj = reload(obj,S);
end
end
end
end
Related Examples
13-32
Restore Listeners
Restore Listeners
In this section...
Create Listener with loadobj on page 13-33
Use Transient Property to Load Listener on page 13-33
Using the BankAccount and AccountManager Classes on page 13-35
13-33
13
AccountStatus
end
methods
function obj = BankAccount(initialBalance)
obj.AccountBalance = initialBalance;
obj.AccountStatus = 'New Account';
obj.AccountManagerListener = AccountManager.addAccount(obj);
end
end
methods (Static)
function obj = loadobj(obj)
if isstruct(obj) % Handle possble error
initialBalance = obj.AccountBalance;
obj = BankAccount(initialBalance);
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
13-34
Restore Listeners
end
end
Now set an account value to confirm that the AccountManager sets AccountStatus
appropriately:
ba.AccountBalance = -10;
ba.AccountStatus
ans =
overdrawn
Related Examples
13-35
13
Store the nondefault dynamic property attributes values for SetAccess and
GetAccess in the struct. The loadobj function restores these values.
methods
function s = saveobj(obj)
metaDynoProp = findprop(obj,'DynoProp');
s.dynamicprops(1).name = metaDynoProp.Name;
s.dynamicprops(1).value = obj.DynoProp;
s.dynamicprops(1).setAccess = metaDynoProp.SetAccess;
s.dynamicprops(1).getAccess = metaDynoProp.GetAccess;
...
end
end
Your loadobj method can add the dynamic property and set the attribute values:
Create an instance of the class.
Use addprop to add a new dynamic property to the object.
Restore the attributes of the dynamic property.
methods (Static)
function obj = loadobj(s)
if isstruct(s)
obj = ClassConstructor;
...
metaDynoProp = addprop(obj,s.dynamicprops(1).name);
obj.(s.dynamicprops(1).name) = s.dynamicprops(1).value;
metaDynoProp.SetAccess = s.dynamicprops(1).setAccess;
metaDynoProp.GetAccess = s.dynamicprops(1).getAccess;
end
end
end
Related Examples
13-37
14
Enumerations
Named Values on page 14-2
Define Enumeration Classes on page 14-5
Refer to Enumerations on page 14-11
Restrict Property Values to Enumerations on page 14-17
Operations on Enumerations on page 14-19
Enumeration Class Restrictions on page 14-27
Enumerations Derived from Built-In Types on page 14-28
Mutable Handle vs. Immutable Value Enumeration Members on page 14-34
Enumerations That Encapsulate Data on page 14-41
Save and Load Enumerations on page 14-45
14
Enumerations
Named Values
In this section...
Kinds of Predefined Names on page 14-2
Techniques for Defining Enumerations on page 14-3
Named Values
change (from [1 0 0] to [.93 .14 .14], for example) without updating every
function that accepts colors, as you would if you defined the color as the char vector
'red'.
Define enumerations by creating an enumeration block in the class definition.
See Define Enumeration Classes on page 14-5 for more information.
14
Enumerations
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
Related Examples
14-4
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.
14-5
14
Enumerations
Name
Size
today
1x1
Bytes
104
Class
Attributes
WeekDays
today
today =
Tuesday
Size
a
b
1x1
1x1
Bytes
60
4
Class
Attributes
Bearing
uint32
The uint32 constructor accepts an object of the subclass Bearing and returns and
object of class uint32.
14-6
14-7
14
Enumerations
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 =
1
Because SyntaxColors is a value class (it does not derive from handle), only the class
constructor can set property values:
e.R = 0
You cannot set the read-only property 'R' of SyntaxColors.
For more information on enumeration classes that define properties, see Mutable
Handle vs. Immutable Value Enumeration Members on page 14-34.
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 Bool < logical & MyBool
enumeration
No (0)
Yes (1)
end
end
14-9
14
Enumerations
Related Examples
14-10
Refer to Enumerations
Refer to Enumerations
In this section...
Instances of Enumeration Classes on page 14-11
Conversion of Characters to Enumerations on page 14-13
Enumeration Arrays on page 14-15
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.
classdef PPM < double
enumeration
High (1000)
Medium (100)
Low (10)
end
end
14
Enumerations
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 values
levelNew = level + 100
levelNew =
1100
Size
level
levelNew
1x1
1x1
Bytes
108
8
Class
Attributes
PPM
double
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
14-12
Refer to Enumerations
For information on operations you can perform on enumeration class instances, see
Operations on Enumerations on page 14-19.
Create an enumeration array using the WeekDay class constructor and a cell array of
char vectors.
wd = WeekDays({'Monday','Wednesday','Friday'})
wd =
Monday
Wednesday
Friday
class(wd)
ans =
WeekDays
14-13
14
Enumerations
All char vectors in the cell array must correspond to an enumeration member defined by
the class.
Coercion of char to Enumerations
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 =
Monday
Wednesday
Friday
Wednesday
Friday
Tuesday
14-14
Refer to Enumerations
Today is Friday
The automatic conversion of enumeration classes to char enable you to use enumeration
members in this case.
Enumeration Arrays
Create enumeration arrays by:
Concatenating enumeration members using []
Assigning enumeration members to an array using indexed assignment
Create an enumeration array of class WeekDays by concatenating enumeration members:
wd = [WeekDays.Tuesday,WeekDays.Wednesday,WeekDays.Friday];
14-15
14
Enumerations
WeekDays
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.
For example, assign a value to element 5 of an array, a:
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
a =
Monday
Monday
Monday
Related Examples
14-16
Monday
Tuesday
Use the WeekDays enumerations to restrict the allowed values of the Today property:
classdef Days
properties
Today WeekDays
end
end
14
Enumerations
d = Days;
d.Today = WeekDays.Tuesday;
d =
Days with properties:
Today: Tuesday
For more information on restricting property values, see Restrict Class of Properties on
page 8-20.
14-18
Operations on Enumerations
Operations on Enumerations
In this section...
Operations Supported by Enumerations on page 14-19
Enumeration Class on page 14-19
Default Methods on page 14-20
Convert Enumeration Member to Characters on page 14-20
Convert Enumeration Array to Cell Array of char Vectors on page 14-20
Enumerations and char Vectors in Relational Operations on page 14-21
Enumerations in switch Statements on page 14-22
Enumeration Set Membership on page 14-23
Enumeration Text Comparison Methods on page 14-24
How to Get Information About Enumerations on page 14-25
Testing for an Enumeration on page 14-25
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
14
Enumerations
Default Methods
Enumeration classes have the following default methods:
methods('WeekDays')
Methods for class WeekDays:
WeekDays
cellstr
char
eq
intersect
ismember
ne
setdiff
setxor
strcmp
strcmpi
strncmp
strncmpi
union
The WeekDays method converts char vectors or a cell array of char vectors 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.
ans =
Today is Friday
Operations on Enumerations
class([ca{1:2}])
ans =
char
14-21
14
Enumerations
Test equality to implement if statements. The char vector Wednesday is equal to (==)
the enumeration member WeekDays.Wednesday:
today = 'Wednesday';
...
if today == WeekDays.Wednesday
disp('Team meeting at 2:00')
end
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.
14-23
14
Enumerations
Determine if the enumeration member is a member of the cell array of char vectors.
ismember(WeekDays.Friday,{'Wednesday','Friday'})
ans =
1
14-24
Operations on Enumerations
0
strcmp(today,'Tuesday')
ans =
1
14-25
14
Enumerations
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 =
1
Related Examples
14-26
Related Examples
14-27
14
Enumerations
14-28
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 =
1
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];
First
Second
Third
14-29
14
Enumerations
ans =
1
For example, the actual name of an instance of the Bool.off enumeration member is
No:
a = Bool.No
a =
14-30
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 =
1
14-31
14
Enumerations
Low
(10)
Medium (50)
High
(100)
end
end
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 =
14-32
Yes
Yes
Related Examples
14-33
14
Enumerations
14-34
end
end
14-35
14
Enumerations
[red.R,red.G,red.B]
ans =
1
14-36
end
enumeration
Red
(1, 0, 0)
Green (0, 1, 0)
Blue (0, 0, 1)
end
end
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 =
14-37
14
Enumerations
0.8000
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 =
1
See the handle eq method for information on how isequal and == differ when used
with handles.
14-38
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.
classdef Machine < handle
properties (SetAccess = private)
State = MachineState.NotRunning;
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
14-39
14
Enumerations
NotRunning
Related Examples
14-40
14-41
14
Enumerations
You can asses the property values via the enumeration member:
Colors.Reddish.R
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 =
0.9294
0.1412
0.1490
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
14-42
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.
Enumerations Defining Categories
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.
classdef Cars < CarPainter
enumeration
Hybrid (2,'Manual',55,Colors.Reddish)
Compact(4,'Manual',32,Colors.Greenish)
MiniVan(6,'Automatic',24,Colors.Blueish)
SUV
(8,'Automatic',12,Colors.Yellowish)
end
properties (SetAccess = private)
Cylinders
Transmission
MPG
Color
end
methods
function obj = Cars(cyl,trans,mpg,colr)
obj.Cylinders = cyl;
obj.Transmission = trans;
obj.MPG = mpg;
obj.Color = colr;
end
function paint(obj,colorobj)
if isa(colorobj,'Colors')
obj.Color = colorobj;
else
[~,cls] = enumeration('Colors');
disp('Not an available color')
disp(cls)
end
end
14-43
14
Enumerations
end
end
The CarPainter class requires its subclasses to define a method called paint:
classdef CarPainter < handle
methods (Abstract)
paint(carobj,colorobj)
end
end
Related Examples
14-44
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.
14-45
14
Enumerations
More About
14-47
15
Constant Properties
15
Constant Properties
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.
Referencing Constant Properties
Refer to the constant using the class name and the property name:
ClassName.PropName
15-2
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 constants that are useful for making astronomical calculations, define
a AstroConstants class in a package called constants:
+constants/AstroConstants/AstroConstants.m
%
%
%
%
m/s
m/kgs
Earth mass (kg)
Earth radius (m)
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
15-3
15
Constant Properties
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 ConstantMapClass with a field ConstMapProp:
ConstMapClass.ConstMapProp('Date') = datestr(clock);
15-4
end
methods (Access = private)
function obj = MyProject
obj.Date = datestr(clock);
obj.Department = 'Engineering';
obj.ProjectNumber = 'P29.367';
end
end
end
Because MyProject is a handle class, you can get the handle to the instance that is
assigned to the constant property:
p = MyProject.ProjectInfo;
Modify the nonconstant properties of the MyProject class using this handle:
p.Department = 'Quality Assurance';
Clearing the class results in the assignment of a new instance of MyProject to the
ProjectInfo property.
15-5
15
Constant Properties
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
Related Examples
More About
15-6
16
Information from Class Metadata
Class Metadata on page 16-2
Class Introspection with Metadata on page 16-5
Find Objects with Specific Values on page 16-10
Get Information About Properties on page 16-14
Find Default Values in Property Metadata on page 16-20
16
Class Metadata
In this section...
What Is Class Metadata? on page 16-2
The meta Package on page 16-3
Metaclass Objects on page 16-3
Metaclass Object Lifecycle on page 16-4
16-2
'matlab.mixin.Copyable'
'Implement copy method for handle objects in MA...'
''
0
0
1
0
1
1
{0x1 cell}
[1x1 meta.package]
[0x1 meta.property]
[19x1 meta.method]
[1x1 meta.event]
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)
Create meta.class object from class name using the ? operator:
mc = ?MyClass;
Create meta.class object from class name using the fromName method:
mc = meta.class.fromName('MyClass');
16-3
16
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 of the classes in the meta package.
meta.class is a class in the meta package whose instances contain information about
MATLAB classes. Metadata is information about classes contained in metaclasses.
Related Examples
16-4
16-5
16
end
end
end
The EmployeeData class has only one superclass. For classes having more than one
direct superclass, a contains a meta.class object for each superclass.
Use an indexed reference to refer to any particular superclass:
a(1).Name
16-6
The length of mpArray indicates there are two meta.property objects, one for each
property defined by the EmployeeData class:
length(mpArray)
ans =
2
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.
Find Component with Specific Attribute
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
ans =
EmployeeNumber
Note that Access is not a property of the meta.property class. You must 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:
mc = ?handle;
mc.MethodList(ismember([mc.MethodList(:).Hidden],true)).Name
ans =
16-7
16
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)
You cannot get the 'EmployeeNumber' property of EmployeeData.
mpArray(2).GetAccess
ans =
private
16-8
end
end
Related Examples
16-9
16
NW = findobj(PB,'Name','Nancy Wong');
[NW.Name,' - ',NW.Number]
ans =
Nancy Wong - 5081234569
The -property option enables you to omit the value of the property and search for
objects using only the property name.
Using Logical Expressions
Search for specific combinations of property names and values:
H = findobj(PB,'Name','Nancy Vidal','-and','Address','123 Main Street');
H.Number
ans =
5081234568
16-11
16
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 Properties That Have Public Get Access
Find the names of all properties in the containers.Map class that have public
GetAccess:
Get the meta.class object.
Use findobj to search the array of meta.property objects.
Use braces to create a cell array of property names.
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} =
Count
names{2} =
KeyType
names{3} =
ValueType
16-12
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
method with properties:
Name:
Description:
DetailedDescription:
Access:
Static:
Abstract:
Sealed:
Hidden:
InputNames:
OutputNames:
DefiningClass:
'empty'
'Returns an empty object array of the given size'
''
'public'
1
0
0
1
{'varargin'}
{'E'}
[1x1 meta.class]
See Also
empty
Related Examples
16-13
16
'Count'
'Number of pairs in the collection'
''
'public'
'private'
1
0
0
1
0
0
0
0
[]
[]
[1x1 meta.class]
The preceding meta.property display shows that the default Map object Count
property:
16-14
'containers.Map'
'MATLAB Map Container'
'MATLAB Map Container'
0
0
1
1
{0x1 cell}
[1x1 meta.package]
[4x1 meta.property]
[35x1 meta.method]
[1x1 meta.event]
[0x1 meta.EnumeratedValue]
[1x1 meta.class]
The meta.class object contains a meta.property object for hidden properties too.
Compare the result with the properties function, which returns only public properties:
16-15
16
properties('containers.Map')
Properties for class containers.Map:
Count
KeyType
ValueType
The serialization property is Hidden and has its GetAccess and SetAccess
attributes set to private. Therefore, the properties function does not list it. However,
you can get information about this property from its associated meta.property object
(which is the fourth element in the array of meta.property objects in this case):
mc.PropertyList(4)
ans =
class with properties:
Name:
Description:
DetailedDescription:
GetAccess:
SetAccess:
Dependent:
Constant:
Abstract:
Transient:
Hidden:
GetObservable:
SetObservable:
AbortSet:
GetMethod:
SetMethod:
DefiningClass:
'serialization'
'Serialization property.'
''
'private'
'private'
0
0
0
0
1
0
0
0
[]
[]
[1x1 meta.class]
class(mc)
ans =
meta.class
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
16-17
16
16-18
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
'KeyType'
'ValueType'
'serialization'
'KeyType'
'ValueType'
Related Examples
16-19
16
Default Values
Class definitions can specify explicit default values for properties (see Property Default
Values on page 8-14). You can determine if a class defines explicit default values for a
property and what the value of the default is from the propertys 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 MATLAB MException class:
mc = ?MException;
The first element in the mp array is the meta.property object for the type property:
mp(1)
ans =
class with properties:
Name:
Description:
DetailedDescription:
GetAccess:
SetAccess:
Dependent:
Constant:
16-20
'type'
'Type of error reporting'
''
'private'
'private'
0
0
Abstract:
Transient:
Hidden:
GetObservable:
SetObservable:
AbortSet:
GetMethod:
SetMethod:
HasDefault:
DefaultValue:
DefiningClass:
0
0
0
1
1
0
[]
[]
1
{}
[1x1 meta.class]
Getting the meta.property object for the property whose default value you want to
query.
16
Follow these steps to obtain the default value defined for the Material property. Include
any error checking that is necessary for your application.
1
The length of the mp array equals the number of properties. You can use the
meta.property Name property to find the property of interest:
for k = 1:length(mp)
if (strcmp(mp(k).Name,'Material')
...
Before querying the default value of the Material property, test the HasDefault
meta.property to determine if MyClass defines a default property for this
property:
if mp(k).HasDefault
dv = mp(k).DefaultValue;
end
end
end
The DefaultValue property is read only. Changing the default value in the class
definition changes the value of DefaultValue property. You can query the default value
of a property regardless of its access settings.
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.
16-22
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 =
0
dv = mp.DefaultValue;
No default value has been defined for property Foo
Abstract Property
MyClass defines the Foo property as Abstract:
classdef MyAbst
16-23
16
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 =
0
dv = mp.DefaultValue;
Property Foo is abstract and therefore cannot have a default value.
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 =
16-24
1
dv = mp.DefaultValue;
Error using pie (line 29)
Not enough input arguments.
Querying the default value causes the evaluation of the expression and returns the error.
Property With Explicitly Defined Default Value of Empty ([])
MyEmptyProp assigns a default of [] (empty double) to the Foo property:
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 =
1
dv = mp.DefaultValue;
dv =
[]
Related Examples
16-25
17
Specialize Object Behavior
Methods That Modify Default Behavior on page 17-2
Number of Arguments for subsref and subsasgn on page 17-5
Modify nargout and nargin for Indexing Methods on page 17-8
Concatenation Methods on page 17-10
Object Converters on page 17-11
Object Array Indexing on page 17-14
Code Patterns for subsref and subsasgn Methods on page 17-20
Indexed Reference on page 17-27
Indexed Assignment on page 17-31
end as Object Index on page 17-36
Objects in Index Expressions on page 17-38
Class with Modified Indexing on page 17-40
Operator Overloading on page 17-48
17
Description
Concatenating Objects
cat, horzcat, and vertcat
Displaying Objects
disp
display
17-2
Description
Called when statements are not terminated by
semicolons. disp is often used to implement
display methods.
See Overloading the disp Function on page
18-41
See Custom Display Interface on page 18-2
Indexing Objects
subsref and subsasgn
end
numel
size
subsindex
17-3
17
Description
More About
17-4
17-5
17
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 =
1
ans =
2
ans =
3
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 =
1x13 ValuesArray array with properties:
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 subsref to support either '{}', '.', or both types of indexing and
the operation returns more than one value, overload subsref to return multiple values
using varargout:
function varargout = subsref(A,S)
...
end
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 = subsagn(A,S,varargin)
...
end
More About
17-7
17
function n = numArgumentsFromSubscript(obj,s,indexingContext)
...
end
Input Argument
Description
obj
Indexing structure that contains the indexing type and indices used
in the operation
More About
17-9
17
Concatenation Methods
In this section...
Default Concatenation on page 17-10
Methods to Overload on page 17-10
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]
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.
Related Examples
17-10
Object Converters
Object Converters
In this section...
Why Implement Converters on page 17-11
Converters for Package Classes on page 17-11
Converters and Subscripted Assignment on page 17-12
17-11
17
...
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.
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 RightSide variable.
For example, suppose that you make the following assignments:
A(1) = objA; % Object of class ClassA
A(2) = objB; % Object of class ClassB
Related Examples
17-12
Object Converters
17-13
17
8
2
5
5
6
7
7
3
7
Reference and assign elements of either array using index values in parentheses:
B(2) = A(3,4);
B
B =
3
17-14
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:
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.
For general information about array indexing, see Matrix Indexing.
17
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:
Dot notation calls to class methods
Dot notation reference and assignment involving properties
Any indexing using parentheses '()'
Any indexing using braces '{}'
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.
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)
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'))
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
17-17
17
ToF = false;
end
end
end
This behavior enables you to use standard MATLAB indexing to implement specialized
behaviors. See Class with Modified Indexing on page 17-40 for examples of how to
use both built-in and class-modified indexing.
17-18
B = A.(S.subs);
end
end
end
end
end
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
ans =
1
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.
Related Examples
17-19
17
Input
Output
b = subsref(obj,s)
b Result of indexing
expression
s Indexing structure
obj =
subsasgn(obj,s,b)
17-20
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
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];
17
A switch statement is a convenient way to detect the first level of indexing. There are
three types of indexingdot, 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.
Code Framework for subsref Method
The following framework for the subsref method shows how to use information in
the indexing structure in conditional statements. Your application can involve other
expression not shown here.
function varargout = subsref(obj,s)
switch s(1).type
case '.'
if length(s) == 1
% Implement obj.PropertyName
...
elseif length(s) == 2
% Implement obj.PropertyName(indices)
...
else
varargout = {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 = {builtin('subsref',obj,s)};
end
17-23
17
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 = {builtin('subsref',obj,s)};
end
otherwise
error('Not a valid indexing expression')
end
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:
[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 = subssasgn(obj,s,varargin)
switch s(1).type
17-24
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{:}
...
% Use built-in for any other expression
obj = {builtin('subsasgn',obj,s,varargin)};
end
otherwise
error('Not a valid indexing expression')
end
end
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:
C = {'one';'two','three'};
17-25
17
[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
Related Examples
17-26
Indexed Reference
Indexed Reference
In this section...
How Indexed Reference Works on page 17-27
Compound Indexed References on page 17-28
How to Write subsref for Objects on page 17-29
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.
For example, the expression:
A(1:4,:)
Causes MATLAB to call subsref(A,S), where S is a 1-by-1 structure with a twoelement cell array. The cell array contains the numbers 1, 2, 3, 4, and the colon character
:.
17-27
17
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
ans =
:
The default subsref returns all array elements in rows 1 through 4 and all the columns
in the array.
Similarly, this expression:
A{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
Indexed Reference
A(1,2).PropertyName(1:4)
S(2).type = '.'
S(2).subs = 'PropertyName'
S(3).type = '()'
S(3).subs = {1:4}
For a brace index when A is an object, you can implement indexing using {} as a
special case. For example, suppose that you want A{n} to access a property of A called
CellProperty, and that contains a cell array:
% Parse A{n}
switch S.type
case '{}'
B = A.CellProperty{S.subs{:}};
end
Although braces are used for cell arrays in MATLAB, your subsref method can define
its own meaning for this syntax.
Dot name indexing typically accesses property values. The name can be an arbitrary
char vector for which you take an arbitrary action:
switch S.type
case '.'
switch S.subs
17-29
17
case
B
case
B
'name1'
= A.name1;
'name2'
= A.name2;
end
end
If the dot name is a method call, passing arguments requires a second level of indexing.
Use Default Indexing
The method can call the built-in subsref to handle any of the three indexing types that
you do not want to change. For example, call the built-in for {} indexing:
case '{}'
varargout = builtin('subsref',A,s);
Related Examples
17-30
Indexed Assignment
Indexed Assignment
In this section...
How Indexed Assignment Works on page 17-31
Indexed Assignment to Objects on page 17-33
Compound Indexed Assignments on page 17-33
How to Write subsasgn for Objects on page 17-34
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.
For example, the assignment statement:
A(2,3) = B;
17
A = subsasgn(A,S,B)
S contains:
S.type = '()'
S.subs = {2,3}
Indexed Assignment
17
A(1,2).PropertyName(1:4) = B
S(2).type = '.'
S(2).subs = 'PropertyName'
S(3).type = '()'
S(3).subs = {1:4}
[2]
'three'
'four'}
classdef CellProp
properties
CellProperty cell = {1,2,'three'};
end
methods
function A = subsasgn(A,S,B)
switch S(1).type
case '()'
A(S(1).subs{:}) = B;
case '{}'
A.CellProperty{S.subs{:}} = B;
case '.'
name = S(1).subs{:};
if strcmp(name,'CellProperty')
A.CellProperty = B;
else
error('Not a valid property name')
end
end
end
function B = subsref(A,S)
switch S.type
case '()'
17-34
Indexed Assignment
B
case
B
case
B
end
= builtin('subsref',A,S);
'{}'
= A.CellProperty{S.subs{:}};
'.'
= builtin('subsref',A,S);
end
end
end
Related Examples
17-35
17
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,:)
17-36
If your class implements an end method, ensure that it returns a value appropriate for
the class.
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.
function ind = end(obj,k,n)
szd = size(obj.Data);
if k < n
ind = szd(k);
else
ind = prod(szd(k:end));
end
end
Related Examples
17-37
17
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.
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.
17-38
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:
function ind = subsindex(obj)
ind = uint8(obj);
end
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:
function ind = subsindex(obj)
ind = obj.ElementIndex;
end
See Also
Related Examples
More About
17-39
17
Class Description
The class has three properties:
Data numeric test data
Description description of test data
Date date test was conducted
Assume that you have the following random data (randi):
d = randi(9,3,4)
d =
17-40
8
9
2
9
6
1
3
5
9
9
2
9
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
17-41
17
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:
Calls the builtin subsref function for '.' indexing
Returns an error for '{}' indexing
Defines its own version of '()' indexing.
The result: obj(i) is equivalent to obj.Data(i).
function sref = subsref(obj,s)
% obj(i) is equivalent to obj.Data(i)
switch s(1).type
case '.'
sref = builtin('subsref',obj,s);
case '()'
if length(s) < 2
sref = builtin('subsref',obj.Data,s);
return
else
sref = builtin('subsref',obj,s);
end
case '{}'
error('MYDataClass:subsref',...
17-42
Add the functionality to assign values to the Data property with an expression like
this statement:
obj(2,3) = 9;
17-43
17
end
case '{}'
error('MyDataClass:subsasgn',...
'Not a supported subscripted assignment')
end
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 =
17-44
8
9
2
9
6
1
3
9
9
9
2
9
16
13
8
10
16
16
16
9
16
MyDataClass.m
This definition for MyDataClass includes the end indexing method discussed in end as
Object Index on page 17-36.
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
function sref = subsref(obj,s)
% obj(i) is equivalent to obj.Data(i)
switch s(1).type
case '.'
17-45
17
sref = builtin('subsref',obj,s);
case '()'
if length(s)<2
sref = builtin('subsref',obj.Data,s);
return
else
sref = builtin('subsref',obj,s);
end
case '{}'
error('MyDataClass:subsref',...
'Not a supported subscripted reference')
end
end
function obj = subsasgn(obj,s,val)
if isempty(s) && isa(val,'MyDataClass')
obj = MyDataClass(val.Data,val.Description);
end
switch s(1).type
case '.'
obj = builtin('subsasgn',obj,s,val);
case '()'
%
if length(s)<2
if isa(val,'MyDataClass')
error('MyDataClass:subsasgn',...
'Object must be scalar')
elseif isa(val,'double')
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);
17-46
end
function ind = end(obj,k,n)
szd = size(obj.Data);
if k < n
ind = szd(k);
else
ind = prod(szd(k:end));
end
end
end
end
Related Examples
17-47
17
Operator Overloading
In this section...
Why Overload Operators on page 17-48
How to Define Operators on page 17-48
Sample Implementation Addable Objects on page 17-49
MATLAB Operators and Associated Functions on page 17-51
17-48
Operator Overloading
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-44 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.
17-49
17
Using a double converter enables you to add numeric values to Adder objects as well as
other objects of the class.
a = Adder(1:10)
a =
Adder with properties:
NumericData: [1 2 3 4 5 6 7 8 9 10]
17-50
Operator Overloading
Ensure that your class provides any error checking required to implement your class
design.
Method to Define
Description
a + b
plus(a,b)
Binary addition
a - b
minus(a,b)
Binary subtraction
-a
uminus(a)
Unary minus
+a
uplus(a)
Unary plus
a.*b
times(a,b)
Element-wise multiplication
a*b
mtimes(a,b)
Matrix multiplication
a./b
rdivide(a,b)
a.\b
ldivide(a,b)
a/b
mrdivide(a,b)
a\b
mldivide(a,b)
a.^b
power(a,b)
Element-wise power
a^b
mpower(a,b)
Matrix power
a < b
lt(a,b)
Less than
a > b
gt(a,b)
Greater than
a <= b
le(a,b)
a >= b
ge(a,b)
a ~= b
ne(a,b)
Not equal to
a == b
eq(a,b)
Equality
a & b
and(a,b)
Logical AND
a | b
or(a,b)
Logical OR
17-51
17
Operation
Method to Define
Description
~a
not(a)
Logical NOT
a:d:b
colon(a,d,b)
Colon operator
a:b
colon(a,b)
a'
ctranspose(a)
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
Related Examples
17-52
18
Customizing Object Display
Custom Display Interface on page 18-2
How CustomDisplay Works on page 18-7
Role of size Function in Custom Displays on page 18-10
Customize Display for Heterogeneous Arrays on page 18-12
Class with Default Object Display on page 18-14
Choose a Technique for Display Customization on page 18-19
Customize Property Display on page 18-23
Customize Header, Property List, and Footer on page 18-26
Customize Display of Scalar Objects on page 18-32
Customize Display of Object Arrays on page 18-36
Overloading the disp Function on page 18-41
18
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:
classdef MyClass < matlab.mixin.CustomDisplay
18
The default object display does not include a footer. The detailed display provides more
information:
Purpose
Default
getHeader
getPropertyGroups
Define how and what properties
display, including order, values, and
grouping.
18-4
Method
Purpose
Default
getFooter
displayScalarObject
displayNonScalarObject
prod(size(obj)) > 1
displayEmptyObject
prod(size(obj)) == 0
displayScalarHandleToDeletedObject
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.
18-5
18
Method
Inputs
Outputs
convertDimensionsToString
displayPropertyGroups
PropertyGroup array
getClassNameForHeader
Object
getDeletedHandleText
None
getDetailedFooter
Object
getDetailedHeader
Object
getHandleText
None
getSimpleHeader
Object
Related Examples
18-6
MATLAB determines the class of obj and calls the disp method to display the
object.
When obj is a scalar handle object, disp calls isvalid to determine if obj is the
handle of a deleted object. Deleted handles in nonscalar arrays do not affect the
display.
disp calls the state handler method for an object of the state of obj. In this case,
obj is a valid scalar that results in a call to:
displayScalarObject(obj)
18-7
18
disp(footer)
MATLAB follows a similar sequence for nonscalar object arrays and empty object arrays.
In the case of scalar handles to deleted objects, disp calls the
displayScalarHandleToDeletedObject method, which displays the default text for
handles to deleted objects without calling any part-builder methods.
18-8
Related Examples
18-9
18
Related Examples
18-11
18
18-12
function displayScalarHandleToDeletedObject(obj)
displayScalarHandleToDeletedObject@matlab.mixin.CustomDisplay(obj);
end
end
end
Related Examples
18-13
18
18-14
end
end
'Bill Tork'
'Software Engineer'
'Product Development'
1000
'bill123'
18
>>[Emp123,Emp124]
ans
1x2 EmployeeInfo array with properties:
Name
JobTitle
Department
Salary
Password
18-16
Department
Salary
Password
>> isscalar(emt)
ans =
0
'Bill Tork'
'Software Engineer'
'Product Development'
1000
'bill123'
18-17
18
Related Examples
18-18
18
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 18-8)
18-20
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 = getPropertyGroups@matlab.mixin.CustomDisplay(obj);
end
end
end
end
18
18-22
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
18-23
18
end
When you create a PropertyGroup object using a cell array of property names,
MATLAB automatically
Adds the property values for a scalar object display
Uses the property names without values for a nonscalar object display (including
empty object arrays)
The getPropertyGroups method is not called to create the display for a scalar handle
to a deleted object.
18-24
JobTitle:
Name:
Salary:
Password:
'Software Engineer'
'Bill Tork'
'Not available'
'*******'
Related Examples
18-25
18
Objective
Customize each of the three parts of the display header, property groups, and footer.
18-27
18
Emp123 =
handle to deleted EmployeeInfo
Implementation
The EmployeeInfo class overrides three matlab.mixin.CustomDisplay methods to
implement the display shown:
getHeader
getPropertyGroups
getFooter
Each method must produce the desired results with each of the following inputs:
Scalar object
Nonscalar object array
Empty object array
18-28
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 objects 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.
Both branches return a matlab.mixin.util.PropertyGroup object, which determines how
to displays the object properties.
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.
18-29
18
18-30
propgrp(2) = matlab.mixin.util.PropertyGroup(propList2,gTitle2);
end
end
function footer = getFooter(obj)
if isscalar(obj)
footer = sprintf('%s\n','Company Private');
else
footer = '';
end
end
end
end
Related Examples
18-31
18
Objective
Customize the display of scalar objects.
18-32
Personal Info
Salary: 'Level: 10'
Password: '*******'
Implementation
The EmployeeInfo class overrides two matlab.mixin.CustomDisplay methods to
implement the display shown:
displayScalarObject Called to display valid scalar objects
getPropertyGroups Builds the property groups for display
18-33
18
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:
Defines two titles for the two groups
Creates a cell array of property names that are included in the first group. MATLAB
adds the property values for the display
Creates a struct array of property names with associated property values for the
second group. Using a struct instead of a cell array enables you to replace the values
that are displayed for the Salary and Password properties without changing the
personal information stored in the object properties.
Constructs two matlab.mixin.util.PropertyGroup objects, which are used by the
displayScalarObject 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)
if ~isscalar(obj)
propgrp = getPropertyGroups@matlab.mixin.CustomDisplay(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
18-34
Related Examples
18-35
18
Objective
Customize the display of nonscalar objects, including empty object arrays.
18-36
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:
displayNonScalarObject Called to display nonempty object arrays
displayEmptyObject Called to display empty object arrays
18
Uses the displayPropertyGroups static method to generate the property display for
valid objects.
Here is the implementation of displayNonScalarObjects:
methods (Access = protected)
function displayNonScalarObject(objAry)
dimStr = matlab.mixin.CustomDisplay.convertDimensionsToString(objAry);
cName = matlab.mixin.CustomDisplay.getClassNameForHeader(objAry);
headerStr = [dimStr,' ',cName,' members:'];
header = sprintf('%s\n',headerStr);
disp(header)
for ix = 1:length(objAry)
o = objAry(ix);
if ~isvalid(o)
str1 = matlab.mixin.CustomDisplay.getDeletedHandleText;
str2 = matlab.mixin.CustomDisplay.getClassNameForHeader(o);
headerInv = [str1,' ',str2];
tmpStr = [num2str(ix),'. ',headerInv];
numStr = sprintf('%s\n',tmpStr);
disp(numStr)
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
end
18-38
18-39
18
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
Related Examples
18-40
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.
18
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.
When invoked display:
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 built-in display function calls disp.
Code explicitly invokes disp.
For empty built-in types (numeric types, char, struct, and cell) the display function
displays:
[] for numeric types
"0x0 struct array with no fields." for empty structs.
"Empty cell array: 0-by-1" for empty cell arrays.
'' for empty char arrays
disp differs from display in these ways:
disp does not print the variable name or ans.
disp prints nothing for built-in types (numeric types, char, struct, and cell) when
the value is empty.
Related Examples
18-42
19
Implementing a Class for Polynomials
19
Object Requirements
This example implements a class to represent polynomials in the MATLAB language.
The design requirements are:
Value class behaviora 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.
Class
Default
Description
coef
double
[]
The following table summarizes the methods for the DocPolynom class.
DocPolynom Class Methods
Name
Description
DocPolynom
Class constructor
double
char
disp
subsref
plus
minus
mtimes
p1 = DocPolynom([1 0 -2 -5])
p1 =
x^3 - 2*x - 5
p2 = DocPolynom([2 0 3 2 -7])
19-3
19
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
properties
coef
end
methods
19-4
Discussion
Value class that implements a
data type for polynomials.
Vector of polynomial coefficients
[highest order ... lowest order]
For general information
about methods, see Ordinary
Methods on page 9-7
Class constructor creates objects
using:
Coefficient vector of existing
object
Coefficient vector passed as
argument
Example Code
function c = double(obj)
c = obj.coef;
end
Discussion
See The DocPolynom
Constructor on page 19-13
Set method for coef property:
Allows coefficients only of
type double
Removes leading zeros from
the coefficient vector.
See Remove Irrelevant
Coefficients on page 19-14
Convert DocPolynom object
to double by returning the
coefficients.
See Convert DocPolynom
Objects to Other Types on page
19-15
19-5
19
Example Code
function str = char(obj)
if all(obj.coef == 0)
s = '0';
str = s;
return
else
d = length(obj.coef)-1;
s = cell(1,d);
ind = 1;
for a = obj.coef;
if a ~= 0;
if ind ~= 1
if a > 0
s(ind) = {' + '};
ind = ind + 1;
else
s(ind) = {' - '};
a = -a;
ind = ind + 1;
end
end
if a ~= 1 || d == 0
if a == -1
s(ind) = {'-'};
ind = ind + 1;
else
s(ind) = {num2str(a)};
ind = ind + 1;
if d > 0
s(ind) = {'*'};
ind = ind + 1;
end
end
end
if d >= 2
s(ind) = {['x^' int2str(d)]};
ind = ind + 1;
elseif d == 1
s(ind) = {'x'};
ind = ind + 1;
end
end
19-6
Discussion
Convert DocPolynom object
to char that represents the
expression:
y = f(x)
See Convert DocPolynom
Objects to Other Types on page
19-15
Example Code
Discussion
d = d - 1;
end
end
str = [s{:}];
end
function disp(obj)
c = char(obj);
if iscell(c)
disp(['
' c{:}])
else
disp(c)
end
end
function dispPoly(obj,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
19-7
19
Example Code
Discussion
function b = subsref(a,s)
Redefine indexed reference for
switch s(1).type
DocPolynom objects.
case '()'
ind = s.subs{:};
For information about this
b = polyval(a.coef,ind);
code, see Redefine Indexed
case '.'
Reference on page 19-19
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
19-8
Example Code
Discussion
function r = plus(obj1,obj2)
Define three arithmetic
obj1 = DocPolynom(obj1);
operators:
obj2 = DocPolynom(obj2);
k = length(obj2.coef) - length(obj1.coef);
Polynomial addition
zp = zeros(1,k);
Polynomial subtraction
zm = zeros(1,-k);
r = DocPolynom([zp,obj1.coef] + [zm,obj2.coef]);
Polynomial multiplication
end
function r = minus(obj1,obj2)
code, see Define Arithmetic
obj1 = DocPolynom(obj1);
Operators on page 19-21
obj2 = DocPolynom(obj2);
k = length(obj2.coef) - length(obj1.coef);
For general information
zp = zeros(1,k);
about defining operators, see
zm = zeros(1,-k);
Operator Overloading on page
r = DocPolynom([zp,obj1.coef] - [zm,obj2.coef]);
17-48
end
function r = mtimes(obj1,obj2)
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
r = DocPolynom(conv(obj1.coef,obj2.coef));
end
end
end
end
19-9
19
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
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
function str = char(obj)
% Created a formated display of the polynom
% as powers of x
if all(obj.coef == 0)
s = '0';
str = s;
return
else
d = length(obj.coef)-1;
s = cell(1,d);
ind = 1;
for a = obj.coef;
if a ~= 0;
if ind ~= 1
if a > 0
s(ind) = {' + '};
ind = ind + 1;
else
s(ind) = {' - '};
19-10
a = -a; %#ok<FXSET>
ind = ind + 1;
end
end
if a ~= 1 || d == 0
if a == -1
s(ind) = {'-'};
ind = ind + 1;
else
s(ind) = {num2str(a)};
ind = ind + 1;
if d > 0
s(ind) = {'*'};
ind = ind + 1;
end
end
end
if d >= 2
s(ind) = {['x^' int2str(d)]};
ind = ind + 1;
elseif d == 1
s(ind) = {'x'};
ind = ind + 1;
end
end
d = d - 1;
end
end
str = [s{:}];
end % 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);
19-11
19
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)
% PLUS Implement obj1 + obj2 for DocPolynom
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
19-12
k = length(obj2.coef) - length(obj1.coef);
zp = zeros(1,k);
zm = zeros(1,-k);
r = DocPolynom([zp,obj1.coef] + [zm,obj2.coef]);
end % plus
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
19
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 19-14 for a description of the property set method.
An example use of the DocPolynom constructor is the statement:
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 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.
19-14
if ~isempty(ind);
obj.coef = val(ind(1):end);
else
obj.coef = val;
end
end
end
the statement:
c = double(p)
returns:
c=
1
-2
-5
19
class(c)
ans =
double
19-16
if d > 0
s(ind) = {'*'};
ind = ind + 1;
end
end
end
if d >= 2
s(ind) = {['x^' int2str(d)]};
ind = ind + 1;
elseif d == 1
s(ind) = {'x'};
ind = ind + 1;
end
end
d = d - 1;
end
end
str = [s{:}];
end
end
19-17
19
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
19-18
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
19
obj = p.method Use dot notation to call methods without arguments and return
a modified object.
subsref Implementation Details
The subsref method overloads the subsref function.
For example, consider a call to the polyval function:
p = DocPolynom([1 0 -2 -5])
p =
x^3 - 2*x - 5
polyval(p.coef,[3 5 7])
ans =
16
110
324
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;
19-20
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
Operator Implemented
plus(a,b)
Addition
minus(a,b)
Subtraction
mtimes(a,b)
Matrix multiplication
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
If either p or q is a DocPolynom object, this expression:
p + q
19-21
19
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
methods
function r = mtimes(obj1,obj2)
obj1 = DocPolynom(obj1);
obj2 = DocPolynom(obj2);
r = DocPolynom(conv(obj1.coef,obj2.coef));
end
end
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
19-23
20
Designing Related Classes
A Simple Class Hierarchy on page 20-2
Containing Assets in a Portfolio on page 20-20
20
The following diagram shows the properties defined for the classes of assets.
DocAsset
Properties
Description
Date
Type
CurrentValue
DocStocks
(is a DocAsset)
DocBonds
(is a DocAsset)
DocSavings
(is a DocAsset)
Inherited Props
Description
Date
Type
CurrentValue
Inherited Props
Description
Date
Type
CurrentValue
Inherited Props
Description
Date
Type
CurrentValue
DocStocks Props
NumShares
SharePrice
DocBonds Props
FaceValue
Yield
CurrentBondYield
DocSavings Props
InterestRate
The DocStock, DocBond, and DocSavings classes inherit properties from the DocAsset
class. In this example, the DocAsset class provides storage for data common to all
subclasses and shares methods with these subclasses.
20
Class
Default
Description
Description
char
''
Description of asset
CurrentValue
double
Date
char
date
Type
char
'savings'
The following table summarizes the methods for the DocAsset class.
DocAsset Class Methods
20-4
Name
Description
DocAsset
Class constructor
disp
set.Type
Set function for Type. Property tests for correct value when
property is set.
20-5
20
a.CurrentValue = current_value;
end
end % DocAsset
The MATLAB runtime calls this function whenever an attempt is made to set the Type
property, even from within the class constructor function or by assigning an initial value.
Therefore, the following statement in the class definition would produce an error:
properties
Type = 'cash';
end
The only exception is the set.Type function itself, where the statement:
obj.Type = type;
The DocAsset subclass display methods can now call this method to display the data
stored in the parent class. This approach isolates the subclass disp methods from
changes to the DocAsset class.
20-6
Class
Default
Description
NumShares
double
SharePrice
double
char
''
Description of asset
20-7
20
Name
Class
Default
Description
CurrentValue
double
Date
char
date
Type
char
''
The following table summarizes the methods for the DocStock class.
DocStock Class Methods
Name
Description
DocStock
Class constructor
disp
creates a DocStock object, XdotcomStock, that contains information about a stock asset
in Xdotcom Corp. The asset consists of 200 shares that have a per share value of $23.47.
The DocStock Constructor Method
The constructor first creates an instance of a DocAsset object since the DocStock class
is derived from the DocAsset class (see The DocAsset Constructor Method on page
20-5). The constructor returns the DocStock object after setting value for its two
properties:
function s = DocStock(description,num_shares,share_price)
if nargin ~= 3 % Support no argument constructor syntax
description = '';
num_shares = 0;
share_price = 0;
end
s = s@DocAsset(description,'stock',share_price*num_shares);
s.NumShares = num_shares;
s.SharePrice = share_price;
end % DocStock
the MATLAB runtime looks for a method in the @DocStock folder called disp. The disp
method for the DocStock class produces this output:
Description: Xdotcom
Date: 17-Nov-1998
Type: stock
Current Value: $2500.00
Number of shares: 100
Share price: $25.00
The following function is the DocStock disp method. When this function returns from
the call to the DocAsset disp method, it uses fprintf to display the Numshares and
SharePrice property values on the screen:
20-9
20
function disp(s)
disp@DocAsset(s)
fprintf('Number of shares: %g\nShare price: %3.2f\n',...
s.NumShares,s.SharePrice);
end % disp
Class
Default
Description
FaceValue
double
SharePrice
double
20-10
Description
char
''
Description of asset
CurrentValue
double
Date
char
date
Name
Class
Default
Description
Type
char
''
The following table summarizes the methods for the DocStock class.
DocBond Class Methods
Name
Description
DocBond
Class constructor
disp
calc_value
20
creates a DocBond object, b, that contains information about a bond asset xyzbond with
a face value of $100, a yield of 4.3%, and also contains information about the current
yield of such bonds (6.2% in this case) that is used to calculate the current value.
Note The calculations performed in this example are intended only to illustrate the use
of MATLAB classes and do not represent a way to determine the actual value of any
monetary investment.
The DocBond Constructor Method
The DocBond constructor method requires four arguments. It also supports the no
argument syntax by defining default values for the missing input arguments:
function b = DocBond(description,face_value,yield,current_yield)
if nargin ~= 4
description = '';
face_value = 0;
yield = 0;
current_yield = 0;
end
market_value = DocBond.calc_value(face_value,yield,current_yield);
b = b@DocAsset(description,'bond',market_value);
b.FaceValue = face_value;
b.Yield = yield;
b.CurrentBondYield = current_yield;
end % DocBond
Calculation of the asset's market value requires that the yields be nonzero, and should be
positive just to make sense. While the calc_value method issues no errors for bad yield
values, it does ensure bad values are not used in the calculation of market value.
The asset's market value is passed to the DocAsset base-class constructor when it is
called within the DocBond constructor. calc_value has its Static attribute set to
true because it does not accept a DocBond object as an input argument. The output of
calc_value is used by the base-class (DocAsset) constructor:
methods (Static)
function market_value = calc_value(face_value,yield,current_yield)
if current_yield <= 0 || yield <= 0
market_value = face_value;
else
market_value = face_value*yield/current_yield;
end
end % calc_value
end % methods
the MATLAB runtime looks for a method in the @DocBond folder called disp. The disp
method for the DocBond class produces this output:
Description: xyzbond
Date: 17-Nov-1998
Type: bond
Current Value: $69.35
Face value of bonds: $100
Yield: 4.30%
The following function is the DocBond disp method. When this function returns from
the call to the DocAsset disp method, it uses fprintf to display the FaceValue,
Yield, and CurrentValue property values on the screen:
function disp(b)
disp@DocAsset(b) % Call DocAsset disp method
fprintf('Face value of bonds: $%g\nYield: %3.2f%%\n',...
b.FaceValue,b.Yield);
end % disp
20-13
20
Class
Default
Description
InterestRate
double
''
20-14
Description
char
''
Description of asset
CurrentValue
double
Current value of
asset
Date
char
date
Type
char
''
The following table summarizes the methods for the DocSavings class.
DocSavings Class Methods
Name
Description
DocSavings
Class constructor
disp
creates a DocSavings object, sv, that contains information about an account in MyBank
with a balance of $1000 and an interest rate of 2.9%.
20-15
20
the MATLAB runtime looks for a method in the @DocSavings folder called disp. The
disp method for the DocSavings class produces this output:
Description: MyBank
Date: 17-Nov-1998
Type: savings
Current Value: $1000.00
Interest Rate: 2.90%
The following function is the DocSaving disp method. When this function returns from
the call to the DocAsset disp method, it uses fprintf to display the Numshares and
SharePrice property values on the screen:
function disp(b)
disp@DocAsset(b) % Call DocAsset disp method
fprintf('%s%3.2f%%\n','Interest Rate: ',s.InterestRate);
end % disp
20-16
20-17
20
description = '';
num_shares = 0;
share_price = 0;
end
s = s@DocAsset(description, 'stock', share_price*num_shares);
s.NumShares = num_shares;
s.SharePrice = share_price;
end
function disp(s)
disp@DocAsset(s)
fprintf('Number of shares: %g\nShare price: $%2.2f\n',...
s.NumShares,s.SharePrice);
end
end
end
20-18
else
market_value = face_value*yield/current_yield;
end
end
end
end
20-19
20
Kinds of Containment
Aggregation is the containment of objects by other objects. The basic relationship is that
each contained object "is a part of" the container object. Composition is a more strict form
of aggregation in which the contained objects are parts of the containing object and are
not associated with any other objects. Portfolio objects form a composition with asset
objects because the asset objects are value classes, which are copied when the constructor
method creates the DocPortfolio object.
For example, consider a financial portfolio class as a container for a set of assets (stocks,
bonds, savings, and so on). It can group, analyze, and return useful information about
the individual assets. The contained objects are not accessible directly, but only via the
portfolio class methods.
A Simple Class Hierarchy on page 20-2 provides information about the assets collected
by this portfolio class.
Class
Default
Description
Name
char
''
IndAssets
cell
{}
TotalValue
double
The following table summarizes the methods for the DocPortfolio class.
DocBond Class Methods
Name
Description
DocPortfolio
Class constructor
disp
pie3
20
20-22
XYZStock,...
SaveAccount,...
USTBonds)
The DocPortfolio pie3 Method on page 20-24 provides a graphical display of the
portfolio.
20-23
20
if nargin > 0
p.Name = name;
for k = 1:length(varargin)
p.IndAssets{k} = varargin(k);
asset_value = p.IndAssets{k}{1}.CurrentValue;
p.TotalValue = p.TotalValue + asset_value;
end
end
end % DocPortfolio
20-24
label(k) = {'Stocks'};
pie_vector(k) = stock_amt;
k = k + 1;
end % if
if bond_amt ~= 0
label(k) = {'Bonds'};
pie_vector(k) = bond_amt;
k = k + 1;
end % if
if savings_amt ~= 0
label(k) = {'Savings'};
pie_vector(k) = savings_amt;
end % if
% Step 3: Call pie3, adjust fonts and colors
pie3(pie_vector,label);set(gcf,'Renderer','zbuffer')
set(findobj(gca,'Type','Text'),...
'FontSize',14,'FontWeight','bold')
colormap prism
stg(1) = {['Portfolio Composition for ',p.Name]};
stg(2) = {['Total Value of Assets: $',num2str(p.TotalValue,'%0.2f')]};
title(stg,'FontSize',10)
end % pie3
Visualizing a Portfolio
You can use a DocPortfolio object to present an individual's financial portfolio. For
example, given the following assets:
XYZStock = DocStock('XYZ Stocks',200,12.34);
USTBonds = DocBond('U.S. Treasury Bonds',1600,3.2,2.8);
SaveAccount = DocSavings('MyBank Acc # 123',2000,6);
VictoriaSelna = DocPortfolio('Victoria Selna',...
XYZStock,...
SaveAccount,...
USTBonds);
you can use the class's pie3 method to display the relative mix of assets as a pie chart.
20-25
20
pie3(VictoriaSelna)
20-26
end
end
function disp(p)
fprintf('\nAssets for Client: %s\n',p.Name);
for k = 1:length(p.IndAssets)
disp(p.IndAssets{k}{1})
end
fprintf('\nTotal Value: $%0.2f\n',p.TotalValue);
end
function pie3(p)
stock_amt = 0; bond_amt = 0; savings_amt = 0;
for k=1:length(p.IndAssets)
if isa(p.IndAssets{k}{1},'DocStock')
stock_amt = stock_amt + p.IndAssets{k}{1}.CurrentValue;
elseif isa(p.IndAssets{k}{1},'DocBond')
bond_amt = bond_amt + p.IndAssets{k}{1}.CurrentValue;
elseif isa(p.IndAssets{k}{1},'DocSavings')
savings_amt = savings_amt + p.IndAssets{k}{1}.CurrentValue;
end
end
i = 1;
if stock_amt ~= 0
label(i) = {'Stocks'};
pie_vector(i) = stock_amt;
i = i +1;
end
if bond_amt ~= 0
label(i) = {'Bonds'};
pie_vector(i) = bond_amt;
i = i +1;
end
if savings_amt ~= 0
label(i) = {'Savings'};
pie_vector(i) = savings_amt;
end
pie3(pie_vector,label)
set(findobj(gca,'Type','Text'),'FontSize',14,'FontWeight','bold')
set(gcf,'Renderer','zbuffer')
colormap prism
stg(1) = {['Portfolio Composition for ',p.Name]};
stg(2) = {['Total Value of Assets: $',num2str(p.TotalValue,'%0.2f')]};
title(stg,'FontSize',10)
end
end
end
20-27