Добавил:
2200 7008 9480 6099 TKFF БЛАГОДАРНОСТЬ МОЖНО ТУТ ОСТАВИТЬ Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ДИПЛОМ 2025 / 4 курса_МТУСИ / 1 КУРС / Информатика / С# для чайников - Мюллер.pdf
Скачиваний:
0
Добавлен:
04.06.2025
Размер:
53.3 Mб
Скачать

Выводы

Вы можете сказать, что нужно было с самого начала писать программу BankAccount с использованием decimal, и, пожалуй, с вами можно согласить­ ся. Но дело не в этом. Могут быть разные приложения и ситуации. Главное, что класс Ban kAccount оказался в состоянии решить проблему так, что не пришлось вносить никаких изменений в использующую его программу (об­ ратите внимание на то, что открытый интерфейс класса не изменился: методы

Balance ( ) и Withdraw ( ) так и возвращают значения типа douЫe, а Deposit ( )

иWithdraw ( ) принимают параметр типа douЫe).

Вданном случае единственным методом, на который потенциально вли­ яло изменение при непосредственном обращении к балансу, является метод Main ( ) , но в реальной программе могут существовать десятки таких методов,

иони могут оказаться в не меньшем количестве модулей. В данном случае ни один из этих методов не должен изменяться, потому что исправление находит­

ся в пределах класса BankAccount, ть. гхьх,ы ндьдгnд,dы которого (его откры­ тые методы) не изменился. Если бы методы обращались ко внутренним членам класса непосредственно, это было бы решительно невозможно.

Внесение внутренних изменений в класс требует определенного те­ стирования использующего класс кода, несмотря на то, что в него не

вносятся никакие модификации.

ВНИМАНИЕ!

Определение свойс;тв класса

Методы GetX( ) и SetX( ) , продемонстрированные в программе BankAccount, называются фдьтоРны отdь sаыы(access methods). Хотя их использование тео­ ретически является хорошей привычкой, на практике это зачастую приводит к грустным результатам. Судите сами - чтобы увеличить член _accountNumЬer на 1, требуется писать следующий код:

6, r))р им , хиnC,, r))р им , ,х n C c ) т V

С# имеет конструкцию, называемую deт,dь eтфыи делающую использование методов доступа существенно более простым. Приведенный далее фрагмент кода определяет свойство AccountNumЬer доступным для чтения и записи:

т

:)

:им r))р

им

,

и,х

, ,

 

g

1,

х,

химш))р

им

, и,хV

, ,

 

 

и шr , ­ =

 

 

, ш))р им ,

,х .

шr ,V

, ,

­­ую ЧАСТЬ 2 ETi. 2#"з"(,.# 2,(".( ##". 6(" ((..,( ".(#,. #( лD

 

=

 

 

 

 

 

 

 

 

 

 

=

 

 

 

 

 

 

 

 

 

 

 

S=

=

 

=

 

 

 

 

 

t-(=

+-===)(

(+n

(5E(d((=( (AyTh=(

(

)( (+;*=+=yA=yT=

=(T

T=y;(;

-TyiTy+(;

-

5=(===()-( {=)(;(

 

5-(=5+-=(=-(=

+;=(5o

5==(

5-+=(-T=+*yTTA=yT= +(;A=y) =vv(==(5+(y+5 =*

+(-

=5)n(+(

{=*(+c

+y-T

-(T A+(yE( ((=( -==(=)

y+=* -y=yT+

=(y +(Ao

T( +(; =y-( y+=*(

=-(=+=5=

=(y;( = Ay5+--(=A =y)5

=t-(=5+-(-(-5y

)y (= =(+y==)(=(==T==*y=5+(-= 5(=(=+= (=)g 5+*(;g;(=(

-(ag+-==(=o

T +=*(==AT=y=y=5+-T(=(=(=

y=*(-y*; -

(=)= =())=

 

 

 

СОВЕТ

ТЕХНИЧЕСКИЕ

ПОДРОБНОСТИ

,О АО!ПСi! Нre rЗ!НС АМОИАЕТМТЕХСerНСЕТАe А, ПСОПrАТЕХОИЕТBОМЕ!ЕТC ): ССЕТrЕТЕТС! e!! МТЕХrЗСТЕХeЕТОr!ВЕТАМОИАЕТМСН! rЗ!eЕТ АООЕТООАП!ВB!ЕТПrЗ

АСЕТЕПСОАЕТОhВCВС1ОТЕХСН! hВCВС1ОЕ Т8 Е Т

СМОИАЕТМСАОМА!ЗТЕХОЕТ! ,1СЕТ!ПЕТЕХО! !ttОЕТrМНЕ ОЗПr П,ЕТОС9 ЗО): !!ЕТ ОПЕТrr1rЗ С ОМСЕТЕПСОАЕТОИЗ!ЕТОВВОАЕТRПСЕТСОeЕТООНЕТRВ!ЕТ!!ТЕХ!): СrСОМСЕТЕН! ЕТОПЕi! ЗСirТЕХТЕХЕООЗСНВe!З Н!ПОАС!ВАЕТМ!НТЕХООЕТСС! ):

..,.!ТЕХr!О eП!ТЕХRacЕТОМС!ТЕХОЕТОПЕОО! ВП, ПСrОПСВНЕ ПСОrССЗЗ ТЕХОr ВП, АСЗО!ОС9 ОrЕТПrЕТО!ОС9 irСО ООrАПОП 1R!ЕТАМОИАЕТМСr ЕТОoi! АСЗО! ВОП!ТЕХЕВ!ПСЕТЕr МЕcВС!! ВП, ОЕТСС..,.!Нr,О eП!НСЗoВСННЕЗ ОПСААСr1 З!ЕТОВОМ ЕТОi!О ОПСААСC

Статические свойства

l,( , >o-.

o>.oT0

.(TT0o

..(--(un-!War,20, .!-,1.T0

>o,o2 -,(,

>or

-. o--!3-,-(е

.(. .!.(2()!

-

-.o.1 eo- .,!-,o3cho- ., -o,o

 

 

 

 

ГЛАВА 1 5 Класс: каждый сам за себя

335

Свойство NextAccountNumЬer доступно посредством указания имени его класса, так как оно не является свойством конкретного объекта (оно объявлено как static).

цц

,,

r))с им,

ж

:им

щr ,, ддщимmr))с ким,,

r))с

им,

г ,хi

(В этом примере value находится вне контекста свойства, а потому не рас­ сматривается как зарезервированное слово.)

Побочные действия свойств

Операция get может применяться не только для простого получения значе­ ния, связанного со свойством. Взгляните на следующий код:

т

:)

 

:)щ :им r))с

им , г

 

цц

 

 

 

р

 

цц

х,

химaaпим,

r))с

им, г х, i

 

1,

Данное свойство увеличивает статический член класса перед тем, как вер­ нуть результат. Однако это не слишком хорошая идея, ведь пользователь ниче­ го не знает о такой особенности и не подозревает, что происходит что-то по­ мимо чтения значения. Увеличение переменной в данном случае представляет собой зл­л­тли Hи,)e,2иц

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

ЗАПОМНИ! и методы должны избегать побочных действий, так как это может привести к трудноуловимым ошибкам. Изменяйте класс настолько явно и непосредственно, насколько это возможно.

336 ЧАСТЬ 2 Объектно-ориентированное программирование на С#

puЫic string Name ( get;
Это эквивалентно private string <somename>;

Дайте компилятору написать свойства для вас

Большинство свойств, описанных в предыдущем разделе, представляют со­ бой простые подпрограммы, писать которые очень просто. . . и утомительно:

private

string _name;

//

Член, соответствующий свойству

puЫic

string Name ( get

(

return _name ; } set ( _name = value; } }

Поскольку код везде оказывается одним и тем же, было решено позволить компилятору С# 3.0 делать эту работу вместо вас. Вот все, что вы должны на­ писать:

set ; }

// Что такое <somename>? // неизвестно и неважно .

puЬlic string Name ( get ( return <somename>; } set ( <somename> = value; } }

Компилятор создает некий загадочный член-данные, который во всем при­ веденном коде оказывается безымянным. Такой стиль заставляет использовать свойства даже внутри других членов того же класса просто потому, что все, что вам известно, - это имя свойства. По этой причине вы должны иметь оба свойства - и get, и set. Инициализировать их можно при помощи следующе­ го синтаксиса:

puЫic

int Anint (get ;

set ; } //

Компилятор создает

 

 

//

закрытую переменную

Anint

2 ;

//

Инициализация созданной компилятором

 

 

//

переменной при помощи свойства .

Методы и уровни доступа

Методы доступа не обязательно должны быть объявлены как puЫ ic. Вы можете объявлять их на любом уровне доступа, включая pri vate, если метод доступа предназначен для использования исключительно внутри собственного класса.

Можно даже отдельно изменять уровень доступа для частей get и set. Предположим, например, что вы не хотите давать возможнщ:ть работы с ме­ тодом set вне класса. В этом случае свойство можно записать таким образом:

internal string Name ( get ; private set ; }

ГЛАВА 1 5 Класс: каждый сам за себя ии#.

Конструирование объектов

 

 

 

 

 

 

 

 

с по_м_ощ ю

кон трукторов

 

 

 

 

 

 

 

 

 

!!!!!c!

Mc!!!.i!

,;!!!

 

e!!

!!!Зl!

!!!!!M!!

 

!!!-!c!!o

 

!D!c!!c

 

!-s:cl!!

!!M!

M-i!.i!!!N

!!D!!N

 

e!!!!!

!

cP! D!-i!Mot!

!!.i!.iМl!!cLn

ЗАПОМНИ!

!!Р !!Dc!

!!

!!c!!!.i

 

!!M!З !c!!!

!!,

!!M

СM!!!-i!С!M !!!!B

 

!.i!-i!!!!!P!

!-s:cl!!

-c!!

 

! !!!i L!! !!M!!Dc!Mc

!!Dc!

!!!!!!.i!,;

 

-i!-!!B

cP!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

!!-i!!!Bi

o !!l!!

 

!.i!,;L!c

L!c!!

!!!!!c

l! !!.i!.i! !l!D,;!!.i,

-i!!!!!c!i

 

 

!!!!

!,;!.i!!!!

 

i!

l!!!cl

!!!B

!!-!!!

!!

!!l!P!

!-s: cl !! D!!!З

!c

 

!!M!c!!.i,o

-i!l

it !cd!c!

e!,;!!!-!c!,;

 

!,;!c!

!!-i!!!

M!MdM!!!-i!

 

!,;Eec

! !c!!!!

 

!!!!!!

!!Lc!.ilM

!!!

!M!c!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

t П

 

 

 

 

 

 

 

 

 

 

 

!! !!!.i!!,;lС!,

!c !!!Зl!

!!!c!,c!

!!!,!З

!!,

!-s:cl!!Р

!!

!

!!!!!!,c!

 

!!MСM!!M-i !СME cP! L!c!!!i

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Мc!,;!!B!c

!c!!!!!

 

 

Mp

 

t

 

oi

e!! l!

!!.i!.i !!

el-ic!!!,!

 

l! !!.i!.i!

 

!!i M!c!M ИontОWn

e!! !-s:cl

! l! !!.i!.i!

 

io

 

ЗАПОМНИ!

Конструкторы, предоставляемые С#

,.

_w 0!'1!E!

-(,1AA( !(-,A.0)#(.

0'1$п0#,$.#

п0. ,A'1A(,1A'1'1,0 $

'1A ,!

.)!,-A(

$-,!,..!)#(.

'1A0'1$п0#,0.$'1!)#'1'1,A

,A'1A(,1A'1'1,A_

е#,'10(,1A'1

,'1A,_

-(#),A'1'1,.

,#,AA _!,

,'10)A,A( _ 1A'1A'1#п0$

!E0._0

)'1A(,1A'1$

_!(,1,0,-D$0

 

 

 

r

н

 

 

 

 

 

,.

_w !(-,A.0 )#A( (!(

S#_(

.(!

'10 a_

'10

'1A 0(,1A.(

,'1$-)!A'1'1!1!

.'1#.Aem

'10

$

'1A (,1!1-(

0-,!,..!)#(б--

)

),'1#.A'100_

Б!(,1,$,-п0-

T(!. (,10_ '1!,'1!1'1#(,1_

(,1,

,'10)!,0(

_ 1A'1A'1#п00 -,A,-.O$0

-!!.OA'10.

!. !E$._#0

 

_ _

T_

_w ,'1A,!-(#),-A(

_!'1-('1-_(!'1

,! -(,1!,.#'10.е

_!(!'1,.

0'10п$#,$.$'1-A(

.,A'1, ,#'1'1,0 !.tA_

#

 

 

 

-- ._

_._АQ

r 1,<9_,1:1а"!и!

$(,"а($!-'1""!,

.$ ! $'1 -- ($!-'1"(,

"'1 91

==

=

 

==

=

=

=

=

=

=

­==h+( +=--(h+(=(==(=====**RISh=(* =(=(+==*(=(+ )=h(+(-(--== ( =)h=g(* ) **===-=(=l(==(( *h=(=*Th(=5(===A==*(===5===*5==-{

-u( *h)*=)(=l(

5

(=(= RI()( = *(===(=( (=====**=RISh= (=* ) 5=5(=)=

-=====-*(=(+((

)-(( (

( ==(-(5iS=5(= t=(=h+(=+--u)-( (= *=(==A)=

=

 

 

=== h+) *(==-)) (=l(===5=h(=-=(=-(=(==RI(==(=h( )-)a)==)==t

a)) (=l(===) (

(==(-(5 *=) =u-(

=(= ==(-u ==--=( )=( =h(=*

)(

d)=(dh=(=* ((

*h=(=* *(=(+ ==)=====)( =(*====-=(-==(-)=

t

5(+=

-=*(+ n

 

 

 

ГЛАВА 1 5

класс: каждый сам за себя

339

Соседние файлы в папке Информатика