Main Content

Subclasses of Built-In Types with Properties

Specialized Numeric Types with Additional Data Storage

Subclass built-in numeric types to create customized data types that inherit the functionality of the built-in type. Add or modify functionality to that provided by the superclass by implementing class methods.

Providing additional data storage in the subclass by defining properties can be a useful extension to the built-in data class. However, the addition of properties to the subclass requires the subclass to define methods to implement standard array behaviors.

For more information, see Subclasses of MATLAB Built-In Types.

Subclasses with Properties

When a subclass of a built-in class defines properties, default indexing and concatenation do not work. The default subsref, subsasgn, horzcat, and vertcat functions cannot work with unknown property types and values. Therefore, the subclass must define these behaviors by implementing these methods.

This sample implementation of the ExtendDouble class derives from the double class and defines a single property. The ExtendDouble class definition demonstrates how to implement indexing and concatenation for subclasses of built-in classes

Property Added

The ExtendDouble class defines the DataString property to contain text that describes the data. The superclass part of the class contains the numeric data.

Methods Implemented

The following methods modify the behavior of the ExtendDouble class:

  • 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 built-in 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.

  • dispExtendDouble implements a disp method to provide a custom display for the object.

Class Definition Code

The ExtendDouble class extends double and implements methods to support subscripted indexing and concatenation.

classdef ExtendDouble < double
   
   properties
      DataString
   end
   
   methods
      function obj = ExtendDouble(data,str)
         if nargin == 0
            data = 0;
            str = '';
         elseif nargin == 1
            str = '';
         end
         obj = obj@double(data);
         obj.DataString = str;
      end
      
      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')
               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 = 

One to ten
     1     2     3     4     5     6     7     8     9    10

Inherited Methods

The ExtendDouble class inherits methods from the class double. To see a list of all public methods defined by the double class, use the methods function:

methods(double.empty)

The sum function continues to operate on the superclass part of the object:

sum(ed)
ans =
    55

The sort function works on the superclass part of the object:

sort(ed(10:-1:1))
ans = 

     1     2     3     4     5     6     7     8     9    10

Arithmetic operators work on the superclass part of the object:

ed.^2
ans =

     1     4     9    16    25    36    49    64    81   100

Subscripted Indexing

Because the ExtendDouble class defines a property, the class must implement its own subsref and subsasgn methods.

This class implements the following subscripted indexing expressions for reference and assignment.

  • 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.

  • obj(ind) — access the numeric data (same as obj.Data(ind)). Reference returns values of type ExtendDouble.

The class subsref method enables you to use ExtendDouble objects like numeric arrays to reference the numeric data:

ed = ExtendDouble(1:10,'One to ten');
ed(10:-1:1)
ans = 

One to ten
    10     9     8     7     6     5     4     3     2     1

Access the numeric data of the ExtendDouble using property-style indexing with the arbitrarily chosen name Data:

ed.Data(10:-1:1)
ans = 

One to ten
    10     9     8     7     6     5     4     3     2     1

Access the DataString property:

ed.DataString
ans =

One to ten

Subscripted assignment implements similar syntax in the class subsasgn method.

ed = ExtendDouble(1:10,'One to ten');
ed(11:13) = [11,12,13];
ed.DataString = 'one to thirteen';
ed
ed = 

One to thirteen'
     1     2     3     4     5     6     7     8     9    10    11    12    13

The ExtendDouble inherits converter methods from the double class. For example, MATLAB® calls the char method to perform this assignment statement.

ed(11:13) = ['a','b','c']
ed = 

one to thirteen
     1     2     3     4     5     6     7     8     9    10    97    98    99

Class of Value Returned by Indexing Expression

The ExtendDouble implements two forms of indexed reference in the subsref method:

  • obj.Data and obj.Data(ind) — Return values of class double

  • obj(ind) — Return values of class ExtendDouble

For example, compare the values returned by these expressions.

ed = ExtendDouble(1:10,'One to ten');
a = ed(1)
a = 

One to ten
     1
b = ed.Data(1)
b =

     1
whos
  Name      Size            Bytes  Class           Attributes

  a         1x1               132  ExtendDouble              
  b         1x1                 8  double                    
  ed        1x10              204  ExtendDouble              

The increased flexibility of the implementation of indexed reference in the ExtendDouble class.

Concatenation of ExtendDouble Objects

Create these two objects:

ed1 = ExtendDouble([1:10],'One to ten');
ed2 = ExtendDouble([10:-1:1],'Ten to one');

Concatenate these objects along the horizontal dimension:

hcat = [ed1,ed2]
hcat = 

    'One to ten'    'Ten to one'

  Columns 1 through 13

     1     2     3     4     5     6     7     8     9    10    10     9     8

  Columns 14 through 20

     7     6     5     4     3     2     1
whos
  Name      Size            Bytes  Class           Attributes

  ed1       1x10              204  ExtendDouble              
  ed2       1x10              204  ExtendDouble              
  hcat      1x20              528  ExtendDouble 

Vertical concatenation works in a similar way:

vcat = [ed1;ed2]
vcat = 

    'One to ten'    'Ten to one'

     1     2     3     4     5     6     7     8     9    10
    10     9     8     7     6     5     4     3     2     1

Both horzcat and vertcat return a new object of the same class as the subclass.

Related Topics