This example defines a class that modifies the default indexing behavior by implementing subsref
and subsasgn
methods. The class also implements type conversion and addition by implementing a double
converter method and a plus
method.
The objective of the class design is to:
Enable you to treat an object of the class as a numeric array
Be able to contain nonnumeric and numeric data in an object of the class
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 = 8 9 3 9 9 6 5 2 2 1 9 9
Create an instance of the class:
obj = MyDataClass(d,'Test001')
obj = MyDataClass with properties: Data: [3x4 double] Description: 'Test001' Date: [2012 1 7 9 32 34.5190]
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
Implement a subsref
method to support both the default and a specialized type of indexing.
The default indexed reference behavior for scalar objects:
obj.Data(2,3)
ans = 5
And to add the functionality to index into the Data
property with an expression like this statement:
obj(2,3)
If you redefine '()'
indexing to support access to the Data
property, you cannot create arrays of MyDataClass
objects and use '()'
indexing to access individual objects. You can reference only scalar objects.
To achieve the design goals, the subsref
method must handle all indexing types. The subsref
method:
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); else sref = builtin('subsref',obj,s); end case '{}' error('MYDataClass:subsref',... 'Not a supported subscripted reference') end end
To support the equivalent of the indexed reference behavior with indexed assignment, implement a subsasgn
method.
Support the default indexed assignment:
obj.Data(2,3) = 9;
Add the functionality to assign values to the Data
property with an expression like this statement:
obj(2,3) = 9;
Like the subsref
method, the subsasgn
method:
Calls the builtin
subsasgn
function for '.'
indexing
Returns an error for '{}'
indexing
Defines its own version of '()'
indexing.
The substruct
function redefines the index type and index subscripts structure that MATLAB® passes to subsref
and subsasgn
.
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') % Redefine the struct s to make the call: obj.Data(i) snew = substruct('.','Data','()',s(1).subs(:)); obj = subsasgn(obj,snew,val); end end case '{}' error('MyDataClass:subsasgn',... 'Not a supported subscripted assignment') end end
First, implement a double
method that converts an object to an array of doubles. By implementing a double
converter method, it is possible to add a MyDataClass
object to another class of object. However, the other class must implement a double
method that also returns an array of doubles. For more information on type conversion, see Object Converters.
Allow direct addition of the Data
property values by implementing a plus
method. Implementing a plus
method enables the use of the +
operator for addition of MyDataClass
objects.
Because the plus method implements addition by adding double arrays, MATLAB:
Apply the rules of addition when adding MyDataClass
objects
Returns errors for any condition that can cause errors in default numeric addition. For example, dimension mismatch.
The plus
method uses the double
method to convert the object to numeric values before performing the addition:
function a = double(obj) a = obj.Data; end
function c = plus(obj,b) c = double(obj) + double(b); end
For example, the plus
method enables you to add a scalar number to the object Data
array.
Here are the values of the Data
, displayed using indexed reference:
obj(:,:)
ans = 8 9 3 9 9 6 9 2 2 1 9 9
Add 7
to the array contained in the Data
property:
obj + 7
ans = 15 16 10 16 16 13 16 9 9 8 16 16
This definition for MyDataClass
includes the end
indexing method discussed in end as Object Index. extraneous
classdef MyDataClass % Example for "A Class with Modified Indexing" properties Data Description end properties (SetAccess = private) Date end methods function obj = MyDataClass(data,desc) % Support 0-2 args if nargin > 0 obj.Data = data; end if nargin > 1 obj.Description = desc; end obj.Date = clock; end 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); 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); 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