Этот пример обсуждает, как приблизиться к разработке и реализации класса. Цель этого класса состоит в том, чтобы представлять знакомую концепцию (банковский счет). Однако можно применить тот же подход к большинству проектов класса.
Чтобы спроектировать класс, который представляет банковский счет, сначала определите элементы данных и операции, которые формируют вашу абстракцию банковского счета. Например, банковский счет имеет:
Номер счета
Остаток на счете
Состояние (открытый, закрытый, и т.д.)
Необходимо выполнить определенные операции на банковском счете:
Создайте объект для каждого банковского счета
Внесите деньги
Заберите деньги
Сгенерируйте оператор
Сохраните и загрузите BankAccount объект
Если баланс является слишком низким, и вы пытаетесь забрать деньги, банковский счет широковещательно передает уведомление. Когда это событие имеет место, банковский счет широковещательно передает уведомление другим сущностям, которые спроектированы, чтобы прислушаться к этим уведомлениям. В этом примере упрощенная версия программы менеджера учетных записей выполняет эту задачу.
В этом примере программа менеджера учетных записей определяет состояние всех банковских счетов. Эта программа контролирует остаток на счете и присваивает одно из трех значений:
open — Остаток на счете является положительным значением
overdrawn — Остаток на счете превышен ограничения, но на 200$ или меньше.
closed — Остаток на счете превышен ограничения больше чем на 200$.
Эти функции задают требования BankAccount и AccountManager классы. Включайте только, какая функциональность требуется, чтобы достигать ваших определенных целей. Поддержите специальные типы учетных записей путем разделения на подклассы BankAccount и добавление более определенных опций к подклассам. Расширьте AccountManager как требуется поддерживать новые типы учетных записей.
Классы хранят данные в свойствах, реализуют операции с методами и поддерживают уведомления с событиями и прослушивателями. Вот то, как BankAccount и AccountManager классы задают эти компоненты.
Класс задает эти свойства сохранить номер счета, остаток на счете и состояние счета:
AccountNumber — Свойство сохранить номер, идентифицирующий определенную учетную запись. MATLAB® присваивает значение этому свойству, когда вы создаете экземпляр класса. Только BankAccount методы класса могут установить это свойство. SetAccess атрибутом является private.
AccountBalance — Свойство сохранить текущий баланс учетной записи. Операция класса внесения и удаления денег присваивает значения этому свойству. Только BankAccount методы класса могут установить это свойство. SetAccess атрибутом является private.
AccountStatus — BankAccount класс задает значение по умолчанию для этого свойства. AccountManager методы класса изменяют это значение каждый раз, когда значение AccountBalance падения ниже 0. Access атрибут задает это только AccountManager и BankAccount классы имеют доступ к этому свойству.
AccountListener — Устройство хранения данных для InsufficentFunds event.listener. Сохранение BankAccount объект не сохраняет это свойство, потому что необходимо воссоздать прослушиватель при загрузке объекта.
Эти методы реализуют операции, заданные в формулировке класса:
BankAccount — Принимает, что номер счета и начальный баланс создают объект, который представляет учетную запись.
deposit — Обновляет AccountBalance свойство, когда транзакция депозита происходит
withdraw — Обновляет AccountBalance свойство, когда транзакция вывода происходит
getStatement — Информация об отображениях об учетной записи
loadobj — Воссоздает прослушиватель менеджера учетных записей, когда вы загружаете объект из MAT-файла.
Программа менеджера учетных записей изменяет состояние банковских счетов, которые имеют отрицательные балансы. Реализовывать это действие, BankAccount класс инициировал событие, когда вывод приводит к отрицательному балансу. Поэтому инициирование InsufficientsFunds событие имеет место из withdraw метод.
Чтобы задать событие, задайте имя в events блок. Инициируйте событие вызовом notify метод класса Handle. Поскольку 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 | Обновления Для получения дополнительной информации о прослушивателях смотрите Синтаксис Событий и Прослушивателей. |
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 -------------------------