Object Array Indexing

Default Indexed Reference and Assignment

MATLAB® classes support object array indexing by default. Many class designs require no modification to this behavior.

Arrays enable you to reference and assign elements of the array using a subscripted notation. This notation specifies the indices of specific array elements. For example, suppose that you create two arrays of numbers (using randi and concatenation).

Create a 3-by-4 array of integers from 1 through 9:

A = randi(9,3,4)
A =

     4     8     5     7
     4     2     6     3
     7     5     7     7

Create a 1-by-3 array of the numbers 3, 6, 9:

B = [3 6 9];

Reference and assign elements of either array using index values in parentheses:

B(2) = A(3,4);
B
B =
     3     7     9

When you execute a statement that involves indexed reference:

C = A(3,4);

MATLAB calls the built-in subsref function to determine how to interpret the statement. Similarly, if you execute a statement that involves indexed assignment:

C(4) = 7;

MATLAB calls the built-in subsasgn function to determine how to interpret the statement.

The MATLAB default subsref and subsasgn functions also work with user-defined objects. For example, create an array of objects of the same class:

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 Array Indexing.

What You Can Modify

You can modify your class indexed reference and/or assignment behavior by implementing class methods called subsref and subsasgn. For syntax description, see their respective reference pages.

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.

When to Modify Indexing Behavior

Default indexing for object arrays and dot notation for access to properties and methods enables user-defined objects to behave like built-in classes. For example, suppose that you define a class with a property called Data that contains an array of numeric data.

This statement:

obj.Data(2,3)

Returns the value contained in the second row, third column of the array. If you have an array of objects, use an expression like:

objArray(3).Data(2,3)

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.

Built-In subsref and subsasgn Called in Methods

MATLAB does not call class-defined subsref or subsasgn methods within the overloaded methods. Within class methods, MATLAB always calls the built-in subsref and subsasgn functions. This behavior occurs within the class-defined subsref and subsasgn methods too.

For example, within a class method, this dot reference:

obj.Prop

calls the built-in subsref function. To call the class-defined subsref method, use:

subsref(obj,substruct('.','Prop'))

Whenever a method requires the functionality of the class-defined subsref or subsasgn method, the class must call the overloaded methods as functions. Do not use the operators, '()', '{}', or '.'.

For example, suppose that you define a class to represent polynomial. This class has a subsref method that evaluates the polynomial with the value of the independent variable equal to the subscript. Assume that this statement defines the polynomial with its coefficients:

p = polynom([1 0 -2 -5]);

The MATLAB expression for the resulting polynomial is:

x^3 - 2*x - 5

This subscripted expression returns the value of the polynomial at x = 3:

p(3)
ans =
    16

Suppose that you want to use this feature in another class method. To do so, call the subsref function directly. The evalEqual method accepts two polynom objects and a value at which to evaluate the polynomials:

methods
   function ToF = evalEqual(p1,p2,x)
      % Create arguments for subsref
      subs.type = '()';
      subs.subs = {x};
      % Need to call subsref explicitly 
      y1 = subsref(p1,subs);
      y2 = subsref(p2,subs);
      if y1 == y2
         ToF = true;
      else 
         ToF = false;
      end
   end
end

This behavior enables you to use standard MATLAB indexing to implement specialized behaviors. See Class with Modified Indexing for examples of how to use both built-in and class-modified indexing.

Avoid Overriding Access Attributes

Because subsref is a class method, it has access to private class members. Avoid inadvertently giving access to private methods and properties as you handle various types of reference. Consider this subsref method defined for a class having private properties, x and y:

classdef MyPlot
   properties (Access = private)
      x
      y
   end
   properties
      Maximum
      Minimum
      Average
   end
   methods
      function obj = MyPlot(x,y)
         obj.x = x;
         obj.y = y;
         obj.Maximum = max(y);
         obj.Minimum = min(y);
         obj.Average = mean(y);
      end
      function B = subsref(A,S)
         switch S(1).type
            case '.'
               switch S(1).subs
                  case 'plot'
                     % Reference to A.x and A.y call built-in subsref
                     B = plot(A.x,A.y);
                  otherwise
                     % Enable dot notation for all properties and methods
                     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     2     3     4     5     6     7     8     9    10

The same issue applies to writing a subsasgn method that enables assignment to private or protected properties. Your subsref and subsasgn methods might need to code each specific property and method name explicitly to avoid violating the class design.

Related Topics