This note attempts to provide a brief introduction to the concepts of instantiation, objects, and classes in Object-Oriented Programming (OOP) paradigm via MATLAB.

Objects and classes

So far in the notes, we have seen the evolution of programming from simple variable definitions and tasks on the MATLAB command line to writing scripts and functions, while passing scalar or compound variables (lists, arrays, dictionaries, …) to functions. It took a few decades since the development of the first high-level programming language, Fortran, for the computer scientists to realize that one could take the programming paradigms to an even higher level of combining functions and their input/output data into a single entity called object. Let have another look at the diagram we saw before about the evolution of computer programming paradigms,

But there is more to Object-Oriented Programming (OOP) than the simple concept of objects. As soon as we are talking about objects, one has to also specify the class to which the object belongs. For example, all dogs in the world belong to the generic class of dog. Similarly, in computer programming, including MATLAB, one has to first define a class from which objects can be instantiated whenever needed in the program.

The concept of MATLAB class, as in almost any other programming language, relates to packing a set of variables together with a set of functions operating on those variables. The goal of writing classes is to achieve more modular code by grouping data and functions into manageable units. One thing to keep in mind for scientific computing is that classes, and more generally, Object Oriented Programming (OOP), are not necessary, and could be a hindrance to efficient computing if used naively. Nevertheless, classes lead to either more elegant solutions to the programming problem or a code that is easier to extend and maintain large scale projects. In the non-mathematical programming world where there are no mathematical concepts and associated algorithms to help structure the programming problem, software development can be very challenging. In those cases, Classes greatly improve the understanding of the problem and simplify the modeling of data. As a consequence, almost all large-scale software systems being developed in the world today are heavily based on classes (but certainly not all scientific projects!).

One of the greatest advantages that the OOP brings to programming is code-reusability; Once we define a blueprint class, all objects belonging to that class can be easily instantiated from it and personalized. Therefore, the first step in OOP is to define the class of an object that we want to create and use.

Defining classes in MATLAB

Programming with classes is offered by most modern programming languages, including MATLAB. MATLAB uses the concept of classes in almost every bit of it. However, most MATLAB users don’t even notice the heavy dependence of MATLAB on classes under the hood, until they learn what a class is, just as we have made progress in this class so far, without knowing about classes.

Despite having a clean syntax, defining a valid class in MATLAB is rather tricky. First you have to make sure that your MATLAB class is all in a single MATLAB M-file that has the same name as the class-name. For example the following code will define a class named Dog, which does not have any properties (attributes) or methods,

classdef Dog
end

However, for this code snippet to be a valid MATLAB code, it must be saved in MATLAB M-file with the name Dog.m. In addition, there are strict rules with regards to where this file resides on your computer. To use a class, the class definition must be on the MATLAB’s path. There are two types of folders that can contain class definition files,

  • Path folders – The folder is on the MATLAB path and the folder name does not begin with an @ character. Use this type of folder when you want multiple classes in one folder. However, the entire class definition must be contained in one .m file.

  • Class folders – The folder name begins with an @ character followed by the class name. The folder is not on the MATLAB path, but its parent folder is on the path. Use this type of folder when you want to use multiple files for one class definition. See MATLAB’s path() function for information about using the MATLAB path.

The above code creates a class Dog that does not have any properties or attributes (variables that define different aspects of the object) or methods or functions (components of objects that define the tasks the object can do with or without the use of the object’s attributes). The MATLAB keyword classdef declares the beginning of a class definition, and the end keyword marks the end of the class definition.

Once the class is created, you could instantiate objects from the blueprint class,

>> my_dog = Dog()
my_dog = 
  Dog with no properties.

where, the empty parentheses is added in recognition of the fact that Dog is a class, and not an attribute (variable), for example.

You can confirm whether you have indeed instantiated an object from the class Dog via class() intrinsic function in MATLAB,

>> class(my_dog)
ans =
    'Dog'

#% class attributes vs. instance attributes

The class Dog defined above has no use as it does not contain any attributes or methods. In practice, a dog has color, race, age, and so many other attributes. Besides, it can eat, run, sleep, bark, and so on. Therefore,

classdef Dog
    properties
        age;
        name = 'unnamed';
        race = 'unknown';
        color = 'unknown';
    end
end

Now, note that not all the attributes defined this way should be preassigned a default value. Once an object is instantiated from this class,

>> my_dog = Dog
my_dog = 
  Dog with properties:

      age: []
     name: 'unnamed'
     race: 'unknown'
    color: 'unknown'

one could change the default values of the properties to anything else. For example,

my_dog = Dog();
disp( [my_dog.name,' is a ',my_dog.color,'-color ',my_dog.race,'-race dog of age ',num2str(my_dog.age),'.'] )
unnamed is a unknown-color unknown-race dog of age .

can be modified to,

my_dog.age = 3;
my_dog.name = 'Coco';
my_dog.race = 'Terrier';
my_dog.color = 'brown';
disp( [my_dog.name,' is a ',my_dog.color,'-color ',my_dog.race,'-race dog of age ',num2str(my_dog.age),'.'] )
Coco is a brown-color Terrier-race dog of age 3.

Object constructor

While the above approach to class attribute definition and value assignment works fine, it is verbose and rather tedious. Instead, there is a better way of initializing an instance of a class by defining an object constructor method within the class definition. Amethod with the same name as the class-name can be defined in every class and used for performing tasks that are supposed to be done once (and only once) at the time of object instantiation. This includes the assignment of user-provided values to the attributes or default values in case no value is provided by the user.

classdef Dog
    properties
        age;
        name;
        race;
        color;
    end
    methods (Access = public)
        % This is the class constructor
        function Self = Dog(age,name,race,color)
            % instance attributes
            Self.age = age;
            Self.name = name;
            Self.race = race;
            Self.color = color;
        end
    end
end
my_dog = Dog(3,'Coco','Terrier','brown')
my_dog = 
  Dog with properties:

      age: 3
     name: 'Coco'
     race: 'Terrier'
    color: 'brown'

In OOP terminology, this intrinsic class method is called the object contructor method. In many object-oriented programming languages, by convention, the first input argument to the constructor method is always the object itself, that is going to be instantiated, and is frequently named self. However, since it is an output argument, in MATLAB, it is listed as the output of the constructor method and not among the input arguments. Also, the object’s name (here, Self) is arbitrary and can be set to anything, for example, DogObj standing for object,

classdef Dog
    properties
        age;
        name;
        race;
        color;
    end
    methods (Access = public)
        % This is the class constructor
        function DogObj = Dog(age,name,race,color)
            % instance attributes
            DogObj.age = age;
            DogObj.name = name;
            DogObj.race = race;
            DogObj.color = color;
        end
    end
end
my_dog = Dog(3,'Coco','Terrier','brown')
my_dog = 
  Dog with properties:

      age: 3
     name: 'Coco'
     race: 'Terrier'
    color: 'brown'

I highly recommend you to stick to the common-practice in object-naming or choose a self-explanatory name. Also, note that the constructor is called automatically at the time of object instantiation.

As a result, the best practice is to initialize attributes that are common to all instances of a class outside the constructor and keep instance-specific attributes initialization within the class constructor,

classdef Dog

    properties

        % class attributes
        species = 'mammal';

        % instance attributes
        age;
        name;
        race;
        color;

    end

    methods (Access = public)

        % This is the class constructor
        function DogObj = Dog(age,name,race,color)
            % instance attributes
            DogObj.age = age;
            DogObj.name = name;
            DogObj.race = race;
            DogObj.color = color;
        end

    end

end
>> my_dog = Dog(3,'Coco','Terrier','brown')
my_dog = 
  Dog with properties:

    species: 'mammal'
        age: 3
       name: 'Coco'
       race: 'Terrier'
      color: 'brown'

Summary

Class attributes are the attributes that apply to all instances of the class, and so by convention, are defined outside the object-constructor method of the class.

Instance attributes are the attributes that are unique to each instance of the class and are, therefore, by convention (not a strict language requirement), defined only inside the object-constructor method of the class.