Этот пример обсуждает, как приблизиться к разработке и реализации класса. Цель этого класса состоит в том, чтобы представлять знакомую концепцию (банковский счет). Однако можно применить тот же подход к большинству проектов класса.
Чтобы разработать класс, который представляет банковский счет, сначала определите элементы данных и операции, которые формируют вашу абстракцию банковского счета. Например, банковский счет имеет:
Номер счета
Баланс счета
Состояние (открытый, закрытый, и т.д.)
Необходимо выполнить определенные операции на банковском счете:
Создайте объект для каждого банковского счета
Внесите деньги
Заберите деньги
Сгенерируйте оператор
Сохраните и загрузите объект BankAccount
Если баланс является слишком низким, и вы пытаетесь забрать деньги, банковский счет широковещательно передает уведомление. Когда это событие имеет место, банковский счет широковещательно передает уведомление другим сущностям, которые разработаны, чтобы прислушаться к этим уведомлениям. В этом примере упрощенная версия программы менеджера учетных записей выполняет эту задачу.
В этом примере программа менеджера учетных записей определяет состояние всех банковских счетов. Эта программа контролирует баланс счета и присваивает одно из трех значений:
открытый Баланс счета является положительным значением
overdrawn — Баланс счета превышен ограничения, но на 200$ или меньше.
closed — Баланс счета превышен ограничения больше чем на 200$.
Эти функции задают требования классов AccountManager и BankAccount. Включайте только, какая функциональность требуется, чтобы достигать ваших определенных целей. Поддержите специальные типы учетных записей путем разделения на подклассы BankAccount и добавления более определенных опций к подклассам. Расширьте AccountManager как требуется, чтобы поддержать новые типы учетных записей.
Классы хранят данные в свойствах, реализуют операции с методами и поддерживают уведомления с событиями и прослушивателями. Вот то, как BankAccount и классы AccountManager задают эти компоненты.
Класс задает эти свойства сохранить номер счета, баланс счета и состояние учетной записи:
AccountNumber — Свойство сохранить номер, идентифицирующий определенную учетную запись. MATLAB® присваивает значение этому свойству, когда вы создаете экземпляр класса. Только методы класса BankAccount могут установить это свойство. Атрибутом SetAccess является private.
AccountBalance — Свойство сохранить текущий баланс учетной записи. Операция класса внесения и удаления денег присваивает значения этому свойству. Только методы класса BankAccount могут установить это свойство. Атрибутом SetAccess является private.
AccountStatus — Класс BankAccount задает значение по умолчанию для этого свойства. Методы класса AccountManager изменяют это значение каждый раз, когда значение AccountBalance падает ниже 0. Атрибут Access указывает, что только AccountManager и классы BankAccount имеют доступ к этому свойству.
AccountListener — Устройство хранения данных для прослушивателя события InsufficentFunds. Сохранение объекта BankAccount не сохраняет это свойство, потому что необходимо воссоздать прослушиватель при загрузке объекта.
Эти методы реализуют операции, заданные в формулировке класса:
BankAccount — Принимает, что номер счета и начальный баланс создают объект, который представляет учетную запись.
deposit — Обновляет свойство AccountBalance, когда транзакция депозита происходит
withdraw — Обновляет свойство AccountBalance, когда транзакция вывода происходит
getStatement — Информация об отображениях об учетной записи
loadobj Воссоздает прослушиватель менеджера учетных записей, когда вы загружаете объект из MAT-файла.
Программа менеджера учетных записей изменяет состояние банковских счетов, которые имеют отрицательные балансы. Чтобы реализовать это действие, класс BankAccount инициировал событие, когда вывод приводит к отрицательному балансу. Поэтому инициирование события InsufficientsFunds происходит из метода withdraw.
Чтобы задать событие, задайте имя в блоке events. Инициируйте событие вызовом метода класса Handle notify. Поскольку InsufficientsFunds не является предопределенным событием, можно назвать его с любым вектором char и инициировать его с любым действием.
Реализация класса BankAccountВажно гарантировать, что существует только один набор данных, сопоставленных с любым объектом класса BankAccount. Вы не хотели бы независимые копии объекта, который мог иметь, например, различные значения для баланса счета. Поэтому реализуйте класс BankAccount как класс Handle. Все копии данного объекта указателя относятся к тем же данным.
Резюме класса BankAccount| Класс BankAccount | Обсуждение |
|---|---|
classdef BankAccount < handle
| Класс Handle, потому что должна быть только одна копия любого экземпляра |
properties (Access = ?AccountManager) AccountStatus = 'open' end |
|
properties (SetAccess = private) AccountNumber AccountBalance end properties (Transient) AccountListener end | Доступ к свойству Свойства
Смотрите задают Атрибуты свойств. |
events InsufficientFunds end | Класс задает событие под названием Для получения информации о событиях и прослушивателях, смотрите События. |
methods
| Блок обычных методов. См. Методы и Функции для синтаксиса. |
function BA = BankAccount(AccountNumber,InitialBalance) BA.AccountNumber = AccountNumber; BA.AccountBalance = InitialBalance; BA.AccountListener = 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 newbal < 0 notify(BA,'InsufficientFunds') end end | Свойство Updates Для получения дополнительной информации о прослушивателях смотрите Синтаксис Событий и Прослушивателей. |
function getStatement(BA) disp('-------------------------') disp(['Account: ',num2str(BA.AccountNumber)]) ab = sprintf('%0.2f',BA.AccountBalance); disp(['CurrentBalance: ',ab]) disp(['Account Status: ',BA.AccountStatus]) disp('-------------------------') end | Отобразите выбранную информацию об учетной записи. |
end methods (Static) | Конец обычного блока методов. Начало блока статических методов. Смотрите Статические методы |
function obj = loadobj(s) if isstruct(s) accNum = s.AccountNumber; initBal = s.AccountBalance; obj = BankAccount(accNum,initBal); else obj.AccountListener = AccountManager.addAccount(s); end end | Метод
Для получения дополнительной информации о сохранении и загружаемых объектах, смотрите, Сохраняют и Процесс Загрузки для Объектов |
end end | Конец блока статических методов Конец |
Формулировка класса AccountManagerЦель класса AccountManager состоит в том, чтобы предоставить услуги учетным записям. Для класса BankAccount класс AccountManager прислушивается к выводу, который заставляет баланс, заскакивают в отрицательную область значений. Когда объект BankAccount инициировал событие InsufficientsFunds, AccountManager сбрасывает состояние учетной записи.
Класс AccountManager не хранит данных, таким образом, ему не нужны свойства. Объектно-ориентированная память BankAccount указатель объекта прослушивателя.
AccountManager выполняет две операции:
Присвойте состояние каждой учетной записи в результате вывода
Добавляет учетная запись к системе путем контроля баланса счетов.
Класс AccountManager реализует два метода:
assignStatus — Метод, который присваивает состояние объекту BankAccount. Служит обратным вызовом прослушивателя.
addAccount — Метод, который создает прослушиватель InsufficientFunds.
Реализация класса AccountManagerКласс AccountManager реализует оба метода как статичные, потому что нет никакой потребности в объекте AccountManager. Эти методы работают с объектами BankAccount.
AccountManager не предназначается, чтобы быть инстанцированным. Разделение функциональности класса AccountManager от класса BankAccount обеспечивает большую гибкость и расширяемость. Например, выполнение так позволяет:
Расширьте класс AccountManager, чтобы поддержать другие типы учетных записей при хранении отдельных классов учетной записи простыми и специализированными.
Измените критерии состояния учетной записи, не влияя на совместимость сохраненных и загруженных объектов BankAccount.
Разработайте суперкласс Account, который факторизует то, что характерно для всех учетных записей, не требуя, чтобы каждый подкласс реализовал функциональность ведения счетов
Резюме класса AccountManager| Класс AccountManager | Обсуждение |
|---|---|
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 lh = addAccount(BA) lh = addlistener(BA, 'InsufficientFunds', ... @(src, ~)AccountManager.assignStatus(src)); end |
|
end end | Операторы |
Класс BankAccount, в то время как чрезмерно простой, демонстрирует, как классы MATLAB ведут себя. Например, создайте объект BankAccount с номером счета и начальным депозитом 500$:
BA = BankAccount(1234567,500)
BA =
BankAccount with properties:
AccountNumber: 1234567
AccountBalance: 500
AccountListener: [1x1 event.listener]Используйте метод getStatement, чтобы проверить состояние:
getStatement(BA)
------------------------- Account: 1234567 CurrentBalance: 500.00 Account Status: open -------------------------
Сделайте вывод в 600$, который приводит к отрицательному балансу счета:
withdraw(BA,600) getStatement(BA)
------------------------- Account: 1234567 CurrentBalance: -100.00 Account Status: overdrawn -------------------------
Вывод за 600$ инициировал событие InsufficientsFunds. Текущие критерии, заданные классом AccountManager, приводят к состоянию overdrawn.
Сделайте другой вывод в 200$:
withdraw(BA,200) getStatement(BA)
------------------------- Account: 1234567 CurrentBalance: -300.00 Account Status: closed -------------------------
Теперь AccountStatus был установлен в closed прослушивателем, и дальнейшие попытки сделать вывод блокируются, не инициировав событие:
withdraw(BA,100)
Account 1234567 has been closed.
Если AccountBalance возвращен в положительное значение депозитом, то AccountStatus возвращен, чтобы открыться, и вывод позволен снова:
deposit(BA,700) getStatement(BA)
------------------------- Account: 1234567 CurrentBalance: 400.00 Account Status: open -------------------------