Department of Engineering

IT Services

Object-oriented programming with Matlab

Why?

Object-oriented programming is a popular mode of working and is supported by Java, C++ and many other modern languages. It's claimed that it makes code easier to read and maintain. Furthermore, an object-oriented approach is in many cases more natural and appeals more to human cognition than other methodologies.

What?

In object-oriented programming you invent new types (called classes) designed to suit your task. These types are more sophisticated than simple variables or arrays - they can have functions (called methods) too. Just as you can create variables of a standard type (like a double in fortran) so in object-oriented programming you can create an object of a certain class, and you can redefine what '+' etc does when applied to these new objects.

Some important object-oriented (O-O) concepts are

  • Objects and messages - in a procedural language like Fortran 77 data is passed around from routine to routine and there's no special relationship between the data and the routines that operate on it. In an O-O language, messages are sent to objects and the object is trusted to do what it's told, operating on the data held within it.
  • Encapsulation - it's considered a good idea to keep together data and the routines which operate on that data, and to tightly control which routines are allowed to access the data (information hiding)..
  • Code reuse - if you want to create a object that's like an existing object, you can use the existing object as a base for the new object. This is known as Inheritance.

The aim is to create objects that have tightly related parts but few connections with anything else. As an analogy consider a lightbulb: as long as it has a standard interface other components don't have to worry about how it's designed internally, and the lightbulb can easily be replaced by one that's internally very different.

How?

CUED's 2nd year C++ course mentions classes. The principles of Matlab's classes are similar. See the Object-Orientated Programming User Guide details. The classdef keyword is used to define a new class. Classes can have data (properties in Matlab) and functions (or Methods). Let's create a class to deal with colours. If you put the following into a file called colour.m

classdef colour
     properties
        red
        green
        blue
     end
end

you can then type c=colour to create an object called c of that class, with 3 fields. It would be useful to be able to set the colour components when we create the object. To do that we need to write constructors - special methods that are used when creating objects. Here's an updated colour.m file with a constructor.

classdef colour
     properties
        red
        green
        blue
     end
     methods
       function c = colour(varargin)
       %COLOUR Colour class constructor
       switch nargin
       case 0
          % No argument - set default colour
          c.red = 0;
          c.green=0;
          c.blue=0;
          c = class(c,'colour');
       case 1
          % 1 argument - if it's a colour object, copy to a new object
          if (isa(varargin{1},'colour'))
            c = varargin{1};
          else
            % assume the arg is a number and set all the components
            c.red = varargin{1};
            c.green=varargin{1};
            c.blue=varargin{1};
            c = class(c,'colour');  
          end 
       case 3
          % 3 arguments. Assume that they're the red, green and blue values
          c.red =varargin{1} ;
          c.green=varargin{2};
          c.blue=varargin{3};
          c = class(c,'colour');
       otherwise
           error('Wrong number of input arguments')
       end
     end
end

Another important method is display which is called when the object is output as text. It produces output that's in the same form as standard MATLAB output: the variable name is displayed followed by an equal sign, then a blank line, then a new line with the values.

function display(c)
% COLOUR/DISPLAY
disp(' ');
disp([inputname(1),' = '])
disp(' ');
disp(['   ' 'Red=' num2str(c.red) ', Green=' num2str(c.green) ', Blue=' num2str(c.blue) ])
disp(' ');

When that's added as a method, you can test by creating objects in various ways -

   colour1=colour(1,2,3)
   colour2=colour(colour1)
   colour3=colour

(note that these lines don't end with semicolons, so the display method is called) and then try

   colour4=colour(6,5)

which should print an error message because the number of arguments (nargin in the code) is unsupported by the code.

Other Class methods

Adding 2 of these colour objects together produces an error message, but you can make the '+' operator work with these new objects by creating a plus method. The following one produces a colour whose components are the average of the constituents' components. The code is written so that it will still work even if one of the operands is a number - the c1 = colour(c1) line has no effect if c1 is already a colour, but will convert c1 to a colour if it's a number.

function r = plus(c1,c2)
% COLOUR/PLUS  Implement '+' for colours.
c1 = colour(c1);
c2 = colour(c2);
r= colour ( (c1.red+c2.red)/2,(c1.green+c2.green)/2,(c1.blue+c2.blue)/2);

With this code installed, typing

  colour5=colour1+colour3

will produce a blend. If you want to be able to brighten a colour by a given factor, you could add a brighten method

function r = brighten(c,f)
% COLOUR/BRIGHTEN 
r= colour (c.red*f, c.green*f, c.blue*f);

and once you've installed it you can call colour5=brighten(colour5,3) to brighten colour5 by a factor of 3.

To find out which methods exist for a class, use the methods command - e.g. methods('colour').

When?

Not all tasks are suited to an object-oriented approach, but in a big project it's useful to be able to hide data, and keep data close to related routines. It also helps with name-clash issues. As in C++, it's possible to have 2 or more functions with the same name as long as they have different types of objects as arguments. The brighten function created above is invoked if the first argument is a colour object, otherwise the standard brighten function is called.

Handle Classes

Create a file called valueInt.m containing the following code

classdef valueInt
   properties
      myValue=0;
   end
   methods
      function v =  valueInt(val)
         v.myValue=val;
      end
   end
end 

This creates a class with one piece of data and one contructor to set that data to an initial value. Type

vi1=valueInt(7);
vi2=vi1;
vi2.myValue=999;
vi1.myValue

The answer 7 will be printed out, which should come as no surprise - 2 objects are created. Now create a file called handleInt.m containing the following code

classdef handleInt < handle
   properties
      myValue=0;
   end   
   methods
      function v =  handleInt(val)
         v.myValue=val;
      end
   end
end 

This differs from the previous code only in its first line. handleInt is "derived from" the handle class and thus inherits the handle class's characteristics. Run the following -

hi1=handleInt(7);
hi2=hi1;
hi2.myValue=999;
hi1.myValue

The output will be 999 because hi2 is an alias for hi1 - there's only one underlying object.

See Also