ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 11.12.2025

Просмотров: 3277

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Пример управления доступом

Приведенная далее демонстрационная программа DoubleBankAccount указывает потенциальные изъяны программы BankAccount .

//

DoubleBankAccount

- с о з д а н и е

б а н к о в с к о г о

с ч е т а

с

/ /

и с п о л ь з о в а н и е м п е р е м е н н о й т и п а double д л я

х р а н е н и я

 

баланса

с ч е т а ( о н а

о б ъ я в л е н а

к а к private ,

ч т о б ы

с к р ы т ь

//

баланс

от в н е ш н е г о

м и р а )

 

 

 

using System;

namespace DoubleBankAccount

{

{

public class Program

 

 

public static v o i d Main(string[]

args)

{

 

 

/ / О т к р ы т и е б а н к о в с к о г о с ч е т а

 

C o n s o l e . W r i t e L i n e ( "Создани е

о б ъ е к т а " +

" б а н к о в с к о г о с ч е т а " ) ;

BankAccount ba = n e w B a n k A c c o u n t ( ) ;

b a . I n i t B a n k A c c o u n t ( ) ;

 

 

/ / В к л а д н а с ч е т

 

 

double dDeposit = 1 2 3 . 4 5 4 ;

 

 

C o n s o l e . W r i t e L i n e ( " В к л а д { 0 : C } " , d D e p o s i t ) ;

b a . D e p o s i t ( d D e p o s i t ) ;

 

 

/ / Б а л а н с с ч е т а

{ о } " ,

ba . GetString()) ;

C o n s o l e . W r i t e L i n e ( " С ч е т =

//Вот где имеетс я неприятность

double dAdditio n =

0.002;

 

C o n s o l e . W r i t e L i n e ( " В к л а д { 0 : C } " , d A d d i t i o n ) ;

b a . D e p o s i t ( d A d d i t i o n ) ;

 

 

/ / Р е з у л ь т а т

 

 

 

Console . WriteLine(

р е з у л ь т а т е с ч е т

= { о } " ,

 

b a . G e t S t r i n g ( ) ) ;

 

/ / Ожидаем

п о д т в е р ж д е н и я

п о л ь з о в а т е л я

C o n s o l e . W r i t e L i n e ( "Нажмит е <Enter>

д л я " +

 

 

" з а в е р ш е н и я п р о г р а м м ы . . . " ) ;

C o n s o l e . R e a d ( ) ;

 

 

 

}

 

 

 

 

}

 

 

 

 

/ / BankAccount

- о п р е д е л е н и е

к л а с с а , п р е д с т а в л я ю щ е г о

/ / п р о с т е й ш и й б а н к о в с к и й с ч е т public class BankAccount

{

private static int n N e x t A c c o u n t N u m b e r = 1 0 0 0 ; private int n A c c o u n t N u m b e r ;

Глава 11. Классы

237


// хранение баланса в виде одной переменной типа double private double d B a l a n c e ;

// Init

- инициализация банковского счета с нулевым

// балансом и использованием очередного глобального

•// номера

public

void InitBankAccount()

{

 

n A c c o u n t N u m b e r = + + n N e x t A c c o u n t N u m b e r ;

dBalance = 0.0;

}

 

// GetBalance - получение текущего баланса

public

double GetBalance()

{

 

return dBalance;,

}

 

// A c c o u n t N u m b e r

public

int GetAccountNumber()

{

 

return n A c c o u n t N u m b e r ;

}

 

public

void SetAccountNumber(int nAccountNumber)

{

 

this . nAccountNumber = n A c c o u n t N u m b e r ; -

}

// Deposit - позволен любой положительный вклад

public void

D e p o s i t ( d o u b l e dAmount)

{

 

 

 

 

 

if (dAmount

>

0.0)

 

 

{

 

 

 

 

 

dBalance

+=

d A m o u n t ;

 

}

 

 

 

 

 

}

 

 

 

 

 

// W i t h d r a w

-

вы

можете

снять

со счета любую сумму, не

// превьшающую

баланс;

функция

возвращает реально снятую

//сумму

public double Withdraw(doubl e dWithdrawal)

{

 

 

if (dBalance

<=

dWithdrawal)

{

 

 

dWithdrawal

=

d B a l a n c e ;

}

dBalance -= d W i t h d r a w a l ; return d W i t h d r a w a l ;

}

// GetStrin g - возвращает информацию о состоянии счета в

//виде строки

public string GetString()

238

Часть

IV.

Объектно-ориентированное программирование



{

string s = String . Format("#{0} = { l : C } " ,

G e t A c c o u n t N u m b e r ( ) , G e t B a l a n c e ( ) ) ;

return s;

}

}

Функция Mai n () создает банковский счет и вносит на него сумму 123.454 — т.е.

}сумму с дробным количеством копеек. Затем функция Mai n () вносит на счет еще одну долю копейки и выводит баланс счета.

Вывод программы выглядит следующим образом:

Создание

о б ъ е к т а

б а н к о в с к о г о

с ч е т а

Вклад

$123 .45

 

 

 

 

 

Счет =

#1001

=

$123 .45

 

Вклад

$0.00

 

 

 

 

 

В р е з у л ь т а т е

с ч е т

=

#1001 =

$123.46

Нажмите

<Enter>

д л я

з а в е р ш е н и я п р о г р а м м ы . . .

Пользователь начинает жаловаться на некорректные расчеты. Лично я ничего не имею против округления счета до ближайшей сотни сверху, но ведь не все клиенты такие покладистые... В общем, что греха таить — в программе действительно имеется ошибка.

Проблема, конечно, в том, что 123.454 выводится как 123.45. Чтобы избе­ жать проблем, банк принимает решение округлять вклады и снятия до бли­ жайшей копейки. Простейший путь осуществить это — конвертировать сче­ та в decimal и использовать метод Decimal . Round ( ) , как это сделано в демонстрационной программе DecimalBankAccount .

// DecimalBankAccount - с о з д а н и е б а н к о в с к о г о

/ /

и с п о л ь з о в а н и е м п е р е м е н н о й т и п а decimal д л я

//

баланса с ч е т а

using System;

с ч е т а с х р а н е н и я

namespace DecimalBankAccount

{

public class Program

{

public static voi d Main(string[] args)

{

/ / О т к р ы т и е б а н к о в с к о г о с ч е т а

C o n s o l e . W r i t e L i n e ( " С о з д а н и е о б ъ е к т а " +

 

" б а н к о в с к о г о с ч е т а " ) ;

BankAccount ba =

n e w B a n k A c c o u n t ( ) ;

b a . I n i t B a n k A c c o u n t ( ) ;

/ / В к л а д н а с ч е т

 

double dDeposit =

1 2 3 . 4 5 4 ;

C o n s o l e . W r i t e L i n e ( " В к л а д { 0 : C } " , d D e p o s i t ) ; b a . D e p o s i t ( d D e p o s i t ) ;

/ / Б а л а н с с ч е т а

[пава 11. Классы

239


C o n s o l e . W r i t e L i n e ( " С ч ет = { o } " (

b a . G e t S t r i n g ( ) ) ;

// Добавляем очень

малую

величину

double dAdditio n =

0.002;

 

Console . WriteLine("Вклад

{ 0 : C } " ,

d A d d i t i o n ) ;

b a . D e p o s i t ( d A d d i t i o n ) ;

 

 

//Результат

Console . WriteLine(" В результате счет = { о } " , ba .GetString ()'');

// Ожидаем подтверждения пользователя Console . WriteLine("Нажмите <Enter> для " +

"завершения п р о г р а м м ы . . . " ) ;

C o n s o l e . R e a d ( ) ;

}

//BankAccount - определение класса, представляющего

//простейший банковский счет

public class

BankAccount

{

 

 

p r i v a t e

static int n N e x t A c c o u n t N u m b e r = 1000 ;

p r i v a t e

int

n A c c o u n t N u m b e r ;

// хранение

баланса в виде одной переменной типа decimal

p r i v a t e

decimal m B a l a n c e ;

// Init - инициализация банковского счета с нулевым

//балансом и использованием очередного глобального

//номера

public v o i d InitBankAccount()

{

nAccountNumber = + + n N e x t A c c o u n t N u m b e r ; mBalance = 0;

}

// G e t B a l a n c e - получение текущего баланса public double GetBalance()

return (double)mBalance;

// A c c o u n t N u m b e r

public int GetAccountNumber()

{

return n A c c o u n t N u m b e r ;

}

public void SetAccountNumber(int nAccountNumber)

this . nAccountNumber = n A c c o u n t N u m b e r ;

}

240

Часть IV. Объектно-ориентированное программирование

Глава