Этот пример обсуждает, как приблизиться к разработке и реализации класса. Цель этого класса состоит в том, чтобы представлять знакомую концепцию (банковский счет). Однако можно применить тот же подход к большинству проектов класса.
Чтобы разработать класс, который представляет банковский счет, сначала определите элементы данных и операции, которые формируют вашу абстракцию банковского счета. Например, банковский счет имеет:
Номер счета
Остаток на счете
Состояние (открытый, закрытый, и т.д.)
Необходимо выполнить определенные операции на банковском счете:
Создайте объект для каждого банковского счета
Внесите деньги
Заберите деньги
Сгенерируйте оператор
Сохраните и загрузите объект 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 -------------------------