Developing Classes — Typical Workflow

Formulating a Class

This example discusses the design and implementation of a simple class. To design a class that represents a bank account, first determine the elements of data and the operations that form your abstraction of a bank account. For example, a bank account has:

  • An account number

  • An account balance

  • A current status (open, closed, etc.)

You need to perform certain operations on a bank account:

  • Deposit money

  • Withdraw money

You might also want the bank account to send a notice if the balance is too low and an attempt is made to withdraw money. When this event occurs, the bank account can broadcast a notice to other entities that are designed to listen for these notices, such as an account manager program. The account manager program can take action in response to the event.

In this class, the status of all bank accounts is determined by an account manager program that looks at the account balance and assigns one of three values:

  • open — Account balance is a positive value

  • overdrawn — Account balance is overdrawn, but by $200 or less.

  • closed — Account balance is overdrawn by more than $200.

MATLAB® classes store data in properties, implement operations with methods, and support notifications with events and listeners. Therefore, the bank account class needs to implement these components, which are discussed in the following sections.

Class Data

The class needs to define these properties to store the account number, account balance, and the account status:

  • AccountNumber — MATLAB assigns a value to this property when you create an instance of the class.

  • AccountBalance — The class operation of depositing and withdrawing money assigns values to this property.

  • AccountStatus — MATLAB sets this property to an initial value when an instance of the class is created. It is then changed by methods from the AccountManager class whenever the value of the AccountBalance falls below 0.

The first two properties contain information that only the class can change, so the SetAccess attribute is set to private (only class methods can set these values).

An external program sets the value of the AccountStatus property. This program needs access to the property, so the property's SetAccess attribute is left as public (any code can access this property value).

Class Operations

There are three operations that the class must be able to perform, so there needs to be three methods:

  • deposit — Update the AccountBalance property when a deposit transaction occurs

  • withdraw — Update the AccountBalance property when a withdrawal transaction occurs

  • BankAccount — Create an initialized instance of the class

Class Events

The account manager program changes the status of bank accounts having negative balances. To implement this action, the BankAccount class triggers an event when a withdrawal results in a negative balance. Therefore, the triggering of the InsufficientsFunds event occurs from within the withdraw method.

To define an event, specify a name within an events block. Trigger the event by a call to the notify handle class method. Because InsufficientsFunds is not a predefined event, you can name it with any string and trigger it with any action.

Implementing the BankAccount Class

It makes sense for there to be only one set of data associated with any instance of a BankAccount class. You would not want independent copies of the object that could have, for example, different values for the account balance. Therefore, the BankAccount class should be implemented as a handle class. All copies of a given handle object refer to the same data.

Example Code

Open both class files in your editor by clicking this link:

Open in editorOpen in editor

Class Definition

classdef BankAccount < handle
   properties (Hidden)
      AccountStatus = 'open'; 
   end
   % The following properties can be set only by class methods
   properties (SetAccess = private)
      AccountNumber
      AccountBalance = 0; 
   end
   % Define an event called InsufficientFunds
   events
      InsufficientFunds 
   end
   methods
      function BA = BankAccount(AccountNumber,InitialBalance)
         BA.AccountNumber = AccountNumber;
         BA.AccountBalance = InitialBalance;
         % Calling a static method requires the class name
         % addAccount registers the InsufficientFunds listener on this instance
         AccountManager.addAccount(BA);
      end
      function deposit(BA,amt)
         BA.AccountBalance = BA.AccountBalance + amt;
         if BA.AccountBalance > 0
            BA.AccountStatus = 'open';
         end
      end
      function withdraw(BA,amt)
         if (strcmp(BA.AccountStatus,'closed')&& BA.AccountBalance < 0)
            disp(['Account ',num2str(BA.AccountNumber),' has been closed.'])
            return
         end
         newbal = BA.AccountBalance - amt;
         BA.AccountBalance = newbal;
         % If a withdrawal results in a negative balance,
         % trigger the InsufficientFunds event using notify
         if newbal < 0
            notify(BA,'InsufficientFunds')
         end
      end % withdraw
   end % methods
end % classdef

Implementing the AccountManager Class

The AccountManager class provides two methods that implement and register a listener for the InsufficientsFunds event, which is defined for all BankAccount objects. The BankAccount class constructor method calls addAccount to register the listener for the instance being created.

Class Definition

classdef AccountManager
   methods (Static)
      function assignStatus(BA)
         if BA.AccountBalance < 0
            if BA.AccountBalance < -200
               BA.AccountStatus = 'closed';
            else
               BA.AccountStatus = 'overdrawn';
            end
         end
      end 
      function addAccount(BA)
      % Call the handle addlistener method 
      % Object BA is a handle class
         addlistener(BA, 'InsufficientFunds', ...
            @(src, evnt)AccountManager.assignStatus(src));
      end
   end
end

Note that the AccountManager class is never instantiated. It serves as a container for the event listener used by all BankAccount objects.

Using the BankAccount Class

The BankAccount class, while overly simple, demonstrates how MATLAB classes behave. For example, create a BankAccount object with a serial number and an initial deposit of $500:

BA = BankAccount(1234567,500);
BA.AccountNumber
ans =
1234567
BA.AccountBalance
ans =
   500
BA.AccountStatus
ans =
open

Now suppose you make a withdrawal of $600, which results in a negative account balance:

BA.withdraw(600)
BA.AccountBalance
ans =
  -100
BA.AccountStatus
ans =
overdrawn

When the $600 withdrawal occurred, the InsufficientsFunds event was triggered. Because the AccountBalance is not less than –$200, the AccountStatus was set to overdrawn:

BA.withdraw(200)
BA.AccountBalance
ans =
  -300
BA.AccountStatus
ans =
closed

Now the AccountStatus has been set to closed by the listener and further attempts to make withdrawals are blocked:

BA.withdraw(100)
Account 1234567 has been closed

If the AccountBalance is returned to a positive value by a deposit, then the AccountStatus is returned to open and withdrawals are allowed again:

BA.deposit(700)
BA.AccountStatus
ans =
open
BA.withdraw(100)
BA.AccountBalance
ans =
  300
Was this topic helpful?