|On this page…|
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:
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.
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).
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
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.
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.
Open both class files in your editor by clicking this link:
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
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.
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.
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