В этом примере обсуждается, как подойти к проекту и реализации класса. Цель этого класса состоит в том, чтобы представлять привычную концепцию (банковский счет). Однако к большинству проектов классов можно применить тот же подход.
Чтобы спроектировать класс, который представляет банковский счет, сначала определите элементы данных и операции, которые формируют вашу абстракцию банковского счета. Для примера банковский счет имеет:
Номер счета
Остаток на счете
Статус (открытый, закрытый и т.д.)
Необходимо выполнить определенные операции на банковском счете:
Создание объекта для каждого банковского счета
Депозитные деньги
Снять деньги
Сгенерируйте оператор
Сохраните и загрузите BankAccount
объект
Если остаток слишком мал, и вы пытаетесь вывести деньги, банковский счет транслирует уведомление. Когда это событие происходит, банковский счет передает уведомление другим сущностям, которые предназначены для прослушивания этих уведомлений. В этом примере упрощенная версия программы менеджера счетов выполняет эту задачу.
В этом примере программа менеджера счетов определяет статус всех банковских счетов. Эта программа контролирует сальдо счета и присваивает одно из трех значений:
open
- Сальдо счета положительное
overdrawn
- Остаток на счете перерисован, но на $200 или менее.
closed
- Остаток на счете перерисован более чем на $200.
Эти функции определяют требования BankAccount
и AccountManager
классы. Включать только те функциональные возможности, которые необходимы для достижения ваших конкретных целей. Поддержка специальных типов счетов путем подклассирования BankAccount
и добавление более специфических функций к подклассам. Расширение AccountManager
по мере необходимости для поддержки новых типов счетов.
Классы хранят данные в свойствах, реализуют операции с методами и поддерживают уведомления с событиями и прослушивателями. Вот как BankAccount
и AccountManager
классы определяют эти компоненты.
Класс определяет эти свойства для хранения номера счета, сальдо счета и статуса счета:
AccountNumber
- Свойство для хранения номера, идентифицирующего конкретную учетную запись. MATLAB® присваивает значение этому свойству при создании образца класса. Только BankAccount
методы класса могут задать это свойство. The SetAccess
атрибут private
.
AccountBalance
- Свойство для хранения текущего остатка на счете. Классовая операция внесения и вывода денег присваивает стоимость этой собственности. Только BankAccount
методы класса могут задать это свойство. The SetAccess
атрибут private
.
AccountStatus
- The BankAccount
класс задает значение по умолчанию для этого свойства. The AccountManager
методы классов изменяют это значение всякий раз, когда значение AccountBalance
падает ниже 0
. The Access
атрибут указывает, что только AccountManager
и BankAccount
классы имеют доступ к этому свойству.
AccountListener
- Хранение для InsufficentFunds
прослушиватель событий. Сохранение 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
сбрасывает состояние учетной записи.
The AccountManager
класс не хранит никаких данных, поэтому ему не нужны свойства. The BankAccount
объект хранит указатель на объект прослушивателя.
The AccountManager
выполняет две операции:
Присвоение статуса каждому счету в результате вывода средств
Добавляет счет в систему путем контроля сальдо счетов.
The AccountManager
класс реализует два метода:
assignStatus
- Метод, который присваивает статус BankAccount
объект. Служит в качестве обратного коллбэка прослушивателя.
addAccount
- Метод, который создает InsufficientFunds
прослушиватель.
AccountManager
КлассThe AccountManager
класс реализует оба метода как статические, потому что нет необходимости в AccountManager
объект. Эти методы работают с BankAccount
объекты.
The 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 | The The |
function lh = addAccount(BA) lh = addlistener(BA, 'InsufficientFunds', ... @(src, ~)AccountManager.assignStatus(src)); end |
|
end end |
|
The 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 -------------------------