Sie sind auf Seite 1von 793

Thinking in C#

Larry OBrien and Bruce Eckel

Thinking in C#
Larry OBrien and Bruce Eckel
Prentice Hall Upper Saddle River, !!!)phptr)c*+ e! "er#ey $%&'(

Overview

Overvie! ,hat# -n#ide -ntr*ducti*n 01 Th*#e ,h* Can, C*de 21 -ntr*ducti*n t* O34ect# /1 Hell*, O34ect#

& . / 0' 0' '0

&1 C*ntr*lling Pr*gra+ 5l*!(6 '1 -nitiali7ati*n 8 Cleanup 0'0 .1 C*upling and C*he#i*n20' .a1 Hiding the -+ple+entati*n %1 Reu#ing cla##e# (a1 -nter9ace# 61 C*llecting :*ur O34ect# 001 -<O in C# 2'$ 26% //' /6/ &(' '2/ '60 %0' (1 -nter9ace# and -+ple+entati*n 2/&

0$1 Err*r Handling ,ith E;cepti*n# 021 Re9lecti*n and =ttri3ute#'.0 0/1 Pr*gra++ing ,ind*!# 5*r+# 0&1 >?-@ Overvie! 0'1 BAL 0.1 ,e3 Service# %$6 %'/ %'' 0&1 Aultithreaded Pr*gra++ing

=1 C# 5*r "ava Pr*gra++er#

%'%

B1 C# 5*r Ci#ual Ba#ic Pr*gra++er# C1 C# Pr*gra++ing >uideline# ?1 Re#*urce# -nde; %%/ %%&

%'6 %.0

Whats Inside
Overvie! ,hat# -n#ide -ntr*ducti*n & . /
PrereDui#ite#))))))))))))))))))))))))/ Learning C#)))))))))))))))))))))))))/ >*al#))))))))))))))))))))))))))))))))))))& Online d*cu+entati*n)))))))). Chapter#)))))))))))))))))))))))))))))). E;erci#e#))))))))))))))))))))))))))))))6 S*urce c*de))))))))))))))))))))))))0$
C*ding #tandard#))))))))))))))))))))))))))02

C# ver#i*n#))))))))))))))))))))))))02 Se+inar# and +ent*ring)))02 Err*r#)))))))))))))))))))))))))))))))))02 *te *n the c*ver de#ign) ) )0/ =ckn*!ledge+ent#))))))))))))0/
-nternet c*ntri3ut*r#))))))))))))))))))))0/

01 Th*#e ,h* Can, C*de 21 -ntr*ducti*n t* O34ect#

0' 0'

The pr*gre## *9 a3#tracti*n0. =n *34ect ha# an inter9ace) 06 =n *34ect pr*vide# #ervice#20 The hidden i+ple+entati*n22

Reu#ing the i+ple+entati*n2/ -nheritance1 reu#ing the inter9ace))))))))))2'


-#Ea v#) i#ElikeEa relati*n#hip#))))))26

-nterchangea3le *34ect# !ith p*ly+*rphi#+)))))))))))/0


=3#tract 3a#e cla##e# and inter9ace#/'

O34ect land#cape# and li9eti+e#))))))))))))))))))))))))))))))))))))))))))))))))))))))))))/.


C*llecti*n# and iterat*r#))))))))))))))/% The #ingly r**ted hierarchy)))))))))/6 C*llecti*n li3rarie# and #upp*rt 9*r ea#y c*llecti*n u#e)))))))))))))))))))))))))))))))))))))))))))))))))))))))))&$ The h*u#ekeeping dile++a1 !h* #h*uld clean upF))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))&0

E;cepti*n handling1 dealing !ith err*r#)))))))))))))))))))))))))))))))))))))))))))))&/ Aultithreading))))))))))))))))))&& Per#i#tence))))))))))))))))))))))))&' C# and the -nternet)))))))))))&'
,hat i# the ,e3F)))))))))))))))))))))))))&. ClientE#ide pr*gra++ing)))))))))))))&. ServerE#ide pr*gra++ing))))))))))))&. = #eparate arena1 applicati*n#)))))&.

=naly#i# and de#ign)))))))))))&% E;tre+e pr*gra++ing))))))&% ,hy ) ET #ucceed#)))))))))))&%


Sy#te+# are ea#ier t* e;pre## and under#tand)))))))))))&% Aa;i+al leverage !ith li3rarie#)))&% Err*r handling))))))))))))))))))))))))))))))&% Pr*gra++ing in the large))))))))))))&%

Strategie# 9*r tran#iti*n))))&(


>uideline#))))))))))))))))))))))))))))))))))))&( Aanage+ent *3#tacle#)))))))))))))))))'$

C# v#) "avaF)))))))))))))))))))))))'$ Su++ary)))))))))))))))))))))))))))'$

/1 Hell*, O34ect#

'0

:*u +anipulate *34ect# !ith re9erence# ))))))))))))))))))'0

:*u +u#t create all the *34ect#)))))))))))))))))))))'2


,here #t*rage live#))))))))))))))))))))))'/ =rray# in "ava)))))))))))))))))))))))))))))))'& Special ca#e1 value type#)))))))))))))))''

:*u never need t* de#tr*y an *34ect)))))))))))))))'.


Sc*ping)))))))))))))))))))))))))))))))))))))))))'. Sc*pe *9 *34ect#))))))))))))))))))))))))))))'%

Creating ne! data type#1 cla##)))))))))))))))))'(


5ield#, Pr*pertie#, and +eth*d#)))'6

Aeth*d#, argu+ent#, and return value#))))))))))))))).0


The argu+ent li#t))))))))))))))))))))))))).2

=ttri3ute# and AetaEBehavi*r)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))./ ?elegate#))))))))))))))))))))))))))).& Pr*pertie#)))))))))))))))))))))))))).' Creating e! Calue Type# .%


Enu+erati*n#))))))))))))))))))))))))))))))).% Struct#)))))))))))))))))))))))))))))))))))))))))).(

Building a C# pr*gra+)))))).6
a+e vi#i3ility))))))))))))))))))))))))))))).6 U#ing *ther c*+p*nent#))))))))))))))%$ The #tatic key!*rd))))))))))))))))))))))))%0

Putting -t =ll T*gether)))))))%/


C*+piling and running))))))))))))))))%' 5ineEtuning C*+pilati*n))))))))))))))%% The C*++*n Language Runti+e)%%

C*++ent# and e+3edded d*cu+entati*n))))))))))))))))))))))))))))))))))))))))))(0


?*cu+entati*n C*++ent#)))))))))))(0 ?*cu+entati*n e;a+ple))))))))))))))(&

C*ding #tyle)))))))))))))))))))))))(. Su++ary)))))))))))))))))))))))))))(% E;erci#e#))))))))))))))))))))))))))))(%

&1 C*ntr*lling Pr*gra+ 5l*!(6


U#ing C#*perat*r#))))))))))))(6

Precedence)))))))))))))))))))))))))))))))))))6$ =##ign+ent))))))))))))))))))))))))))))))))))6$ C## Prepr*ce##*r))))))))))))))))))))))))00'

9*reach)))))))))))))))))))))))))))))0/'

'1 -nitiali7ati*n 8 Cleanup 0'0


>uaranteed initiali7ati*n !ith the c*n#truct*r))))))))))))))))))))))))))))))))))0'0 Aeth*d *verl*ading)))))))))0'&
?i#tingui#hing *verl*aded +eth*d#0'. Overl*ading !ith pri+itive#)))))))0'% Overl*ading *n return value#)))))0.2 ?e9ault c*n#truct*r#)))))))))))))))))))0.2 The thi# key!*rd))))))))))))))))))))))))0./

Cleanup1 9inali7ati*n and gar3age c*llecti*n))))))))))))0.6


,hat are de#truct*r# 9*rF))))))))))))0%0 -n#tead *9 a de#truct*r, u#e Cl*#eGH *r ?i#p*#eGH))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))0%2 ?e#truct*r#, ?i#p*#eGH, and the u#ing key!*rd)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))0%% The death c*nditi*n))))))))))))))))))))0(2 H*! a gar3age c*llect*r !*rk#)))0(/

Ae+3er initiali7ati*n))))))0('
Speci9ying initiali7ati*n))))))))))))))0(% C*n#truct*r initiali7ati*n)))))))))))0((

=rray initiali7ati*n)))))))))))06'
Aultidi+en#i*nal array#))))))))))))2$$ Side3ar<=ppendi;1 ,hat a di99erence a rectangle +ake#)))))))))))))))))))))))))))))))))))))))))))))))))))))2$/

Su++ary)))))))))))))))))))))))))20/ E;erci#e#))))))))))))))))))))))))))20&

.1 C*upling and C*he#i*n20'


S*9t!are =# =rchitecture v#) S*9t!are =rchitecture))))))20% ,hat -# S*9t!are =rchitecture)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))206 Si+ulati*n =rchitecture#1 =l!ay# Taught, Rarely U#ed206 Client<Server and nETier =rchitecture#)))))))))))))))))))))))))))))))))))))))))))))22$ Layered =rchitecture#)))))222 Pr*3le+ES*lving =rchitecture#))))))))))))))))))))))))))))))))))))))))))))))))))))))))))22/ ?i#patching =rchitecture#22/

I *t Really O34ectEOrientedJ22& ?e#ign -# =# ?e#ign ?*e#22& 5ir#t, ?* * Har+)))))))))))22' ?e#ign Rule #01 ,rite B*ring C*de)))))))))))))))))))))))))))))))))))))))))))))))))))22. ?e#ign -# =# ?e#ign ?*e#2/&

.a1 Hiding the -+ple+entati*n


The na+e#pace unit))))))))2/'
Creating uniDue package na+e# 2/. U#ing i+p*rt# t* change 3ehavi*r2/6

2/&

C## acce## #peci9ier#))))))2&$


I5riendlyJ)))))))))))))))))))))))))))))))))))2&$ pu3lic1 inter9ace acce##)))))))))))))))2&0 private1 y*u cant t*uch thatK)))))2&2 pr*tected1 I#*rt *9 9riendlyJ)))))))2&/

-nter9ace and i+ple+entati*n)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))2&' Cla## acce##)))))))))))))))))))))2&. Su++ary)))))))))))))))))))))))))2&( E;erci#e#)))))))))))))))))))))))))2'$

%1 Reu#ing cla##e#

2'$

C*+p*#iti*n #ynta;)))))))))2'2 -nheritance #ynta;)))))))))))2'.


-nitiali7ing the 3a#e cla##)))))))))))2'6

C*+3ining c*+p*#iti*n and inheritance)))))))))))))))2.2


>uaranteeing pr*per cleanup))))2.&

Ch**#ing c*+p*#iti*n v#) inheritance)))))))))))))))))2.% pr*tected)))))))))))))))))))))))))2.6 -ncre+ental devel*p+ent2%$ Upca#ting)))))))))))))))))))))))))2%0


,hy Iupca#tingJF)))))))))))))))))))))))2%2 E;plicit Overl*ading Only))))))))))2%&

The c*n#t and read*nly key!*rd#)))))))))))))))))))))))))))))))))))))))))))))))))))))2(%


Sealed cla##e#)))))))))))))))))))))))))))))26$ E+pha#i7e virtual 9uncti*n#)))))))260

-nitiali7ati*n and cla## l*ading))))))))))))))))))))262

-nitiali7ati*n !ith inheritance))))262

Su++ary)))))))))))))))))))))))))26& E;erci#e#))))))))))))))))))))))))))26'

(1 -nter9ace# and -+ple+entati*n


Upca#ting revi#ited)))))))))/$$
5*rgetting the *34ect type)))))))))))/$0

26%

The t!i#t))))))))))))))))))))))))))/$/
Aeth*dEcall 3inding)))))))))))))))))))/$& Pr*ducing the right 3ehavi*r)))))/$' E;ten#i3ility)))))))))))))))))))))))))))))))/$6

Overriding v#) *verl*ading/0/ Operat*r Overl*ading))))))/0& =3#tract cla##e# and +eth*d#))))))))))))))))))))/0& C*n#truct*r# and p*ly+*rphi#+)))))))))))))))))))))))))))))))))))))))))))))))))))))))/2$
Order *9 c*n#truct*r call#))))))))))/2$ Behavi*r *9 p*ly+*rphic +eth*d# in#ide c*n#truct*r#)))))))))))))))))))))/2/

?e#igning !ith inheritance/2'


Pure inheritance v#) e;ten#i*n) ) )/2% ?*!nca#ting and runEti+e type identi9icati*n))))))))))))))))))))))/26

Su++ary)))))))))))))))))))))))))//& E;erci#e#))))))))))))))))))))))))))//&

(a1 -nter9ace#
E;tending an inter9ace

//'

-nter9ace#)))))))))))))))))))))))))//.
IAultiple inheritanceJ in "ava)))/&$ !ith inheritance)))))))))))))))))))))))))/&& ?*e#nt !*rk in C#) Au#t have #ecti*n *n enu+# and #truct# earlier))))))))))))))))))))))))))))))))))/&. -nitiali7ing 9ield# in inter9ace#))))/&( e#ting inter9ace#))))))))))))))))))))))/&6

-nner cla##e#))))))))))))))))))))/'2
-nner cla##e# and upca#ting))))))))/'' -nner cla##e# in +eth*d# and #c*pe#)))))))))))))))/'% =n*ny+*u# inner cla##e#)))))))))))/.$

The link t* the *uter cla##))))))))))/./ #tatic inner cla##e#)))))))))))))))))))))/.. Re9erring t* the *uter cla## *34ect/.( Reaching *ut!ard 9r*+ a +ultiplyEne#ted cla##)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))/%$ -nheriting 9r*+ inner cla##e#))))))/%0 Can inner cla##e# 3e *verriddenF/%2 -nner cla## identi9ier#)))))))))))))))))/%& ,hy inner cla##e#F)))))))))))))))))))))/%' -nner cla##e# 8 c*ntr*l 9ra+e!*rk#/(0

Su++ary)))))))))))))))))))))))))/(6 E;erci#e#)))))))))))))))))))))))))/6$

61 C*llecting :*ur O34ect#

/6/

=rray#))))))))))))))))))))))))))))))/6&
=rray# are 9ir#tEcla## *34ect#))))))/6. The =rray cla##))))))))))))))))))))))))))&$$ =rray# Static Aeth*d#)))))))))))))))&$0 =rray ele+ent c*+pari#*n#)))))))&$& ,hatF * 3u33le#F))))))))))))))))))))&$. Un#a9e =rray#))))))))))))))))))))))))))))&$( >et thing# rightL))))))))))))))))))))))))&02 L Then >et The+ 5a#t)))))))))))))))&0. =rray #u++ary))))))))))))))))))))))))))&2/

-ntr*ducti*n t* data #tructure#)))))))))))))))))))))))))))))))))))))))))))))))))))))))))&2/ Mueue# and Stack#))))))))))&2& =rrayLi#t))))))))))))))))))))))))))&2% Bit=rray)))))))))))))))))))))))))))&26 ?icti*narie#)))))))))))))))))))))&/0


Ha#hta3le))))))))))))))))))))))))))))))))))))&/0 Li#t?icti*nary))))))))))))))))))))))))))))&/& S*rtedLi#t)))))))))))))))))))))))))))))))))))&/' String #peciali#t#))))))))))))))))))))))))&/. One Ney, Aultiple Calue#)))))))))))&/. Cu#t*+i7ing Ha#hc*de Pr*vider#&/%

String #peciali#t#1 StringC*llecti*n and String?icti*nary ))))))))))))))))&/6 C*ntainer di#advantage1 unkn*!n type)))))))))))))))))&&$

U#ing C*llecti*nBa#e t* +ake typeEc*n#ci*u# c*llecti*n#))))))))))))))))))))))))))))))))))))))))))))))))))))&&/

-Enu+erat*r#))))))))))))))))))&&' Cu#t*+ -nde;er#)))))))))))))&&% Cu#t*+ Enu+erat*r# 8 ?ata Structure#)))))))))))))))))))))))))))))))))))))))))))&'0 S*rting and #earching Li#t#&'% 5r*+ C*llecti*n# t* =rray#&'6 Per#i#tent ?ata ,ith =?O) ET))))))))))))))))))))))))))))))))))))))))))))))))))))))))&..
>etting a handle *n data !ith ?ataSet)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))&.% C*nnecting t* a data3a#e))))))))))))&%0 5a#t Reading ,ith an -?ataReader&%' CRU? ,ith =?O) ET))))))))))))))))&%% Update and ?elete )))))))))))))))))))))&%% The O34ectERelati*nal -+pedance Ai#+atch)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))&(2

Su++ary)))))))))))))))))))))))))&(/ E;erci#e#)))))))))))))))))))))))))&(&

0$1 Err*r Handling ,ith E;cepti*n#


Ba#ic e;cepti*n#))))))))))))))&6$
E;cepti*n argu+ent#))))))))))))))))))&60

&('

Catching an e;cepti*n)))))&62
The try 3l*ck))))))))))))))))))))))))))))))&62 E;cepti*n handler#))))))))))))))))))))&6/ E;cepti*n# have a helplink)))))))))&6&

Creating y*ur *!n e;cepti*n#)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))&6& C## Lack O9 Checked E;cepti*n#)))))))))))))))))))))))))))))))))))))))))))))))))))))'$$


Catching any e;cepti*n)))))))))))))))'$0 Rethr*!ing an e;cepti*n)))))))))))'$2 Elevating the a3#tracti*n level)))'$/

Standard C# e;cepti*n#) )'$' Per9*r+ing cleanup !ith 9inally))))))))))))))))))))))'$.


,hat# 9inally 9*rF))))))))))))))))))))))'$( 5inally and u#ing)))))))))))))))))))))))))'00 Pit9all1 the l*#t e;cepti*n))))))))))))'02

C*n#truct*r#)))))))))))))))))))))'0' E;cepti*n +atching)))))))))'06


E;cepti*n guideline#)))))))))))))))))))'20

Su++ary))))))))))))))))))))))))))'20

Ot*d* P

e! ChapterF ?e#ign By C*ntract)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))'22

E;erci#e#))))))))))))))))))))))))))'22

001 -<O in C#

'2/

5ile, ?irect*ry, and Path '2/


= direct*ry li#ter)))))))))))))))))))))))))'2& Checking 9*r and creating direct*rie#)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))'2' -#*lated St*re#))))))))))))))))))))))))))))'2%

-nput and *utput)))))))))))))'26


Type# *9 Strea+))))))))))))))))))))))))))'/$ Te;t and Binary))))))))))))))))))))))))))'/0 ,*rking ,ith ?i99erent S*urce# '/0 5un ,ith Crypt*Strea+#)))))))))))'/& BinaryReader and Binary,riter '/( Strea+Reader and Strea+,riter'&&

Rand*+ acce## !ith Seek'&% Standard -<O)))))))))))))))))))'&(


Reading 9r*+ #tandard input)))))'&6 Redirecting #tandard -<O)))))))))))'&6 Regular E;pre##i*n#)))))))))))))))))))''0 Checking capitali7ati*n #tyle))))))''.

Su++ary)))))))))))))))))))))))))''6 E;erci#e#)))))))))))))))))))))))))'.$

021 Re9lecti*n and =ttri3ute#'.0


The need 9*r RTT-)))))))))))'.2
The Cla## *34ect))))))))))))))))))))))))))'.' Checking 3e9*re a ca#t))))))))))))))))'.(

RTT- #ynta;)))))))))))))))))))))'%% Re9lecti*n1 runEti+e cla## in9*r+ati*n))))))))))))'($


= cla## +eth*d e;tract*r))))))))))))'(2

Su++ary)))))))))))))))))))))))))'(( E;erci#e#))))))))))))))))))))))))))'(6

0/1 Pr*gra++ing ,ind*!# 5*r+#


?elegate# ))))))))))))))))))))))))'62 ?e#igning ,ith ?elegate#'6' Aultica#t ?elegate#)))))))))'6%

'60

Event#)))))))))))))))))))))))))))))).$0
Recur#ive Trap#))))))))))))))))))))))))).$&

The >ene#i# *9 ,ind*!# 5*r+#)))))))))))))))))))))))))))))))))))))))))))))))))))))))).$. Creating a 5*r+)))))))))))))).$% >U- =rchitecture#))))))))))).$6 U#ing the Ci#ual ?e#igner.$6 5*r+EEventEC*ntr*l)))))))).0. Pre#entati*nE=3#tracti*nEC*ntr*l))))))))))))))))))))))))))))))))))))))))))))))))))))).2$ A*delECie!EC*ntr*ller))).2& Lay*ut))))))))))))))))))))))))))))).26 *nEC*de Re#*urce#))))))).//
Creating Satellite =##e+3lie#)))))./6

C*n#tant Re#*urce#)))))))).&$ ,hat =3*ut the BP L**kF.&2 5ancy Butt*n#))))))))))))))))).&& T**ltip#))))))))))))))))))))))))))).&( ?i#playing 8 Editing Te;t.&6 Linking Te;t)))))))))))))))))))).'/ Check3*;e# and Radi*Butt*n#)))))))))))))))))))))))))))))))))))))))))))))))))))))))))).'' Li#t, C*+3*, and CheckedLi#tB*;e#))))))))))))))))))))))))))))))))))))))))))))))))).'( Aultiplane di#play# !ith the Splitter c*ntr*l))))))))))))))))))))))))))))))))))))..& TreeCie! 8 Li#tCie!)))))))... Li#tCie!))))))))))))))))))))))))))..(
-c*n Cie!#))))))))))))))))))))))))))))))))))..( ?etail# Cie!)))))))))))))))))))))))))))))))..(

Clip3*ard and ?ragEandE?r*p)))))))))))))))))))))))))))))))))))))))))))))))))))))))))).%2


Clip3*ard)))))))))))))))))))))))))))))))))))).%2 ?rag and ?r*p)))))))))))))))))))))))))))).%'

?ataE3*und C*ntr*l#)))))).(' Editing ?ata 9r*+ B*und C*ntr*l#))))))))))))))))))))))))))))))))))))))))))))))))))).6$ Aenu#)))))))))))))))))))))))))))))).6( Standard ?ial*g#)))))))))))))%$2 U#ageECentered ?e#ign)))%$' Su++ary)))))))))))))))))))))))))%$. E;erci#e#)))))))))))))))))))))))))%$(

0&1 >?-@ Overvie!

%$6

?ra!ing pi;el#)))))))))))))))))%$6

?ra!ing #hape#)))))))))))))))%$6 5illing and #tr*king)))))))))%$6 Printing)))))))))))))))))))))))))))%$6 =cce##ing ?irectB))))))))))))%02 Creating a #creen#vaer)))))%02 Creating a #y#te+ #ervice)%02 U#ageECentered ?e#ign) ) )%02 Creating an applicati*n G,ind*!# 8 Aenu#H))))))))))))))))))))))))))))))))))))%02
=+3ient Pr*pertie#)))))))))))))))))))))%02 =pplicati*n))))))))))))))))))))))))))))))))))%02 =pplicati*nC*nte;t)))))))))))))))))))))%02 =;H*#t))))))))))))))))))))))))))))))))))))))))%02 Err*rPr*vider)))))))))))))))))))))))))))))%02 5eatureSupp*rt)))))))))))))))))))))))))))%02 Help))))))))))))))))))))))))))))))))))))))))))))%02 Ae##age))))))))))))))))))))))))))))))))))))))%02 Ae##ageB*; )))))))))))))))))))))))))))))))%02 *ti9y-c*n)))))))))))))))))))))))))))))))))))%02 Pr*gre## Bar))))))))))))))))))))))))))))))))%0/ Pr*perty>rid)))))))))))))))))))))))))))))))%0/ Selecti*nRange)))))))))))))))))))))))))))%0/ Ta3C*ntr*l< Ta33ed Page#)))))))))%0/ Ti+er))))))))))))))))))))))))))))))))))))))))))%0/ T**lBar)))))))))))))))))))))))))))))))))))))))%0/ TrackBar)))))))))))))))))))))))))))))))))))))%0/ U#erC*ntr*l))))))))))))))))))))))))))))))))%0/

,ind*!# Service#))))))))))))%0/ Pr*gra++ing techniDue# %0/


Binding event# dyna+ically))))))))%0/ Separating 3u#ine## l*gic 9r*+ U- l*gic)))))))))))))))))))))))))))))))%0/

Ci#ual pr*gra++ing )))))))%0/ Su++ary))))))))))))))))))))))))))%0/ E;erci#e#))))))))))))))))))))))))))%0/

0&1 Aultithreaded Pr*gra++ing


) ET# Threading A*del) )%0% Thread Scheduling)))))))))))%0%

%0'

Threading Pr*3le+#)))))))))%0% The Cardinal Rule# *9 Threading))))))))))))))))))))))))))))))))))))))))))))))))))))))))%0% Thread Li9ecycle)))))))))))))))%0% Starting Thread#))))))))))))))%0% St*pping Thread#)))))))))))))%0% Pau#ing and Re#tarting))))%0% Bl*cking and ,aiting)))))))%0% E;cepti*n Handling in Thread#))))))))))))))))))))))))))))))))))))))))))))))))))))))))))%0% Thread# and -nter*pera3ility%0% Thread# and >ar3age C*llecti*n))))))))))))))))))))))))))))))))))))))))))))))))))))))))%0( Thread# and Scala3ility) ) )%0( Re#p*n#ive u#er inter9ace#%0(
Creating Thread#))))))))))))))))))))))))%20 Threading 9*r a re#p*n#ive inter9ace%2&

Sharing li+ited re#*urce#%2.


-+pr*perly acce##ing re#*urce#) %2. U#ing the A*nit*r cla## t* prevent c*lli#i*n# Ot*d* P c*n9ir+ +echani#+ *9 A*nit*r and add Aute; #a+ple c*de and -nterl*cked))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))%// Thread#, ?elegate#, and Event#))%'2

0'1 BAL 0.1 ,e3 Service#

%'/ %'' %'% %'6 %.0

Sche+a# and ?ataSet#)))))%'/

=1 C# 5*r "ava Pr*gra++er# B1 C# 5*r Ci#ual Ba#ic Pr*gra++er# C1 C# Pr*gra++ing >uideline#


?e#ign))))))))))))))))))))))))))))))%.0 -+ple+entati*n))))))))))))))%.(

?1 Re#*urce#

%%/

S*9t!are)))))))))))))))))))))))))))%%/ B**k#)))))))))))))))))))))))))))))))%%&
C#)))))))))))))))))))))))))))))))))))))))))))))))%%& =naly#i# 8 de#ign))))))))))))))))))))))))%%& Aanage+ent 8 Pr*ce##))))))))))))))%%&

-nde;

%%&
Bruce Eckel# Hand#EOn "ava Se+inar Aulti+edia C? -t# like c*+ing t* the #e+inarK =vaila3le at !!!)BruceEckel)c*+)))))))))))))))))))))))))))))))))))))))))))))))))))))%%%

Introduction
Prerequisites
Thi# 3**k a##u+e# that y*u have #*+e pr*gra++ing 9a+iliarity1 y*u under#tand that a pr*gra+ i# a c*llecti*n *9 #tate+ent#, the idea *9 a #u3r*utine<9uncti*n<+acr*, c*ntr*l #tate+ent# #uch a# Ii9J and l**ping c*n#truct# #uch a# I!hile,J etc) H*!ever, y*u +ight have learned thi# in +any place#, #uch a# pr*gra++ing !ith a +acr* language *r !*rking !ith a t**l like Perl) =# l*ng a# y*uve pr*gra++ed t* the p*int !here y*u 9eel c*+9*rta3le !ith the 3a#ic idea# *9 pr*gra++ing, y*ull 3e a3le t* !*rk thr*ugh thi# 3**k) O9 c*ur#e, the 3**k !ill 3e easier 9*r the C pr*gra++er# and +*re #* 9*r the C@@ pr*gra++er#, 3ut d*nt c*unt y*ur#el9 *ut i9 y*ure n*t e;perienced !ith th*#e language# G3ut c*+e !illing t* !*rk hardQ al#*, the +ulti+edia C? that acc*+panie# thi# 3**k !ill 3ring y*u up t* #peed *n the 3a#ic C #ynta; nece##ary t* learn C#H) -ll 3e intr*ducing the c*ncept# *9 *34ectE*riented pr*gra++ing GOOPH and C##3a#ic c*ntr*l +echani#+#, #* y*ull 3e e;p*#ed t* th*#e, and the 9ir#t e;erci#e# !ill inv*lve the 3a#ic c*ntr*lE9l*! #tate+ent#) =lth*ugh re9erence# !ill *9ten 3e +ade t* C and C@@ language 9eature#, the#e are n*t intended t* 3e in#ider c*++ent#, 3ut in#tead t* help all pr*gra++er# put C# in per#pective !ith th*#e language#, 9r*+ !hich, a9ter all, C# i# de#cended) - !ill atte+pt t* +ake the#e re9erence# #i+ple and t* e;plain anything that - think a n*nE C<C@@ pr*gra++er !*uld n*t 3e 9a+iliar !ith)

Learning C#
Tk) =t a3*ut the #a+e ti+e that +y 9ir#t 3**k Using C++ GO#3*rne<Ac>ra!EHill, 06(6H ca+e *ut, - 3egan teaching that language) Teaching pr*gra++ing language# ha# 3ec*+e +y pr*9e##i*nQ -ve #een n*dding head#, 3lank 9ace#, and pu77led e;pre##i*n# in audience# all *ver the !*rld #ince 06(6) =# - 3egan giving inEh*u#e training !ith #+aller gr*up# *9 pe*ple, - di#c*vered #*+ething during the e;erci#e#) Even th*#e

pe*ple !h* !ere #+iling and n*dding !ere c*n9u#ed a3*ut +any i##ue#) 9*und *ut, 3y chairing the C@@ track at the S*9t!are ?evel*p+ent C*n9erence 9*r a nu+3er *9 year# Gand later the "ava trackH, that - and *ther #peaker# tended t* give the typical audience t** +any t*pic# t** 9a#t) S* eventually, thr*ugh 3*th variety in the audience level and the !ay that - pre#ented the +aterial, - !*uld end up l*#ing #*+e p*rti*n *9 the audience) Aay3e it# a#king t** +uch, 3ut 3ecau#e - a+ *ne *9 th*#e pe*ple re#i#tant t* traditi*nal lecturing Gand 9*r +*#t pe*ple, - 3elieve, #uch re#i#tance re#ult# 9r*+ 3*red*+H, - !anted t* try t* keep every*ne up t* #peed) 5*r a ti+e, - !a# creating a nu+3er *9 di99erent pre#entati*n# in 9airly #h*rt *rder) Thu#, - ended up learning 3y e;peri+ent and iterati*n Ga techniDue that al#* !*rk# !ell in C# pr*gra+ de#ignH) Eventually devel*ped a c*ur#e u#ing everything - had learned 9r*+ +y teaching e;perienceR*ne that - !*uld 3e happy giving 9*r a l*ng ti+e) -t tackle# the learning pr*3le+ in di#crete, ea#yEt*Edige#t #tep#, and in a hand#E*n #e+inar Gthe ideal learning #ituati*nH there are e;erci#e# 9*ll*!ing each *9 the #h*rt le##*n#) - n*! give thi# c*ur#e in pu3lic C# #e+inar#, !hich y*u can 9ind *ut a3*ut at www.BruceEckel.com) GThe intr*duct*ry #e+inar i# al#* availa3le a# a C? ROA) -n9*r+ati*n i# availa3le at the #a+e ,e3 #ite)H The 9eed3ack that - get 9r*+ each #e+inar help# +e change and re9*cu# the +aterial until - think it !*rk# !ell a# a teaching +ediu+) But thi# 3**k i#nt 4u#t #e+inar n*te#R- tried t* pack a# +uch in9*r+ati*n a# c*uld !ithin the#e page#, and #tructured it t* dra! y*u thr*ugh *nt* the ne;t #u34ect) A*re than anything, the 3**k i# de#igned t* #erve the #*litary reader !h* i# #truggling !ith a ne! pr*gra++ing language)

Goals
Tk) Like +y previ*u# 3**k Thinking in C++, thi# 3**k ha# c*+e t* 3e #tructured ar*und the pr*ce## *9 teaching the language) -n particular, +y +*tivati*n i# t* create #*+ething that pr*vide# +e !ith a !ay t* teach the language in +y *!n #e+inar#) ,hen - think *9 a chapter in the 3**k, think in ter+# *9 !hat +ake# a g**d le##*n during a #e+inar) Ay g*al i# t* get 3iteE#i7ed piece# that can 3e taught in a rea#*na3le a+*unt *9 ti+e,

9*ll*!ed 3y e;erci#e# that are 9ea#i3le t* acc*+pli#h in a cla##r**+ #ituati*n) Ay g*al# in thi# 3**k are t*1 1. 2. Pre#ent the +aterial *ne #i+ple #tep at a ti+e #* that y*u can ea#ily dige#t each c*ncept 3e9*re +*ving *n) U#e e;a+ple# that are a# #i+ple and #h*rt a# p*##i3le) Thi# #*+eti+e# prevent# +e 9r*+ tackling Ireal !*rldJ pr*3le+#, 3ut -ve 9*und that 3eginner# are u#ually happier !hen they can under#tand every detail *9 an e;a+ple rather than 3eing i+pre##ed 3y the #c*pe *9 the pr*3le+ it #*lve#) =l#*, there# a #evere li+it t* the a+*unt *9 c*de that can 3e a3#*r3ed in a cla##r**+ #ituati*n) 5*r thi# - !ill n* d*u3t receive critici#+ 9*r u#ing It*y e;a+ple#,J 3ut -+ !illing t* accept that in 9av*r *9 pr*ducing #*+ething pedag*gically u#e9ul) Care9ully #eDuence the pre#entati*n *9 9eature# #* that y*u arent #eeing #*+ething that y*u havent 3een e;p*#ed t*) O9 c*ur#e, thi# i#nt al!ay# p*##i3leQ in th*#e #ituati*n#, a 3rie9 intr*duct*ry de#cripti*n i# given) >ive y*u !hat - think i# i+p*rtant 9*r y*u t* under#tand a3*ut the language, rather than everything - kn*!) - 3elieve there i# an in9*r+ati*n i+p*rtance hierarchy, and that there are #*+e 9act# that 6' percent *9 pr*gra++er# !ill never need t* kn*! and that 4u#t c*n9u#e pe*ple and add# t* their percepti*n *9 the c*+ple;ity *9 the language) T* take an e;a+ple 9r*+ C, i9 y*u +e+*ri7e the *perat*r precedence ta3le G- never didH, y*u can !rite clever c*de) But i9 y*u need t* think a3*ut it, it !ill al#* c*n9u#e the reader<+aintainer *9 that c*de) S* 9*rget a3*ut precedence, and u#e parenthe#e# !hen thing# arent clear) Neep each #ecti*n 9*cu#ed en*ugh #* that the lecture ti+eRand the ti+e 3et!een e;erci#e peri*d#Ri# #+all) *t *nly d*e# thi# keep the audience# +ind# +*re active and inv*lved during a hand#E*n #e+inar, 3ut it give# the reader a greater #en#e *9 acc*+pli#h+ent)

3.

!.

Introduction

".

Pr*vide y*u !ith a #*lid 9*undati*n #* that y*u can under#tand the i##ue# !ell en*ugh t* +*ve *n t* +*re di99icult c*ur#e!*rk and 3**k#)

Online docu#entation
tk

Cha$ters
Thi# 3**k !a# de#igned !ith *ne thing in +ind1 the !ay pe*ple learn the C# language) Se+inar audience 9eed3ack helped +e under#tand the di99icult part# that needed illu+inati*n) -n the area# !here - g*t a+3iti*u# and included t** +any 9eature# all at *nce, - ca+e t* kn*!Rthr*ugh the pr*ce## *9 pre#enting the +aterialRthat i9 y*u include a l*t *9 ne! 9eature#, y*u need t* e;plain the+ all, and thi# ea#ily c*+p*und# the #tudent# c*n9u#i*n) =# a re#ult, -ve taken a great deal *9 tr*u3le t* intr*duce the 9eature# a# 9e! at a ti+e a# p*##i3le) The g*al, then, i# 9*r each chapter t* teach a #ingle 9eature, *r a #+all gr*up *9 a##*ciated 9eature#, !ith*ut relying *n additi*nal 9eature#) That !ay y*u can dige#t each piece in the c*nte;t *9 y*ur current kn*!ledge 3e9*re +*ving *n) Here i# a 3rie9 de#cripti*n *9 the chapter# c*ntained in the 3**k, !hich c*rre#p*nd t* lecture# and e;erci#e peri*d# in +y hand#E*n #e+inar#)

Chapter 01 Chapter 21
tk

Introduction to Objects
tk

Everything is an Object Controlling Program Flow


tk

Chapter /1 Chapter &1

Initialization & Cleanup


Thi# chapter 3egin# 3y intr*ducing the c*n#truct*r, !hich guarantee# pr*per initiali7ati*n) The de9initi*n *9 the

Thinking in C

www.ThinkingIn.!et

c*n#truct*r lead# int* the c*ncept *9 9uncti*n *verl*ading G#ince y*u +ight !ant #everal c*n#truct*r#H) Thi# i# 9*ll*!ed 3y a di#cu##i*n *9 the pr*ce## *9 cleanup, !hich i# n*t al!ay# a# #i+ple a# it #ee+#) *r+ally, y*u 4u#t dr*p an *34ect !hen y*ure d*ne !ith it and the gar3age c*llect*r eventually c*+e# al*ng and relea#e# the +e+*ry) Thi# p*rti*n e;pl*re# the gar3age c*llect*r and #*+e *9 it# idi*#yncra#ie#) The chapter c*nclude# !ith a cl*#er l**k at h*! thing# are initiali7ed1 aut*+atic +e+3er initiali7ati*n, #peci9ying +e+3er initiali7ati*n, the *rder *9 initiali7ati*n, static initiali7ati*n and array initiali7ati*n)

Chapter '1 Chapter .1

Hiding the Implementation


tk

eusing Classes
The c*ncept *9 inheritance i# #tandard in virtually all OOP language#) -t# a !ay t* take an e;i#ting cla## and add t* it# 9uncti*nality Ga# !ell a# change it, the #u34ect *9 Chapter %H) -nheritance i# *9ten a !ay t* reu#e c*de 3y leaving the I3a#e cla##J the #a+e, and 4u#t patching thing# here and there t* pr*duce !hat y*u !ant) H*!ever, inheritance i#nt the *nly !ay t* +ake ne! cla##e# 9r*+ e;i#ting *ne#) :*u can al#* e+3ed an *34ect in#ide y*ur ne! cla## !ith com"osition) -n thi# chapter y*ull learn a3*ut the#e t!* !ay# t* reu#e c*de in "ava, and h*! t* apply the+)

Chapter %1

Polymorphism
On y*ur *!n, y*u +ight take nine +*nth# t* di#c*ver and under#tand p*ly+*rphi#+, a c*rner#t*ne *9 OOP) Thr*ugh #+all, #i+ple e;a+ple# y*ull #ee h*! t* create a 9a+ily *9 type# !ith inheritance and +anipulate *34ect# in that 9a+ily thr*ugh their c*++*n 3a#e cla##) C## p*ly+*rphi#+ all*!# y*u t* treat all *34ect# in thi# 9a+ily generically, !hich +ean# the 3ulk *9 y*ur c*de d*e#nt rely *n #peci9ic type in9*r+ati*n) Thi# +ake# y*ur pr*gra+# e;ten#i3le, #* 3uilding pr*gra+# and c*de +aintenance i# ea#ier and cheaper)

Introduction

Chapter (1

Inter!aces
C# pr*vide# a third !ay t* #et up a reu#e relati*n#hip, thr*ugh the inter$ace, !hich i# a pure a3#tracti*n *9 the inter9ace *9 an *34ect) The interface i# +*re than 4u#t an a3#tract cla## taken t* the e;tre+e, #ince it all*!# y*u t* per9*r+ a variati*n *n C@@# I+ultiple inheritance,J 3y creating a cla## that can 3e upca#t t* +*re than *ne 3a#e type)

Chapter 61

Holding your Objects


-t# a 9airly #i+ple pr*gra+ that ha# *nly a 9i;ed Duantity *9 *34ect# !ith kn*!n li9eti+e#) -n general, y*ur pr*gra+# !ill al!ay# 3e creating ne! *34ect# at a variety *9 ti+e# that !ill 3e kn*!n *nly !hile the pr*gra+ i# running) -n additi*n, y*u !*nt kn*! until runEti+e the Duantity *r even the e;act type *9 the *34ect# y*u need) T* #*lve the general pr*gra++ing pr*3le+, y*u need t* create any nu+3er *9 *34ect#, anyti+e, any!here) Thi# chapter e;pl*re# in depth the C*llecti*n Li3rary that ) ET #upplie# t* h*ld *34ect# !hile y*ure !*rking !ith the+1 the #i+ple array# and +*re #*phi#ticated c*ntainer# Gdata #tructure#H) Thi# chapter al#* c*ver# =?O) ET 3a#ic#)

Chapter 0$1

Error Handling with E"ceptions


The 3a#ic phil*#*phy *9 C# i# that 3adlyE9*r+ed c*de !ill n*t 3e run) =# +uch a# p*##i3le, the c*+piler catche# pr*3le+#, 3ut #*+eti+e# the pr*3le+#Reither pr*gra++er err*r *r a natural err*r c*nditi*n that *ccur# a# part *9 the n*r+al e;ecuti*n *9 the pr*gra+Rcan 3e detected and dealt !ith *nly at runEti+e) C# ha# e%ce"tion handling t* deal !ith any pr*3le+# that ari#e !hile the pr*gra+ i# running) Thi# chapter e;a+ine# h*! the key!*rd# try, catch, throw, throws, and finally !*rk in C#Q !hen y*u #h*uld thr*! e;cepti*n# and !hat t* d* !hen y*u catch the+) -n additi*n, y*ull #ee "ava# #tandard e;cepti*n#, h*! t* create y*ur *!n, !hat happen# !ith e;cepti*n# in c*n#truct*r#, and h*! e;cepti*n handler# are l*cated)

&

Thinking in C

www.ThinkingIn.!et

Chapter 001

#he C$ I%O &ystem


The*retically, y*u can divide any pr*gra+ int* three part#1 input, pr*ce##, and *utput) Thi# i+plie# that -<O Ginput<*utputH i# an i+p*rtant part *9 the eDuati*n) -n thi# chapter y*ull learn a3*ut the di99erent cla##e# that C# pr*vide# 9*r reading and !riting 9ile#, 3l*ck# *9 +e+*ry, and the c*n#*le)

Chapter 021 Chapter 0/1 Chapter 0&*

un'#ime #ype Identi!ication


tk

Programming (indows )pplications


tk

+ultiple #hreads
C# pr*vide# a 3uiltEin 9acility t* #upp*rt +ultiple c*ncurrent #u3ta#k#, called threads, running !ithin a #ingle pr*gra+) GUnle## y*u have +ultiple pr*ce##*r# *n y*ur +achine, thi# i# *nly the a""earance *9 +ultiple #u3ta#k#)H Thi# chapter l**k# at the #ynta; and #e+antic# *9 +ultithreading in C#)

Chapter 0'1

,+Tk

Chapter ./* (eb &ervices =ppendi; =1 C$ For 0ava Programmers


tk

=ppendi; B1
tk

C$ For 1isual 2asic Programmers

%&ercises
-ve di#c*vered that #i+ple e;erci#e# are e;cepti*nally u#e9ul t* c*+plete a #tudent# under#tanding during a #e+inar, #* y*ull 9ind a #et at the end *9 each chapter) A*#t e;erci#e# are de#igned t* 3e ea#y en*ugh that they can 3e 9ini#hed in a rea#*na3le a+*unt *9 ti+e in a cla##r**+ #ituati*n !hile the in#truct*r *3#erve#, +aking #ure that all the #tudent# are a3#*r3ing the +aterial)

Introduction

'

S*+e e;erci#e# are +*re advanced t* prevent 3*red*+ 9*r e;perienced #tudent#) The +a4*rity are de#igned t* 3e #*lved in a #h*rt ti+e and te#t and p*li#h y*ur kn*!ledge) S*+e are +*re challenging, 3ut n*ne pre#ent +a4*r challenge#) GPre#u+a3ly, y*ull 9ind th*#e *n y*ur *!nR*r +*re likely theyll 9ind y*uH)

'ource code
=ll the #*urce c*de 9*r thi# 3**k i# availa3le a# c*pyrighted 9ree!are, di#tri3uted a# a #ingle package, 3y vi#iting the ,e3 #ite www.thinkingin.net) T* +ake #ure that y*u get the +*#t current ver#i*n, thi# i# the *99icial #ite 9*r di#tri3uti*n *9 the c*de and the electr*nic ver#i*n *9 the 3**k) :*u can 9ind +irr*red ver#i*n# *9 the electr*nic 3**k and the c*de *n *ther #ite# G#*+e *9 the#e #ite# are 9*und at www.thinkingin.netH, 3ut y*u #h*uld check the *99icial #ite t* en#ure that the +irr*red ver#i*n i# actually the +*#t recent editi*n) :*u +ay di#tri3ute the c*de in cla##r**+ and *ther educati*nal #ituati*n#) The pri+ary g*al *9 the c*pyright i# t* en#ure that the #*urce *9 the c*de i# pr*perly cited, and t* prevent y*u 9r*+ repu3li#hing the c*de in print +edia !ith*ut per+i##i*n) G=# l*ng a# the #*urce i# cited, u#ing e;a+ple# 9r*+ the 3**k in +*#t +edia i# generally n*t a pr*3le+)H -n each #*urce c*de 9ile y*u !ill 9ind a re9erence t* the 9*ll*!ing c*pyright n*tice1 //:! :CopyRight.txt Copyright 2002 Larry O'Brien Source code fi e fro! the "#t edition of the $oo% &'hin%ing in C(.& ) right# re#er*ed +,C+-' a# a o.ed $y the fo o.ing #tate!ent#: /ou can free y u#e thi# fi e for your o.n .or% 0per#ona or co!!ercia 12 inc uding !odification# and di#tri$ution in executa$ e for! on y. -er!i##ion i# granted to u#e thi# fi e in c a##roo! #ituation#2 inc uding it# u#e in pre#entation !ateria #2 a# ong a# the $oo% &'hin%ing in C(& i# cited a# the #ource. +xcept in c a##roo! #ituation#2 you cannot copy and di#tri$ute thi# code3 in#tead2 the #o e

1(

Thinking in C

www.ThinkingIn.!et

di#tri$ution point i# http://....thin%ingin.net 0and officia !irror #ite#1 .here it i# free y a*ai a$ e. /ou cannot re!o*e thi# copyright and notice. /ou cannot di#tri$ute !odified *er#ion# of the #ource code in thi# pac%age. /ou cannot u#e thi# fi e in printed !edia .ithout the expre## per!i##ion of the author. Larry O4Brien !a%e# no repre#entation a$out the #uita$i ity of thi# #oft.are for any purpo#e. 5t i# pro*ided &a# i#& .ithout expre## or i!p ied .arranty of any %ind2 inc uding any i!p ied .arranty of !erchanta$i ity2 fitne## for a particu ar purpo#e or non6infringe!ent. 'he entire ri#% a# to the 7ua ity and perfor!ance of the #oft.are i# .ith you. Larry O4Brien2 Bruce +c%e 2 and the pu$ i#her #ha not $e ia$ e for any da!age# #uffered $y you or any third party a# a re#u t of u#ing or di#tri$uting #oft.are. 5n no e*ent .i Larry O4Brien2 Bruce +c%e or the pu$ i#her $e ia$ e for any o#t re*enue2 profit2 or data2 or for direct2 indirect2 #pecia 2 con#e7uentia 2 incidenta 2 or puniti*e da!age#2 ho.e*er cau#ed and regard e## of the theory of ia$i ity2 ari#ing out of the u#e of or ina$i ity to u#e #oft.are2 e*en if Larry O4Brien2 Bruce +c%e and the pu$ i#her ha*e $een ad*i#ed of the po##i$i ity of #uch da!age#. Shou d the #oft.are pro*e defecti*e2 you a##u!e the co#t of a nece##ary #er*icing2 repair2 or correction. 5f you thin% you'*e found an error2 p ea#e #u$!it the correction u#ing the for! you .i find at ....thin%ingin.net. 0- ea#e u#e the #a!e for! for non6code error# found in the $oo%.1 ///:8 :*u +ay u#e the c*de in y*ur pr*4ect# and in the cla##r**+ Gincluding y*ur pre#entati*n +aterial#H a# l*ng a# the c*pyright n*tice that appear# in each #*urce 9ile i# retained)

Introduction

11

Coding standards
-n the te;t *9 thi# 3**k, identi9ier# G9uncti*n, varia3le, and cla## na+e#H are #et in bold) A*#t key!*rd# are al#* #et in 3*ld, e;cept 9*r th*#e key!*rd# that are u#ed #* +uch that the 3*lding can 3ec*+e tedi*u#, #uch a# Icla##)J tk The pr*gra+# in thi# 3**k are 9ile# that are included 3y the !*rd pr*ce##*r in the te;t, directly 9r*+ c*+piled 9ile#) Thu#, the c*de 9ile# printed in the 3**k #h*uld all !*rk !ith*ut c*+piler err*r#) The err*r# that should cau#e c*+pileEti+e err*r +e##age# are c*++ented *ut !ith the c*++ent //! #* they can 3e ea#ily di#c*vered and te#ted u#ing aut*+atic +ean#) Err*r# di#c*vered and rep*rted t* the auth*r !ill appear 9ir#t in the di#tri3uted #*urce c*de and later in update# *9 the 3**k G!hich !ill al#* appear *n the ,e3 #ite www.thinkingin.netH)

C# versions
tk

'e#inars and #entoring


tk

%rrors
* +atter h*! +any trick# a !riter u#e# t* detect err*r#, #*+e al!ay# creep in and the#e *9ten leap *99 the page 9*r a 9re#h reader) There i# an err*r #u3+i##i*n 9*r+ linked 9r*+ the 3eginning *9 each chapter in the HTAL ver#i*n *9 thi# 3**k Gand *n the C? ROA 3*und int* the 3ack *9 thi# 3**k, and d*!nl*ada3le 9r*+ www.thinkingin.netH and al#* *n the ,e3 #ite it#el9, *n the page 9*r thi# 3**k) -9 y*u di#c*ver anything y*u 3elieve t* 3e an err*r, plea#e u#e thi# 9*r+ t* #u3+it the err*r al*ng !ith y*ur #ugge#ted c*rrecti*n) -9 nece##ary, include the

1)

Thinking in C

www.ThinkingIn.!et

*riginal #*urce 9ile and n*te any #ugge#ted +*di9icati*n#) :*ur help i# appreciated)

(ote on the cover design


tk

)c*nowledge#ents
tk

Internet contri+utors
tk

Introduction

13

1, -hose Who Can. Code 2, Introduction to O+/ects


The gene#i# *9 the c*+puter rev*luti*n !a# in a +achine) The gene#i# *9 *ur pr*gra++ing language# thu# tend# t* l**k like that +achine)
But c*+puter# are n*t #* +uch +achine# a# they are +ind a+pli9icati*n t**l# GI3icycle# 9*r the +ind,J a# Steve "*3# i# 9*nd *9 #ayingH and a di99erent kind *9 e;pre##ive +ediu+) =# a re#ult, the t**l# are 3eginning t* l**k le## like +achine# and +*re like part# *9 *ur +ind#, and al#* like *ther 9*r+# *9 e;pre##i*n #uch a# !riting, painting, #culpture, ani+ati*n, and 9il++aking) O34ectE*riented pr*gra++ing GOOPH i# part *9 thi# +*ve+ent t*!ard u#ing the c*+puter a# an e;pre##ive +ediu+) Thi# chapter !ill intr*duce y*u t* the 3a#ic c*ncept# *9 OOP, including an *vervie! *9 devel*p+ent +eth*d#) Thi# chapter, and thi# 3**k, a##u+e that y*u have had e;perience in a pr*cedural pr*gra++ing language, alth*ugh n*t nece##arily C) -9 y*u think y*u need +*re preparati*n in pr*gra++ing and the #ynta; *9 C 3e9*re tackling thi# 3**k, y*u #h*uld !*rk thr*ugh the Thinking in C* +oundations $or C++ and ,a-a training C? ROA availa3le at www.BruceEckel.com) Thi# chapter i# 3ackgr*und and #upple+entary +aterial) Aany pe*ple d* n*t 9eel c*+9*rta3le !ading int* *34ectE*riented pr*gra++ing !ith*ut under#tanding the 3ig picture 9ir#t) Thu#, there are +any c*ncept# that

15

are intr*duced here t* give y*u a #*lid *vervie! *9 OOP) H*!ever, +any *ther pe*ple d*nt get the 3ig picture c*ncept# until theyve #een #*+e *9 the +echanic# 9ir#tQ the#e pe*ple +ay 3ec*+e 3*gged d*!n and l*#t !ith*ut #*+e c*de t* get their hand# *n) -9 y*ure part *9 thi# latter gr*up and are eager t* get t* the #peci9ic# *9 the language, 9eel 9ree t* 4u+p pa#t thi# chapterR#kipping it at thi# p*int !ill n*t prevent y*u 9r*+ !riting pr*gra+# *r learning the language) H*!ever, y*u !ill !ant t* c*+e 3ack here eventually t* 9ill in y*ur kn*!ledge #* y*u can under#tand !hy *34ect# are i+p*rtant and h*! t* de#ign !ith the+)

-he $rogress o0 a+straction


=ll pr*gra++ing language# pr*vide a3#tracti*n#) -t can 3e argued that the c*+ple;ity *9 the pr*3le+# y*ure a3le t* #*lve i# directly related t* the kind and Duality *9 a3#tracti*n) By IkindJ - +ean, I,hat i# it that y*u are a3#tractingFJ =##e+3ly language i# a #+all a3#tracti*n *9 the underlying +achine) Aany #*Ecalled Ii+perativeJ language# that 9*ll*!ed G#uch a# 5*rtran, B=S-C, and CH !ere a3#tracti*n# *9 a##e+3ly language) The#e language# are 3ig i+pr*ve+ent# *ver a##e+3ly language, 3ut their pri+ary a3#tracti*n #till reDuire# y*u t* think in ter+# *9 the #tructure *9 the c*+puter rather than the #tructure *9 the pr*3le+ y*u are trying t* #*lve) The pr*gra++er +u#t e#ta3li#h the a##*ciati*n 3et!een the +achine +*del Gin the I#*luti*n #pace,J !hich i# the place !here y*ure +*deling that pr*3le+, #uch a# a c*+puterH and the +*del *9 the pr*3le+ that i# actually 3eing #*lved Gin the Ipr*3le+ #pace,J !hich i# the place !here the pr*3le+ e;i#t#H) The e99*rt reDuired t* per9*r+ thi# +apping, and the 9act that it i# e;trin#ic t* the pr*gra++ing language, pr*duce# pr*gra+# that are di99icult t* !rite and e;pen#ive t* +aintain, and a# a #ide e99ect created the entire Ipr*gra++ing +eth*d#J indu#try) The alternative t* +*deling the +achine i# t* +*del the pr*3le+ y*ure trying t* #*lve) Early language# #uch a# L-SP and =PL ch*#e particular vie!# *9 the !*rld GI=ll pr*3le+# are ulti+ately li#t#J *r I=ll pr*3le+# are alg*rith+ic,J re#pectivelyH) PROLO> ca#t# all pr*3le+# int* chain# *9 deci#i*n#) Language# have 3een created 9*r c*n#traintE3a#ed

16

pr*gra++ing and 9*r pr*gra++ing e;clu#ively 3y +anipulating graphical #y+3*l#) GThe latter pr*ved t* 3e t** re#trictive)H Each *9 the#e appr*ache# i# a g**d #*luti*n t* the particular cla## *9 pr*3le+ theyre de#igned t* #*lve, 3ut !hen y*u #tep *ut#ide *9 that d*+ain they 3ec*+e a!k!ard) The *34ectE*riented appr*ach g*e# a #tep 9urther 3y pr*viding t**l# 9*r the pr*gra++er t* repre#ent ele+ent# in the pr*3le+ #pace) Thi# repre#entati*n i# general en*ugh that the pr*gra++er i# n*t c*n#trained t* any particular type *9 pr*3le+) ,e re9er t* the ele+ent# in the pr*3le+ #pace and their repre#entati*n# in the #*luti*n #pace a# I*34ect#)J GO9 c*ur#e, y*u !ill al#* need *ther *34ect# that d*nt have pr*3le+E#pace anal*g#)H The idea i# that the pr*gra+ i# all*!ed t* adapt it#el9 t* the ling* *9 the pr*3le+ 3y adding ne! type# *9 *34ect#, #* !hen y*u read the c*de de#cri3ing the #*luti*n, y*ure reading !*rd# that al#* e;pre## the pr*3le+) Thi# i# a +*re 9le;i3le and p*!er9ul language a3#tracti*n than !hat !eve had 3e9*re) Thu#, OOP all*!# y*u t* de#cri3e the pr*3le+ in ter+# *9 the pr*3le+, rather than in ter+# *9 the c*+puter !here the #*luti*n !ill run) There# #till a c*nnecti*n 3ack t* the c*+puter, th*ugh) Each *34ect l**k# Duite a 3it like a little c*+puterQ it ha# a #tate, and it ha# *perati*n# that y*u can a#k it t* per9*r+) H*!ever, thi# d*e#nt #ee+ like #uch a 3ad anal*gy t* *34ect# in the real !*rldRthey all have characteri#tic# and 3ehavi*r#) S*+e language de#igner# have decided that *34ectE*riented pr*gra++ing 3y it#el9 i# n*t adeDuate t* ea#ily #*lve all pr*gra++ing pr*3le+#, and adv*cate the c*+3inati*n *9 vari*u# appr*ache# int* multi"aradigm pr*gra++ing language#)0 =lan Nay #u++ari7ed 9ive 3a#ic characteri#tic# *9 S+alltalk, the 9ir#t #ucce##9ul *34ectE*riented language and *ne *9 the language# up*n !hich C# i# 3a#ed) The#e characteri#tic# repre#ent a pure appr*ach t* *34ectE *riented pr*gra++ing1 1. Everything is an object. Think *9 an *34ect a# a 9ancy varia3leQ it #t*re# data, 3ut y*u can I+ake reDue#t#J t* that *34ect, a#king it t* per9*r+ *perati*n# *n it#el9) -n the*ry, y*u can take any c*nceptual c*+p*nent in the pr*3le+ y*ure trying t* #*lve

0 See .ulti"aradigm /rogramming in 0eda 3y Ti+*thy Budd G=ddi#*nE,e#ley 066'H)

Cha"ter 1* Introduction to 123ects

1#

Gd*g#, 3uilding#, #ervice#, etc)H and repre#ent it a# an *34ect in y*ur pr*gra+) 2. A program is a bunch of objects telling each other what to do by sending messages) T* +ake a reDue#t *9 an *34ect, y*u I#end a +e##ageJ t* that *34ect) A*re c*ncretely, y*u can think *9 a +e##age a# a reDue#t t* call a 9uncti*n that 3el*ng# t* a particular *34ect) Each object has its own memory made up of other objects) Put an*ther !ay, y*u create a ne! kind *9 *34ect 3y +aking a package c*ntaining e;i#ting *34ect#) Thu#, y*u can 3uild c*+ple;ity in a pr*gra+ !hile hiding it 3ehind the #i+plicity *9 *34ect#) Every object has a type) U#ing the parlance, each *34ect i# an instance *9 a class, in !hich Icla##J i# #yn*ny+*u# !ith Itype)J The +*#t i+p*rtant di#tingui#hing characteri#tic *9 a cla## i# I,hat +e##age# can y*u #end t* itFJ All objects of a particular type can receive the same messages) Thi# i# actually a l*aded #tate+ent, a# y*u !ill #ee later) Becau#e an *34ect *9 type IcircleJ i# al#* an *34ect *9 type I#hape,J a circle i# guaranteed t* accept #hape +e##age#) Thi# +ean# y*u can !rite c*de that talk# t* #hape# and aut*+atically handle anything that 9it# the de#cripti*n *9 a #hape) Thi# su2stituta2ilit4 i# *ne *9 the +*#t p*!er9ul c*ncept# in OOP)

3.

!.

B**ch *99er# an even +*re #uccinct de#cripti*n *9 an *34ect1 5n o23ect has state6 2eha-ior and identit4 Thi# +ean# that an *34ect can have internal data G!hich give# it #tateH, +eth*d# Gt* pr*duce 3ehavi*rH, and each *34ect can 3e uniDuely di#tingui#hed 9r*+ every *ther *34ect P t* put thi# in a c*ncrete #en#e, each *34ect ha# a uniDue addre## in +e+*ry2

2 Thi# i# actually a 3it re#trictive, #ince *34ect# can c*nc eiva3ly e;i#t in di99erent +achine#

and addre## #pace#, and they can al#* 3e #t*red *n di#k) -n the#e ca#e#, the identity *9 the *34ect +u#t 3e deter+ined 3y #*+ething *ther than +e+*ry addre##)

1&

Thinking in C

www.ThinkingIn.!et

)n o+/ect has an inter0ace


=ri#t*tle !a# pr*3a3ly the 9ir#t t* 3egin a care9ul #tudy *9 the c*ncept *9 t4"e7 he #p*ke *9 Ithe cla## *9 9i#he# and the cla## *9 3ird#)J The idea that all *34ect#, !hile 3eing uniDue, are al#* part *9 a cla## *9 *34ect# that have characteri#tic# and 3ehavi*r# in c*++*n !a# u#ed directly in the 9ir#t *34ectE*riented language, Si+ulaE.%, !ith it# 9unda+ental key!*rd class that intr*duce# a ne! type int* a pr*gra+) Si+ula, a# it# na+e i+plie#, !a# created 9*r devel*ping #i+ulati*n# #uch a# the cla##ic I3ank teller pr*3le+)J -n thi#, y*u have a 3unch *9 teller#, cu#t*+er#, acc*unt#, tran#acti*n#, and unit# *9 +*neyRa l*t *9 I*34ect#)J O34ect# that are identical e;cept 9*r their #tate during a pr*gra+# e;ecuti*n are gr*uped t*gether int* Icla##e# *9 *34ect#J and that# !here the key!*rd class ca+e 9r*+) Creating a3#tract data type# Gcla##e#H i# a 9unda+ental c*ncept in *34ectE*riented pr*gra++ing) =3#tract data type# !*rk al+*#t e;actly like 3uiltEin type#1 :*u can create varia3le# *9 a type Gcalled o23ects *r instances in *34ectE*riented parlanceH and +anipulate th*#e varia3le# Gcalled sending messages *r re8uests7 y*u #end a +e##age and the *34ect 9igure# *ut !hat t* d* !ith itH) The +e+3er# Gele+ent#H *9 each cla## #hare #*+e c*++*nality1 every acc*unt ha# a 3alance, every teller can accept a dep*#it, etc) =t the #a+e ti+e, each +e+3er ha# it# *!n #tate, each acc*unt ha# a di99erent 3alance, each teller ha# a na+e) Thu#, the teller#, cu#t*+er#, acc*unt#, tran#acti*n#, etc), can each 3e repre#ented !ith a uniDue entity in the c*+puter pr*gra+) Thi# entity i# the *34ect, and each *34ect 3el*ng# t* a particular cla## that de9ine# it# characteri#tic# and 3ehavi*r#) S*, alth*ugh !hat !e really d* in *34ectE*riented pr*gra++ing i# create ne! data type#, virtually all *34ectE*riented pr*gra++ing language# u#e the Icla##J key!*rd) ,hen y*u #ee the !*rd ItypeJ think Icla##J and vice ver#a/) Since a cla## de#cri3e# a #et *9 *34ect# that have identical characteri#tic# Gdata ele+ent#H and 3ehavi*r# G9uncti*nalityH, a cla## i# really a data type 3ecau#e a 9l*ating p*int nu+3er, 9*r e;a+ple, al#* ha# a #et *9
/ S*+e pe*ple +ake a di#tincti*n, #tating that type deter+ine# the inter9ace !hile cla## i#

a particular i+ple+entati*n *9 that inter9ace)

Cha"ter 1* Introduction to 123ects

1'

characteri#tic# and 3ehavi*r#) The di99erence i# that a pr*gra++er de9ine# a cla## t* 9it a pr*3le+ rather than 3eing 9*rced t* u#e an e;i#ting data type that !a# de#igned t* repre#ent a unit *9 #t*rage in a +achine) :*u e;tend the pr*gra++ing language 3y adding ne! data type# #peci9ic t* y*ur need#) The pr*gra++ing #y#te+ !elc*+e# the ne! cla##e# and give# the+ all the care and typeEchecking that it give# t* 3uiltEin type#) The *34ectE*riented appr*ach i# n*t li+ited t* 3uilding #i+ulati*n#) ,hether *r n*t y*u agree that any pr*gra+ i# a #i+ulati*n *9 the #y#te+ y*ure de#igning, the u#e *9 OOP techniDue# can ea#ily reduce a large #et *9 pr*3le+# t* a #i+ple #*luti*n) Once a cla## i# e#ta3li#hed, y*u can +ake a# +any *34ect# *9 that cla## a# y*u like, and then +anipulate th*#e *34ect# a# i9 they are the ele+ent# that e;i#t in the pr*3le+ y*u are trying t* #*lve) -ndeed, *ne *9 the challenge# *9 *34ectE*riented pr*gra++ing i# t* create a *neEt*E*ne +apping 3et!een the ele+ent# in the pr*3le+ #pace and *34ect# in the #*luti*n #pace) But h*! d* y*u get an *34ect t* d* u#e9ul !*rk 9*r y*uF There +u#t 3e a !ay t* +ake a reDue#t *9 the *34ect #* that it !ill d* #*+ething, #uch a# c*+plete a tran#acti*n, dra! #*+ething *n the #creen, *r turn *n a #!itch) =nd each *34ect can #ati#9y *nly certain reDue#t#) The reDue#t# y*u can +ake *9 an *34ect are de9ined 3y it# inter$ace6 and the type i# !hat deter+ine# the inter9ace) = #i+ple e;a+ple +ight 3e a repre#entati*n *9 a light 3ul31

-5$e (a#e Inter0ace

Light On12 O0012 3righten12 4i#12

Light t 9 ne. Light013 t.On013

)(

Thinking in C

www.ThinkingIn.!et

The inter9ace e#ta3li#he# what reDue#t# y*u can +ake 9*r a particular *34ect) H*!ever, there +u#t 3e c*de #*+e!here t* #ati#9y that reDue#t) Thi#, al*ng !ith the hidden data, c*+pri#e# the im"lementation) 5r*+ a pr*cedural pr*gra++ing #tandp*int, it# n*t that c*+plicated) = type ha# a 9uncti*n a##*ciated !ith each p*##i3le reDue#t, and !hen y*u +ake a particular reDue#t t* an *34ect, that 9uncti*n i# called) Thi# pr*ce## i# u#ually #u++ari7ed 3y #aying that y*u I#end a +e##ageJ G+ake a reDue#tH t* an *34ect, and the *34ect 9igure# *ut !hat t* d* !ith that +e##age Git e;ecute# c*deH) Here, the na+e *9 the type<cla## i# Light, the na+e *9 thi# particular Light *34ect i# lt, and the reDue#t# that y*u can +ake *9 a Light *34ect are t* turn it *n, turn it *99, +ake it 3righter, *r +ake it di++er) :*u create a Light *34ect 3y de9ining a Ire9erenceJ GltH 9*r that *34ect and calling new t* reDue#t a ne! *34ect *9 that type) T* #end a +e##age t* the *34ect, y*u #tate the na+e *9 the *34ect and c*nnect it t* the +e##age reDue#t !ith a peri*d Gd*tH) 5r*+ the #tandp*int *9 the u#er *9 a prede9ined cla##, that# pretty +uch all there i# t* pr*gra++ing !ith *34ect#) The diagra+ #h*!n a3*ve 9*ll*!# the 9*r+at *9 the Uni$ied .odeling 0anguage GUALH) Each cla## i# repre#ented 3y a 3*;, !ith the type na+e in the t*p p*rti*n *9 the 3*;, any data +e+3er# that y*u care t* de#cri3e in the +iddle p*rti*n *9 the 3*;, and the mem2er $unctions Gthe 9uncti*n# that 3el*ng t* thi# *34ect, !hich receive any +e##age# y*u #end t* that *34ectH in the 3*tt*+ p*rti*n *9 the 3*;) O9ten, *nly the na+e *9 the cla## and the pu3lic +e+3er 9uncti*n# are #h*!n in UAL de#ign diagra+#, and #* the +iddle p*rti*n i# n*t #h*!n) -9 y*ure intere#ted *nly in the cla## na+e, then the 3*tt*+ p*rti*n d*e#nt need t* 3e #h*!n, either)

)n o+/ect $rovides services


tk

Cha"ter 1* Introduction to 123ects

)1

-he hidden i#$le#entation


-t i# help9ul t* 3reak up the playing 9ield int* class creators Gth*#e !h* create ne! data type#H and client "rogrammers Gthe cla## c*n#u+er# !h* u#e the data type# in their applicati*n#H) The g*al *9 the client pr*gra++er i# t* c*llect a t**l3*; 9ull *9 cla##e# t* u#e 9*r rapid applicati*n devel*p+ent) The g*al *9 the cla## creat*r i# t* 3uild a cla## that e;p*#e# *nly !hat# nece##ary t* the client pr*gra++er and keep# everything el#e hidden) ,hyF Becau#e i9 it# hidden, the client pr*gra++er cant u#e it, !hich +ean# that the cla## creat*r can change the hidden p*rti*n at !ill !ith*ut !*rrying a3*ut the i+pact *n any*ne el#e) The hidden p*rti*n u#ually repre#ent# the tender in#ide# *9 an *34ect that c*uld ea#ily 3e c*rrupted 3y a carele## *r unin9*r+ed client pr*gra++er, #* hiding the i+ple+entati*n reduce# pr*gra+ 3ug#) The c*ncept *9 i+ple+entati*n hiding cann*t 3e *vere+pha#i7ed) -n any relati*n#hip it# i+p*rtant t* have 3*undarie# that are re#pected 3y all partie# inv*lved) ,hen y*u create a li3rary, y*u e#ta3li#h a relati*n#hip !ith the client pr*gra++er, !h* i# al#* a pr*gra++er, 3ut *ne !h* i# putting t*gether an applicati*n 3y u#ing y*ur li3rary, p*##i3ly t* 3uild a 3igger li3rary) -9 all the +e+3er# *9 a cla## are availa3le t* every*ne, then the client pr*gra++er can d* anything !ith that cla## and there# n* !ay t* en9*rce rule#) Even th*ugh y*u +ight really pre9er that the client pr*gra++er n*t directly +anipulate #*+e *9 the +e+3er# *9 y*ur cla##, !ith*ut acce## c*ntr*l there# n* !ay t* prevent it) Everything# naked t* the !*rld) S* the 9ir#t rea#*n 9*r acce## c*ntr*l i# t* keep client pr*gra++er# hand# *99 p*rti*n# they #h*uldnt t*uchRpart# that are nece##ary 9*r the internal +achinati*n# *9 the data type 3ut n*t part *9 the inter9ace that u#er# need in *rder t* #*lve their particular pr*3le+#) Thi# i# actually a #ervice t* u#er# 3ecau#e they can ea#ily #ee !hat# i+p*rtant t* the+ and !hat they can ign*re)

))

Thinking in C

www.ThinkingIn.!et

The #ec*nd rea#*n 9*r acce## c*ntr*l i# t* all*! the li3rary de#igner t* change the internal !*rking# *9 the cla## !ith*ut !*rrying a3*ut h*! it !ill a99ect the client pr*gra++er) 5*r e;a+ple, y*u +ight i+ple+ent a particular cla## in a #i+ple 9a#hi*n t* ea#e devel*p+ent, and then later di#c*ver that y*u need t* re!rite it in *rder t* +ake it run 9a#ter) -9 the inter9ace and i+ple+entati*n are clearly #eparated and pr*tected, y*u can acc*+pli#h thi# ea#ily) "ava u#e# 9ive e;plicit key!*rd# t* #et the 3*undarie# in a cla##1 public, private, protected, internal, and protected internal) Their u#e and +eaning are Duite #traight9*r!ard) The#e access s"eci$iers deter+ine !h* can u#e the de9initi*n# that 9*ll*!) public +ean# the 9*ll*!ing de9initi*n# are availa3le t* every*ne) The private key!*rd, *n the *ther hand, +ean# that n* *ne can acce## th*#e de9initi*n# e;cept y*u, the creat*r *9 the type, in#ide +e+3er 9uncti*n# *9 that type) private i# a 3rick !all 3et!een y*u and the client pr*gra++er) -9 #*+e*ne trie# t* acce## a private +e+3er, theyll get a c*+pileEti+e err*r) protected act# like private, !ith the e;cepti*n that an inheriting cla## ha# acce## t* protected +e+3er#, 3ut n*t private +e+3er#) -nheritance !ill 3e intr*duced #h*rtly) internal i# *9ten called I9riendlyJPthe de9initi*n can 3e acce##ed 3y *ther cla##e# in the #a+e na+e#pace a# i9 it !ere public, 3ut i# n*t acce##i3le t* cla##e# in di99erent na+e#pace#) a+e#pace# !ill 3e di#cu##ed in depth in chapter #re9#) protected internal all*!# acce## 3y cla##e# !ithin the #a+e na+e#pace Ga# !ith internalH or 3y inheriting cla##e# Ga# !ith protectedH even i9 the inheriting cla##e# are n*t !ithin the #a+e na+e#pace) C## de9ault acce##, !hich c*+e# int* play i9 y*u d*nt u#e *ne *9 the a9*re+enti*ned #peci9ier#, i# internal)

6eusing the i#$le#entation


Once a cla## ha# 3een created and te#ted, it #h*uld GideallyH repre#ent a u#e9ul unit *9 c*de) -t turn# *ut that thi# reu#a3ility i# n*t nearly #* ea#y t* achieve a# +any !*uld h*peQ it take# e;perience and in#ight t* pr*duce a g**d de#ign) But *nce y*u have #uch a de#ign, it 3eg# t* 3e reu#ed) C*de

Cha"ter 1* Introduction to 123ects

)3

reu#e i# *ne *9 the greate#t advantage# that *34ectE*riented pr*gra++ing language# pr*vide) The #i+ple#t !ay t* reu#e a cla## i# t* 4u#t u#e an *34ect *9 that cla## directly, 3ut y*u can al#* place an *34ect *9 that cla## in#ide a ne! cla##) ,e call thi# Icreating a +e+3er *34ect)J :*ur ne! cla## can 3e +ade up *9 any nu+3er and type *9 *ther *34ect#, in any c*+3inati*n that y*u need t* achieve the 9uncti*nality de#ired in y*ur ne! cla##) Becau#e y*u are c*+p*#ing a ne! cla## 9r*+ e;i#ting cla##e#, thi# c*ncept i# called com"osition G*r +*re generally, aggregationH) C*+p*#iti*n i# *9ten re9erred t* a# a Iha#EaJ relati*n#hip, a# in Ia car ha# an engine)J
Car % n g in e

GThe a3*ve UAL diagra+ indicate# c*+p*#iti*n !ith the 9illed dia+*nd, !hich #tate# there i# *ne car) - !ill typically u#e a #i+pler 9*r+1 4u#t a line, !ith*ut the dia+*nd, t* indicate an a##*ciati*n)&H C*+p*#iti*n c*+e# !ith a great deal *9 9le;i3ility) The +e+3er *34ect# *9 y*ur ne! cla## are u#ually private, +aking the+ inacce##i3le t* the client pr*gra++er# !h* are u#ing the cla##) Thi# all*!# y*u t* change th*#e +e+3er# !ith*ut di#tur3ing e;i#ting client c*de) :*u can al#* change the +e+3er *34ect# at runEti+e, t* dyna+ically change the 3ehavi*r *9 y*ur pr*gra+) -nheritance, !hich i# de#cri3ed ne;t, d*e# n*t have thi# 9le;i3ility #ince the c*+piler +u#t place c*+pileEti+e re#tricti*n# *n cla##e# created !ith inheritance) Becau#e inheritance i# #* i+p*rtant in *34ectE*riented pr*gra++ing it i# *9ten highly e+pha#i7ed, and the ne! pr*gra++er can get the idea that inheritance #h*uld 3e u#ed every!here) Thi# can re#ult in a!k!ard and *verly c*+plicated de#ign#) -n#tead, y*u #h*uld 9ir#t l**k t* c*+p*#iti*n !hen creating ne! cla##e#, #ince it i# #i+pler and +*re 9le;i3le) -9 y*u take thi# appr*ach, y*ur de#ign# !ill 3e cleaner) Once y*uve had #*+e e;perience, it !ill 3e rea#*na3ly *3vi*u# !hen y*u need inheritance)

& Thi# i# u#ually en*ugh detail 9*r +*#t diagra+#, and y*u d*nt need t* get #peci9ic a3*ut

!hether y*ure u#ing aggregati*n *r c*+p*#iti*n)

)4

Thinking in C

www.ThinkingIn.!et

Inheritance, reusing the inter0ace


By it#el9, the idea *9 an *34ect i# a c*nvenient t**l) -t all*!# y*u t* package data and 9uncti*nality t*gether 3y conce"t, #* y*u can repre#ent an appr*priate pr*3le+E#pace idea rather than 3eing 9*rced t* u#e the idi*+# *9 the underlying +achine) The#e c*ncept# are e;pre##ed a# 9unda+ental unit# in the pr*gra++ing language 3y u#ing the class key!*rd) -t #ee+# a pity, h*!ever, t* g* t* all the tr*u3le t* create a cla## and then 3e 9*rced t* create a 3rand ne! *ne that +ight have #i+ilar 9uncti*nality) -t# nicer i9 !e can take the e;i#ting cla##, cl*ne it, and then +ake additi*n# and +*di9icati*n# t* the cl*ne) Thi# i# e99ectively !hat y*u get !ith inheritance, !ith the e;cepti*n that i9 the *riginal cla## Gcalled the 2ase *r su"er *r "arent cla##H i# changed, the +*di9ied Icl*neJ Gcalled the deri-ed *r inherited *r su2 *r child cla##H al#* re9lect# th*#e change#)
3 ase

4 e riv e d

GThe arr*! in the a3*ve UAL diagra+ p*int# 9r*+ the derived cla## t* the 3a#e cla##) =# y*u !ill #ee, there can 3e +*re than *ne derived cla##)H = type d*e# +*re than de#cri3e the c*n#traint# *n a #et *9 *34ect#Q it al#* ha# a relati*n#hip !ith *ther type#) T!* type# can have characteri#tic# and 3ehavi*r# in c*++*n, 3ut *ne type +ay c*ntain +*re characteri#tic# than an*ther and +ay al#* handle +*re +e##age# G*r handle the+ di99erentlyH) -nheritance e;pre##e# thi# #i+ilarity 3et!een type# u#ing the c*ncept *9 3a#e type# and derived type#) = 3a#e type c*ntain# all *9 the characteri#tic# and 3ehavi*r# that are #hared a+*ng the type# derived 9r*+ it) :*u create a 3a#e type t* repre#ent the c*re *9 y*ur idea# a3*ut

Cha"ter 1* Introduction to 123ects

)5

#*+e *34ect# in y*ur #y#te+) 5r*+ the 3a#e type, y*u derive *ther type# t* e;pre## the di99erent !ay# that thi# c*re can 3e reali7ed) 5*r e;a+ple, a tra#hErecycling +achine #*rt# piece# *9 tra#h) The 3a#e type i# Itra#h,J and each piece *9 tra#h ha# a !eight, a value, and #* *n, and can 3e #hredded, +elted, *r dec*+p*#ed) 5r*+ thi#, +*re #peci9ic type# *9 tra#h are derived that +ay have additi*nal characteri#tic# Ga 3*ttle ha# a c*l*rH *r 3ehavi*r# Gan alu+inu+ can +ay 3e cru#hed, a #teel can i# +agneticH) -n additi*n, #*+e 3ehavi*r# +ay 3e di99erent Gthe value *9 paper depend# *n it# type and c*nditi*nH) U#ing inheritance, y*u can 3uild a type hierarchy that e;pre##e# the pr*3le+ y*ure trying t* #*lve in ter+# *9 it# type#) = #ec*nd e;a+ple i# the cla##ic I#hapeJ e;a+ple, perhap# u#ed in a c*+puterEaided de#ign #y#te+ *r ga+e #i+ulati*n) The 3a#e type i# I#hape,J and each #hape ha# a #i7e, a c*l*r, a p*#iti*n, and #* *n) Each #hape can 3e dra!n, era#ed, +*ved, c*l*red, etc) 5r*+ thi#, #peci9ic type# *9 #hape# are derived GinheritedH1 circle, #Duare, triangle, and #* *n, each *9 !hich +ay have additi*nal characteri#tic# and 3ehavi*r#) Certain #hape# can 3e 9lipped, 9*r e;a+ple) S*+e 3ehavi*r# +ay 3e di99erent, #uch a# !hen y*u !ant t* calculate the area *9 a #hape) The type hierarchy e+3*die# 3*th the #i+ilaritie# and di99erence# 3et!een the #hape#)

Shape d ra w 12 e ra se 12 # ove12 g e tC o lo r 1 2 s e t C o lo r 1 2

C ir c le

S q u a re

T r ia n g le

)6

Thinking in C

www.ThinkingIn.!et

Ca#ting the #*luti*n in the #a+e ter+# a# the pr*3le+ i# tre+end*u#ly 3ene9icial 3ecau#e y*u d*nt need a l*t *9 inter+ediate +*del# t* get 9r*+ a de#cripti*n *9 the pr*3le+ t* a de#cripti*n *9 the #*luti*n) ,ith *34ect#, the type hierarchy i# the pri+ary +*del, #* y*u g* directly 9r*+ the de#cripti*n *9 the #y#te+ in the real !*rld t* the de#cripti*n *9 the #y#te+ in c*de) -ndeed, *ne *9 the di99icultie# pe*ple have !ith *34ectE*riented de#ign i# that it# t** #i+ple t* get 9r*+ the 3eginning t* the end) = +ind trained t* l**k 9*r c*+ple; #*luti*n# i# *9ten #tu+ped 3y thi# #i+plicity at 9ir#t) ,hen y*u inherit 9r*+ an e;i#ting type, y*u create a ne! type) Thi# ne! type c*ntain# n*t *nly all the +e+3er# *9 the e;i#ting type Galth*ugh the private *ne# are hidden a!ay and inacce##i3leH, 3ut +*re i+p*rtant, it duplicate# the inter9ace *9 the 3a#e cla##) That i#, all the +e##age# y*u can #end t* *34ect# *9 the 3a#e cla## y*u can al#* #end t* *34ect# *9 the derived cla##) Since !e kn*! the type *9 a cla## 3y the +e##age# !e can #end t* it, thi# +ean# that the derived cla## is the same t4"e as the 2ase class) -n the previ*u# e;a+ple, Ia circle i# a #hape)J Thi# type eDuivalence via inheritance i# *ne *9 the 9unda+ental gate!ay# in under#tanding the +eaning *9 *34ectE*riented pr*gra++ing) Since 3*th the 3a#e cla## and derived cla## have the #a+e inter9ace, there +u#t 3e #*+e i+ple+entati*n t* g* al*ng !ith that inter9ace) That i#, there +u#t 3e #*+e c*de t* e;ecute !hen an *34ect receive# a particular +e##age) -9 y*u #i+ply inherit a cla## and d*nt d* anything el#e, the +eth*d# 9r*+ the 3a#eEcla## inter9ace c*+e right al*ng int* the derived cla##) That +ean# *34ect# *9 the derived cla## have n*t *nly the #a+e type, they al#* have the #a+e 3ehavi*r, !hich i#nt particularly intere#ting) :*u have t!* !ay# t* di99erentiate y*ur ne! derived cla## 9r*+ the *riginal 3a#e cla##) The 9ir#t i# Duite #traight9*r!ard1 :*u #i+ply add 3rand ne! 9uncti*n# t* the derived cla##) The#e ne! 9uncti*n# are n*t part *9 the 3a#e cla## inter9ace) Thi# +ean# that the 3a#e cla## #i+ply didnt d* a# +uch a# y*u !anted it t*, #* y*u added +*re 9uncti*n#) Thi# #i+ple and pri+itive u#e 9*r inheritance i#, at ti+e#, the per9ect #*luti*n t* y*ur pr*3le+) H*!ever, y*u #h*uld l**k cl*#ely 9*r the p*##i3ility that y*ur 3a#e cla## +ight al#* need the#e additi*nal 9uncti*n#) Thi# pr*ce## *9 di#c*very and iterati*n *9 y*ur de#ign happen# regularly in *34ectE *riented pr*gra++ing)

Cha"ter 1* Introduction to 123ects

)#

Shape d ra w 12 e ra s e 12 # ove12 g e t C o lo r1 2 s e t C o lo r 1 2

C ir c le

S q u a re

T r ia n g le 7 li$ 8 e r t ic a l1 2 7 li$ 9 o r i: o n t a l1 2

=lth*ugh inheritance +ay #*+eti+e# i+ply Ge#pecially in "ava, !here the key!*rd that indicate# inheritance i# extendsH that y*u are g*ing t* add ne! 9uncti*n# t* the inter9ace, that# n*t nece##arily true) The #ec*nd and +*re i+p*rtant !ay t* di99erentiate y*ur ne! cla## i# t* change the 3ehavi*r *9 an e;i#ting 3a#eEcla## 9uncti*n) Thi# i# re9erred t* a# o-erriding that 9uncti*n)

)&

Thinking in C

www.ThinkingIn.!et

Shape d ra w 12 e ra se 12 # ove12 g e tC o lo r 1 2 s e tC o lo r 1 2

C ir c le d ra w 12 e ra se 12

S q u a re d ra w 12 e ra se 12

T r ia n g le d ra w 12 e ra se 12

T* *verride a 9uncti*n, y*u #i+ply create a ne! de9initi*n 9*r the 9uncti*n in the derived cla##) :*ure #aying, I-+ u#ing the #a+e inter9ace 9uncti*n here, 3ut - !ant it t* d* #*+ething di99erent 9*r +y ne! type)J

Is;a vs. is;li*e;a relationshi$s


There# a certain de3ate that can *ccur a3*ut inheritance1 Sh*uld inheritance *verride onl4 3a#eEcla## 9uncti*n# Gand n*t add ne! +e+3er 9uncti*n# that arent in the 3a#e cla##HF Thi# !*uld +ean that the derived type i# e%actl4 the #a+e type a# the 3a#e cla## #ince it ha# e;actly the #a+e inter9ace) =# a re#ult, y*u can e;actly #u3#titute an *34ect *9 the derived cla## 9*r an *34ect *9 the 3a#e cla##) Thi# can 3e th*ught *9 a# "ure su2stitution, and it# *9ten re9erred t* a# the su2stitution "rinci"le) -n a #en#e, thi# i# the ideal !ay t* treat inheritance) ,e *9ten re9er t* the relati*n#hip 3et!een the 3a#e cla## and derived cla##e# in thi# ca#e a# an is9a relati*n#hip, 3ecau#e y*u can #ay Ia circle is a #hape)J = te#t 9*r inheritance i# t* deter+ine !hether y*u can #tate the i#Ea relati*n#hip a3*ut the cla##e# and have it +ake #en#e) There are ti+e# !hen y*u +u#t add ne! inter9ace ele+ent# t* a derived type, thu# e;tending the inter9ace and creating a ne! type) The ne! type can #till 3e #u3#tituted 9*r the 3a#e type, 3ut the #u3#tituti*n i#nt per9ect

Cha"ter 1* Introduction to 123ects

)'

3ecau#e y*ur ne! 9uncti*n# are n*t acce##i3le 9r*+ the 3a#e type) Thi# can 3e de#cri3ed a# an is9like9a' relati*n#hipQ the ne! type ha# the inter9ace *9 the *ld type 3ut it al#* c*ntain# *ther 9uncti*n#, #* y*u cant really #ay it# e;actly the #a+e) 5*r e;a+ple, c*n#ider an air c*nditi*ner) Supp*#e y*ur h*u#e i# !ired !ith all the c*ntr*l# 9*r c**lingQ that i#, it ha# an inter9ace that all*!# y*u t* c*ntr*l c**ling) -+agine that the air c*nditi*ner 3reak# d*!n and y*u replace it !ith a heat pu+p, !hich can 3*th heat and c**l) The heat pu+p is9like9an air c*nditi*ner, 3ut it can d* +*re) Becau#e the c*ntr*l #y#te+ *9 y*ur h*u#e i# de#igned *nly t* c*ntr*l c**ling, it i# re#tricted t* c*++unicati*n !ith the c**ling part *9 the ne! *34ect) The inter9ace *9 the ne! *34ect ha# 3een e;tended, and the e;i#ting #y#te+ d*e#nt kn*! a3*ut anything e;cept the *riginal inter9ace)

T h e rm o s ta t lo w e r - e # $ e r a t u r e 1 2

C o n t r o ls

C o o lin g S y s t e m c o o l1 2

A ir C o n d it io n e r c o o l1 2

eat !um p c o o l1 2 h e a t12

O9 c*ur#e, *nce y*u #ee thi# de#ign it 3ec*+e# clear that the 3a#e cla## Ic**ling #y#te+J i# n*t general en*ugh, and #h*uld 3e rena+ed t* Ite+perature c*ntr*l #y#te+J #* that it can al#* include heatingRat !hich p*int the #u3#tituti*n principle !ill !*rk) H*!ever, the diagra+ a3*ve i# an e;a+ple *9 !hat can happen in de#ign and in the real !*rld) ,hen y*u #ee the #u3#tituti*n principle it# ea#y t* 9eel like thi# appr*ach Gpure #u3#tituti*nH i# the *nly !ay t* d* thing#, and in 9act it is nice i9 y*ur de#ign !*rk# *ut that !ay) But y*ull 9ind that there are ti+e# !hen it# eDually clear that y*u +u#t add ne! 9uncti*n# t* the inter9ace *9 a derived cla##) ,ith in#pecti*n 3*th ca#e# #h*uld 3e rea#*na3ly *3vi*u#)
' Ay ter+)

3(

Thinking in C

www.ThinkingIn.!et

Interchangea+le o+/ects with $ol5#or$his#


,hen dealing !ith type hierarchie#, y*u *9ten !ant t* treat an *34ect n*t a# the #peci9ic type that it i#, 3ut in#tead a# it# 3a#e type) Thi# all*!# y*u t* !rite c*de that d*e#nt depend *n #peci9ic type#) -n the #hape e;a+ple, 9uncti*n# +anipulate generic #hape# !ith*ut re#pect t* !hether theyre circle#, #Duare#, triangle#, *r #*+e #hape that ha#nt even 3een de9ined yet) =ll #hape# can 3e dra!n, era#ed, and +*ved, #* the#e 9uncti*n# #i+ply #end a +e##age t* a #hape *34ectQ they d*nt !*rry a3*ut h*! the *34ect c*pe# !ith the +e##age) Such c*de i# una99ected 3y the additi*n *9 ne! type#, and adding ne! type# i# the +*#t c*++*n !ay t* e;tend an *34ectE*riented pr*gra+ t* handle ne! #ituati*n#) 5*r e;a+ple, y*u can derive a ne! #u3type *9 #hape called pentag*n !ith*ut +*di9ying the 9uncti*n# that deal *nly !ith generic #hape#) Thi# a3ility t* e;tend a pr*gra+ ea#ily 3y deriving ne! #u3type# i# i+p*rtant 3ecau#e it greatly i+pr*ve# de#ign# !hile reducing the c*#t *9 #*9t!are +aintenance) There# a pr*3le+, h*!ever, !ith atte+pting t* treat derivedEtype *34ect# a# their generic 3a#e type# Gcircle# a# #hape#, 3icycle# a# vehicle#, c*r+*rant# a# 3ird#, etc)H) -9 a 9uncti*n i# g*ing t* tell a generic #hape t* dra! it#el9, *r a generic vehicle t* #teer, *r a generic 3ird t* +*ve, the c*+piler cann*t kn*! at c*+pileEti+e preci#ely !hat piece *9 c*de !ill 3e e;ecuted) That# the !h*le p*intR!hen the +e##age i# #ent, the pr*gra++er d*e#nt want t* kn*! !hat piece *9 c*de !ill 3e e;ecutedQ the dra! 9uncti*n can 3e applied eDually t* a circle, a #Duare, *r a triangle, and the *34ect !ill e;ecute the pr*per c*de depending *n it# #peci9ic type) -9 y*u d*nt have t* kn*! !hat piece *9 c*de !ill 3e e;ecuted, then !hen y*u add a ne! #u3type, the c*de it e;ecute# can 3e di99erent !ith*ut reDuiring change# t* the 9uncti*n call) There9*re, the c*+piler cann*t kn*! preci#ely !hat piece *9 c*de i# e;ecuted, #* !hat d*e# it d*F 5*r e;a+ple, in the 9*ll*!ing diagra+ the BirdController *34ect 4u#t !*rk# !ith generic Bird *34ect#, and d*e# n*t kn*! !hat e;act type they are) Thi# i# c*nvenient 9r*+ BirdController# per#pective 3ecau#e it d*e#nt have t* !rite #pecial c*de t* deter+ine the e;act type *9 Bird it# !*rking

Cha"ter 1* Introduction to 123ects

31

!ith, *r that Bird# 3ehavi*r) S* h*! d*e# it happen that, !hen move( ) i# called !hile ign*ring the #peci9ic type *9 Bird, the right 3ehavi*r !ill *ccur Ga oose run#, 9lie#, *r #!i+#, and a !enguin run# *r #!i+#HF
" ir d C o n t r o lle r re L o ca te 12 W hat ha$$ens w h e n # o v e 1 2 is c a lle d < " ir d # o v e 12

# oose # ove12

! e n g u in # ove12

The an#!er i# the pri+ary t!i#t in *34ectE*riented pr*gra++ing1 the c*+piler cann*t +ake a 9uncti*n call in the traditi*nal #en#e) The 9uncti*n call generated 3y a n*nEOOP c*+piler cau#e# !hat i# called earl4 2inding, a ter+ y*u +ay n*t have heard 3e9*re 3ecau#e y*uve never th*ught a3*ut it any *ther !ay) -t +ean# the c*+piler generate# a call t* a #peci9ic 9uncti*n na+e, and the linker re#*lve# thi# call t* the a3#*lute addre## *9 the c*de t* 3e e;ecuted) -n OOP, the pr*gra+ cann*t deter+ine the addre## *9 the c*de until runEti+e, #* #*+e *ther #che+e i# nece##ary !hen a +e##age i# #ent t* a generic *34ect) T* #*lve the pr*3le+, *34ectE*riented language# u#e the c*ncept *9 late 2inding) ,hen y*u #end a +e##age t* an *34ect, the c*de 3eing called i#nt deter+ined until runEti+e) The c*+piler d*e# en#ure that the 9uncti*n e;i#t# and per9*r+# type checking *n the argu+ent# and return value Ga language in !hich thi# i#nt true i# called weakl4 t4"edH, 3ut it d*e#nt kn*! the e;act c*de t* e;ecute) T* per9*r+ late 3inding, C# u#e# a #pecial 3it *9 c*de in lieu *9 the a3#*lute call) Thi# c*de calculate# the addre## *9 the 9uncti*n 3*dy, u#ing in9*r+ati*n #t*red in the *34ect Gthi# pr*ce## i# c*vered in great detail in Chapter %H) Thu#, each *34ect can 3ehave di99erently acc*rding t* the c*ntent# *9 that #pecial 3it *9 c*de) ,hen y*u #end a +e##age t* an *34ect, the *34ect actually d*e# 9igure *ut !hat t* d* !ith that +e##age)

3)

Thinking in C

www.ThinkingIn.!et

-n C#, y*u can ch**#e !hether a language i# earlyE *r lateE3*und) By de9ault, they are earlyE3*und) T* take advantage *9 p*ly+*rphi#+, +eth*d# +u#t 3e de9ined in the 3a#e cla## u#ing the virtual key!*rd and i+ple+ented in inheriting cla##e# !ith the override key!*rd) C*n#ider the #hape e;a+ple) The 9a+ily *9 cla##e# Gall 3a#ed *n the #a+e uni9*r+ inter9aceH !a# diagra++ed earlier in thi# chapter) T* de+*n#trate p*ly+*rphi#+, !e !ant t* !rite a #ingle piece *9 c*de that ign*re# the #peci9ic detail# *9 type and talk# *nly t* the 3a#e cla##) That c*de i# decou"led 9r*+ typeE#peci9ic in9*r+ati*n, and thu# i# #i+pler t* !rite and ea#ier t* under#tand) =nd, i9 a ne! typeRa "exagon, 9*r e;a+pleRi# added thr*ugh inheritance, the c*de y*u !rite !ill !*rk 4u#t a# !ell 9*r the ne! type *9 #hape a# it did *n the e;i#ting type#) Thu#, the pr*gra+ i# e%tensi2le) -9 y*u !rite a +eth*d in C# Ga# y*u !ill #**n learn h*! t* d*H1 *oid :oStuff0Shape #1 ; #.+ra#e013 // ... #.:ra.013 < Thi# 9uncti*n #peak# t* any #hape, #* it i# independent *9 the #peci9ic type *9 *34ect that it# dra!ing and era#ing) -9 in #*+e *ther part *9 the pr*gra+ !e u#e the $o#tuff( ) 9uncti*n1 Circ e c 9 ne. Circ e013 'riang e t 9 ne. 'riang e013 Line 9 ne. Line013 :oStuff0c13 :oStuff0t13 :oStuff0 13 The call# t* $o#tuff( ) aut*+atically !*rk c*rrectly, regardle## *9 the e;act type *9 the *34ect) Thi# i# actually a pretty a+a7ing trick) C*n#ider the line1 :oStuff0c13

Cha"ter 1* Introduction to 123ects

33

,hat# happening here i# that a Circle i# 3eing pa##ed int* a 9uncti*n that# e;pecting a #hape) Since a Circle is a #hape it can 3e treated a# *ne 3y $o#tuff( )) That i#, any +e##age that $o#tuff( ) can #end t* a #hape, a Circle can accept) S* it i# a c*+pletely #a9e and l*gical thing t* d*) ,e call thi# pr*ce## *9 treating a derived type a# th*ugh it !ere it# 3a#e type u"casting) The na+e cast i# u#ed in the #en#e *9 ca#ting int* a +*ld and the u" c*+e# 9r*+ the !ay the inheritance diagra+ i# typically arranged, !ith the 3a#e type at the t*p and the derived cla##e# 9anning *ut d*!n!ard) Thu#, ca#ting t* a 3a#e type i# +*ving up the inheritance diagra+1 Iupca#ting)J
Shape

= > $ c a s t in g =

C ir c le

S q u a re

T r ia n g le

=n *34ectE*riented pr*gra+ c*ntain# #*+e upca#ting #*+e!here, 3ecau#e that# h*! y*u dec*uple y*ur#el9 9r*+ kn*!ing a3*ut the e;act type y*ure !*rking !ith) L**k at the c*de in $o#tuff( )1 #.+ra#e013 // ... #.:ra.013 *tice that it d*e#nt #ay I-9 y*ure a Circle, d* thi#, i9 y*ure a #%uare, d* that, etc)J -9 y*u !rite that kind *9 c*de, !hich check# 9*r all the p*##i3le type# that a #hape can actually 3e, it# +e##y and y*u need t* change it every ti+e y*u add a ne! kind *9 #hape) Here, y*u 4u#t #ay I:*ure a #hape, - kn*! y*u can &rase( ) and $raw( ) y*ur#el9, d* it, and take care *9 the detail# c*rrectly)J ,hat# i+pre##ive a3*ut the c*de in $o#tuff( ) i# that, #*+eh*!, the right thing happen#) Calling $raw( ) 9*r Circle cau#e# di99erent c*de t*

34

Thinking in C

www.ThinkingIn.!et

3e e;ecuted than !hen calling $raw( ) 9*r a #%uare *r a Line, 3ut !hen the $raw( ) +e##age i# #ent t* an an*ny+*u# #hape, the c*rrect 3ehavi*r *ccur# 3a#ed *n the actual type *9 the #hape) Thi# i# a+a7ing 3ecau#e, a# +enti*ned earlier, !hen the C# c*+piler i# c*+piling the c*de 9*r $o#tuff( ), it cann*t kn*! e;actly !hat type# it i# dealing !ith) S* *rdinarily, y*ud e;pect it t* end up calling the ver#i*n *9 &rase( ) and $raw( ) 9*r the 3a#e cla## #hape, and n*t 9*r the #peci9ic Circle, #%uare, *r Line) =nd yet the right thing happen# 3ecau#e *9 p*ly+*rphi#+) The c*+piler and runEti+e #y#te+ handle the detail#Q all y*u need t* kn*! i# that it happen#, and +*re i+p*rtant h*! t* de#ign !ith it) ,hen y*u #end a +e##age t* an *34ect, the *34ect !ill d* the right thing, even !hen upca#ting i# inv*lved)

)+stract +ase classes and inter0aces


O9ten in a de#ign, y*u !ant the 3a#e cla## t* pre#ent onl4 an inter9ace 9*r it# derived cla##e#) That i#, y*u d*nt !ant any*ne t* actually create an *34ect *9 the 3a#e cla##, *nly t* upca#t t* it #* that it# inter9ace can 3e u#ed) Thi# i# acc*+pli#hed 3y +aking that cla## a2stract u#ing the abstract key!*rd) -9 any*ne trie# t* +ake an *34ect *9 an abstract cla##, the c*+piler prevent# the+) Thi# i# a t**l t* en9*rce a particular de#ign) :*u can al#* u#e the abstract key!*rd t* de#cri3e a +eth*d that ha#nt 3een i+ple+ented yetRa# a #tu3 indicating Ihere i# an inter9ace 9uncti*n 9*r all type# inherited 9r*+ thi# cla##, 3ut at thi# p*int - d*nt have any i+ple+entati*n 9*r it)J =n abstract +eth*d +ay 3e created *nly in#ide an abstract cla##) ,hen the cla## i# inherited, that +eth*d +u#t 3e i+ple+ented, *r the inheriting cla## 3ec*+e# abstract a# !ell) Creating an abstract +eth*d all*!# y*u t* put a +eth*d in an inter9ace !ith*ut 3eing 9*rced t* pr*vide a p*##i3ly +eaningle## 3*dy *9 c*de 9*r that +eth*d) The interface key!*rd take# the c*ncept *9 an abstract cla## *ne #tep 9urther 3y preventing any 9uncti*n de9initi*n# at all) The interface i# a very handy and c*++*nly u#ed t**l, a# it pr*vide# the per9ect #eparati*n *9 inter9ace and i+ple+entati*n) -n additi*n, y*u can c*+3ine +any

Cha"ter 1* Introduction to 123ects

35

inter9ace# t*gether, i9 y*u !i#h, !herea# inheriting 9r*+ +ultiple regular cla##e# *r a3#tract cla##e# i# n*t p*##i3le)

O+/ect landsca$es and li0eti#es


Technically, OOP i# 4u#t a3*ut a3#tract data typing, inheritance, and p*ly+*rphi#+, 3ut *ther i##ue# can 3e at lea#t a# i+p*rtant) The re+ainder *9 thi# #ecti*n !ill c*ver the#e i##ue#) One *9 the +*#t i+p*rtant 9act*r# i# the !ay *34ect# are created and de#tr*yed) ,here i# the data 9*r an *34ect and h*! i# the li9eti+e *9 the *34ect c*ntr*lledF There are di99erent phil*#*phie# at !*rk here) C@@ take# the appr*ach that c*ntr*l *9 e99iciency i# the +*#t i+p*rtant i##ue, #* it give# the pr*gra++er a ch*ice) 5*r +a;i+u+ runEti+e #peed, the #t*rage and li9eti+e can 3e deter+ined !hile the pr*gra+ i# 3eing !ritten, 3y placing the *34ect# *n the #tack Gthe#e are #*+eti+e# called automatic *r sco"ed varia3le#H *r in the #tatic #t*rage area) Thi# place# a pri*rity *n the #peed *9 #t*rage all*cati*n and relea#e, and c*ntr*l *9 the#e can 3e very valua3le in #*+e #ituati*n#) H*!ever, y*u #acri9ice 9le;i3ility 3ecau#e y*u +u#t kn*! the e;act Duantity, li9eti+e, and type *9 *34ect# !hile y*uSre !riting the pr*gra+) -9 y*u are trying t* #*lve a +*re general pr*3le+ #uch a# c*+puterEaided de#ign, !areh*u#e +anage+ent, *r airEtra99ic c*ntr*l, thi# i# t** re#trictive) The #ec*nd appr*ach i# t* create *34ect# dyna+ically in a p**l *9 +e+*ry called the heap) -n thi# appr*ach, y*u d*nSt kn*! until runEti+e h*! +any *34ect# y*u need, !hat their li9eti+e i#, *r !hat their e;act type i#) Th*#e are deter+ined at the #pur *9 the +*+ent !hile the pr*gra+ i# running) -9 y*u need a ne! *34ect, y*u #i+ply +ake it *n the heap at the p*int that y*u need it) Becau#e the #t*rage i# +anaged dyna+ically, at runEti+e, the a+*unt *9 ti+e reDuired t* all*cate #t*rage *n the heap i# #igni9icantly l*nger than the ti+e t* create #t*rage *n the #tack) GCreating #t*rage *n the #tack i# *9ten a #ingle a##e+3ly in#tructi*n t* +*ve the #tack p*inter d*!n, and an*ther t* +*ve it 3ack up)H The dyna+ic appr*ach +ake# the generally l*gical a##u+pti*n that *34ect# tend t* 3e c*+plicated, #* the e;tra *verhead *9 9inding #t*rage and relea#ing that

36

Thinking in C

www.ThinkingIn.!et

#t*rage !ill n*t have an i+p*rtant i+pact *n the creati*n *9 an *34ect) -n additi*n, the greater 9le;i3ility i# e##ential t* #*lve the general pr*gra++ing pr*3le+) C# u#e# the #ec*nd appr*ach e;clu#ively, e;cept 9*r -alue t4"es !hich !ill 3e di#cu##ed #h*rtly) Every ti+e y*u !ant t* create an *34ect, y*u u#e the new key!*rd t* 3uild a dyna+ic in#tance *9 that *34ect) ,ith language# that all*! *34ect# t* 3e created *n the #tack, the c*+piler deter+ine# h*! l*ng the *34ect la#t# and can aut*+atically de#tr*y it) H*!ever, i9 y*u create it *n the heap the c*+piler ha# n* kn*!ledge *9 it# li9eti+e) -n a language like C@@, y*u +u#t deter+ine pr*gra++atically !hen t* de#tr*y the *34ect, !hich can lead t* +e+*ry leak# i9 y*u d*nt d* it c*rrectly Gand thi# i# a c*++*n pr*3le+ in C@@ pr*gra+#H) The ) ET runti+e pr*vide# a 9eature called a gar3age c*llect*r that aut*+atically di#c*ver# !hen an *34ect i# n* l*nger in u#e and de#tr*y# it) = gar3age c*llect*r i# +uch +*re c*nvenient 3ecau#e it reduce# the nu+3er *9 i##ue# that y*u +u#t track and the c*de y*u +u#t !rite) A*re i+p*rtant, the gar3age c*llect*r pr*vide# a +uch higher level *9 in#urance again#t the in#idi*u# pr*3le+ *9 +e+*ry leak# G!hich ha# 3r*ught +any a C@@ pr*4ect t* it# knee#H) The re#t *9 thi# #ecti*n l**k# at additi*nal 9act*r# c*ncerning *34ect li9eti+e# and land#cape#)

Collections and iterators


-9 y*u d*nt kn*! h*! +any *34ect# y*ure g*ing t* need t* #*lve a particular pr*3le+, *r h*! l*ng they !ill la#t, y*u al#* d*nt kn*! h*! t* #t*re th*#e *34ect#) H*! can y*u kn*! h*! +uch #pace t* create 9*r th*#e *34ect#F :*u cant, #ince that in9*r+ati*n i#nt kn*!n until runE ti+e) The #*luti*n t* +*#t pr*3le+# in *34ectE*riented de#ign #ee+# 9lippant1 y*u create an*ther type *9 *34ect) The ne! type *9 *34ect that #*lve# thi# particular pr*3le+ h*ld# re9erence# t* *ther *34ect#) O9 c*ur#e, y*u can d* the #a+e thing !ith an array, !hich i# availa3le in +*#t language#) But there# +*re) Thi# ne! *34ect, generally called a container Gal#* called a collectionH, !ill e;pand it#el9 !henever nece##ary t* acc*++*date everything y*u place in#ide it) S* y*u d*nt need t* kn*! h*! +any

Cha"ter 1* Introduction to 123ects

3#

*34ect# y*ure g*ing t* h*ld in a c*ntainer) "u#t create a c*ntainer *34ect and let it take care *9 the detail#) 5*rtunately, a g**d OOP language c*+e# !ith a #et *9 c*ntainer# a# part *9 the package) -n C@@, it# part *9 the Standard C@@ Li3rary and i# #*+eti+e# called the Standard Te+plate Li3rary GSTLH) O34ect Pa#cal ha# c*ntainer# in it# Ci#ual C*+p*nent Li3rary GCCLH) S+alltalk ha# a very c*+plete #et *9 c*ntainer#) C# al#* ha# c*ntainer# in it# #tandard li3rary) -n #*+e li3rarie#, a generic c*ntainer i# c*n#idered g**d en*ugh 9*r all need#, and in *ther# GC#, 9*r e;a+pleH the li3rary ha# di99erent type# *9 c*ntainer# 9*r di99erent need#1 a vect*r Gcalled an 'rrayList in C#H 9*r c*n#i#tent acce## t* all ele+ent#, Dueue#, ha#hta3le#, tree#, #tack#, etc) =ll c*ntainer# have #*+e !ay t* put thing# in and get thing# *utQ there are u#ually 9uncti*n# t* add ele+ent# t* a c*ntainer, and *ther# t* 9etch th*#e ele+ent# 3ack *ut) But 9etching ele+ent# can 3e +*re pr*3le+atic, 3ecau#e a #ingleE#electi*n 9uncti*n i# re#trictive) ,hat i9 y*u !ant t* +anipulate *r c*+pare a #et *9 ele+ent# in the c*ntainer in#tead *9 4u#t *neF The #*luti*n i# an iterat*r, !hich i# an *34ect !h*#e 4*3 i# t* #elect the ele+ent# !ithin a c*ntainer and pre#ent the+ t* the u#er *9 the iterat*r) =# a cla##, it al#* pr*vide# a level *9 a3#tracti*n) Thi# a3#tracti*n can 3e u#ed t* #eparate the detail# *9 the c*ntainer 9r*+ the c*de that# acce##ing that c*ntainer) The c*ntainer, via the iterat*r, i# a3#tracted t* 3e #i+ply a #eDuence) The iterat*r all*!# y*u t* traver#e that #eDuence !ith*ut !*rrying a3*ut the underlying #tructureRthat i#, !hether it# an 'rrayList, a "ashtable, a #tac(, *r #*+ething el#e) Thi# give# y*u the 9le;i3ility t* ea#ily change the underlying data #tructure !ith*ut di#tur3ing the c*de in y*ur pr*gra+) 5r*+ a de#ign #tandp*int, all y*u really !ant i# a #eDuence that can 3e +anipulated t* #*lve y*ur pr*3le+) -9 a #ingle type *9 #eDuence #ati#9ied all *9 y*ur need#, thered 3e n* rea#*n t* have di99erent kind#) There are t!* rea#*n# that y*u need a ch*ice *9 c*ntainer#) 5ir#t, c*ntainer# pr*vide di99erent type# *9 inter9ace# and e;ternal 3ehavi*r) = #tack ha# a di99erent inter9ace and 3ehavi*r than that *9 a Dueue, !hich i# di99erent 9r*+ that *9 a dicti*nary *r a li#t) One *9 the#e +ight pr*vide a +*re 9le;i3le #*luti*n t* y*ur pr*3le+ than the *ther) Sec*nd, di99erent c*ntainer# have

3&

Thinking in C

www.ThinkingIn.!et

di99erent e99iciencie# 9*r certain *perati*n#) But in the end, re+e+3er that a c*ntainer i# *nly a #t*rage ca3inet t* put *34ect# in) -9 that ca3inet #*lve# all *9 y*ur need#, it d*e#nt really +atter h*! it i# i+ple+ented Ga 3a#ic c*ncept !ith +*#t type# *9 *34ect#H)

-he singl5 rooted hierarch5


One *9 the i##ue# in OOP that ha# 3ec*+e e#pecially pr*+inent #ince the intr*ducti*n *9 C@@ i# !hether all cla##e# #h*uld ulti+ately 3e inherited 9r*+ a #ingle 3a#e cla##) -n C# Ga# !ith virtually all *ther OOP language#H the an#!er i# Iye#J and the na+e *9 thi# ulti+ate 3a#e cla## i# #i+ply ob)ect) -t turn# *ut that the 3ene9it# *9 the #ingly r**ted hierarchy are +any) =ll *34ect# in a #ingly r**ted hierarchy have an inter9ace in c*++*n, #* they are all ulti+ately the #a+e type) The alternative Gpr*vided 3y C@@H i# that y*u d*nt kn*! that everything i# the #a+e 9unda+ental type) 5r*+ a 3ack!ardEc*+pati3ility #tandp*int thi# 9it# the +*del *9 C 3etter and can 3e th*ught *9 a# le## re#trictive, 3ut !hen y*u !ant t* d* 9ullE*n *34ectE *riented pr*gra++ing y*u +u#t then 3uild y*ur *!n hierarchy t* pr*vide the #a+e c*nvenience that# 3uilt int* *ther OOP language#) =nd in any ne! cla## li3rary y*u acDuire, #*+e *ther inc*+pati3le inter9ace !ill 3e u#ed) -t reDuire# e99*rt Gand p*##i3ly +ultiple inheritanceH t* !*rk the ne! inter9ace int* y*ur de#ign) -# the e;tra I9le;i3ilityJ *9 C@@ !*rth itF -9 y*u need itRi9 y*u have a large inve#t+ent in CRit# Duite valua3le) -9 y*ure #tarting 9r*+ #cratch, *ther alternative# #uch a# C# can *9ten 3e +*re pr*ductive) =ll *34ect# in a #ingly r**ted hierarchy G#uch a# C# pr*vide#H can 3e guaranteed t* have certain 9uncti*nality) :*u kn*! y*u can per9*r+ certain 3a#ic *perati*n# *n every *34ect in y*ur #y#te+) = #ingly r**ted hierarchy, al*ng !ith creating all *34ect# *n the heap, greatly #i+pli9ie# argu+ent pa##ing G*ne *9 the +*re c*+ple; t*pic# in C@@H) = #ingly r**ted hierarchy +ake# it +uch ea#ier t* i+ple+ent a gar3age c*llect*r G!hich i# c*nveniently 3uilt int* C#H) The nece##ary #upp*rt can 3e in#talled in the 3a#e cla##, and the gar3age c*llect*r can thu# #end the appr*priate +e##age# t* every *34ect in the #y#te+) ,ith*ut a #ingly

Cha"ter 1* Introduction to 123ects

3'

r**ted hierarchy and a #y#te+ t* +anipulate an *34ect via a re9erence, it i# di99icult t* i+ple+ent a gar3age c*llect*r) Since runEti+e type in9*r+ati*n i# guaranteed t* 3e in all *34ect#, y*ull never end up !ith an *34ect !h*#e type y*u cann*t deter+ine) Thi# i# e#pecially i+p*rtant !ith #y#te+ level *perati*n#, #uch a# e;cepti*n handling, and t* all*! greater 9le;i3ility in pr*gra++ing)

Collection li+raries and su$$ort 0or eas5 collection use


Becau#e a c*ntainer i# a t**l that y*ull u#e 9reDuently, it +ake# #en#e t* have a li3rary *9 c*ntainer# that are 3uilt in a reu#a3le 9a#hi*n, #* y*u can take *ne *99 the #hel9 and plug it int* y*ur pr*gra+) ) ET pr*vide# #uch a li3rary, !hich #h*uld #ati#9y +*#t need#)

4owncasting vs. te#$lates?generics


T* +ake the#e c*ntainer# reu#a3le, they h*ld the *ne univer#al type in ) ET that !a# previ*u#ly +enti*ned1 ob)ect) The #ingly r**ted hierarchy +ean# that everything i# an ob)ect, #* a c*ntainer that h*ld# ob)ect# can h*ld anything) Thi# +ake# c*ntainer# ea#y t* reu#e) T* u#e #uch a c*ntainer, y*u #i+ply add *34ect re9erence# t* it, and later a#k 9*r the+ 3ack) But, #ince the c*ntainer h*ld# *nly ob)ect#, !hen y*u add y*ur *34ect re9erence int* the c*ntainer it i# upca#t t* ob)ect, thu# l*#ing it# identity) ,hen y*u 9etch it 3ack, y*u get an ob)ect re9erence, and n*t a re9erence t* the type that y*u put in) S* h*! d* y*u turn it 3ack int* #*+ething that ha# the u#e9ul inter9ace *9 the *34ect that y*u put int* the c*ntainerF Here, the ca#t i# u#ed again, 3ut thi# ti+e y*ure n*t ca#ting up the inheritance hierarchy t* a +*re general type, y*u ca#t d*!n the hierarchy t* a +*re #peci9ic type) Thi# +anner *9 ca#ting i# called d*!nca#ting) ,ith upca#ting, y*u kn*!, 9*r e;a+ple, that a Circle i# a type *9 #hape #* it# #a9e t* upca#t, 3ut y*u d*nt kn*! that an ob)ect i# nece##arily a Circle *r a #hape #* it# hardly #a9e t* d*!nca#t unle## y*u kn*! that# !hat y*ure dealing !ith)

4(

Thinking in C

www.ThinkingIn.!et

-t# n*t c*+pletely danger*u#, h*!ever, 3ecau#e i9 y*u d*!nca#t t* the !r*ng thing y*ull get a runEti+e err*r called an e%ce"tion6 !hich !ill 3e de#cri3ed #h*rtly) ,hen y*u 9etch *34ect re9erence# 9r*+ a c*ntainer, th*ugh, y*u +u#t have #*+e !ay t* re+e+3er e;actly !hat they are #* y*u can per9*r+ a pr*per d*!nca#t) ?*!nca#ting and the runEti+e check# reDuire e;tra ti+e 9*r the running pr*gra+, and e;tra e99*rt 9r*+ the pr*gra++er) ,*uldnt it +ake #en#e t* #*+eh*! create the c*ntainer #* that it kn*!# the type# that it h*ld#, eli+inating the need 9*r the d*!nca#t and a p*##i3le +i#takeF The #*luti*n i# para+eteri7ed type#, !hich are cla##e# that the c*+piler can aut*+atically cu#t*+i7e t* !*rk !ith particular type#) 5*r e;a+ple, !ith a para+eteri7ed c*ntainer, the c*+piler c*uld cu#t*+i7e that c*ntainer #* that it !*uld accept *nly Shape# and 9etch *nly Shape#) Para+eteri7ed type# are an i+p*rtant part *9 C@@, partly 3ecau#e C@@ ha# n* #ingly r**ted hierarchy) -n C@@, the key!*rd that i+ple+ent# para+eteri7ed type# i# Ite+plate)J ) ET currently ha# n* para+eteri7ed type# #ince it i# p*##i3le 9*r it t* get 3yRh*!ever a!k!ardlyRu#ing the #ingly r**ted hierarchy) H*!ever, there i# n* d*u3t that para+eteri7ed type# !ill 3e i+ple+ented in a 9uture ver#i*n *9 the ) ET 5ra+e!*rk)

-he house*ee$ing dile##a, who should clean u$<


Each *34ect reDuire# re#*urce# in *rder t* e;i#t, +*#t n*ta3ly +e+*ry) ,hen an *34ect i# n* l*nger needed it +u#t 3e cleaned up #* that the#e re#*urce# are relea#ed 9*r reu#e) -n #i+ple pr*gra++ing #ituati*n# the Due#ti*n *9 h*! an *34ect i# cleaned up d*e#nt #ee+ t** challenging1 y*u create the *34ect, u#e it 9*r a# l*ng a# it# needed, and then it #h*uld 3e de#tr*yed) -t# n*t hard, h*!ever, t* enc*unter #ituati*n# in !hich the #ituati*n i# +*re c*+ple;) Supp*#e, 9*r e;a+ple, y*u are de#igning a #y#te+ t* +anage air tra99ic 9*r an airp*rt) GThe #a+e +*del +ight al#* !*rk 9*r +anaging crate# in a !areh*u#e, *r a vide* rental #y#te+, *r a kennel 9*r 3*arding pet#)H =t 9ir#t it #ee+# #i+ple1 +ake a c*ntainer t* h*ld airplane#, then create a ne! airplane and place it in the c*ntainer 9*r each airplane that enter# the

Cha"ter 1* Introduction to 123ects

41

airEtra99icEc*ntr*l 7*ne) 5*r cleanup, #i+ply delete the appr*priate airplane *34ect !hen a plane leave# the 7*ne) But perhap# y*u have #*+e *ther #y#te+ t* rec*rd data a3*ut the plane#Q perhap# data that d*e#nt reDuire #uch i++ediate attenti*n a# the +ain c*ntr*ller 9uncti*n) Aay3e it# a rec*rd *9 the 9light plan# *9 all the #+all plane# that leave the airp*rt) S* y*u have a #ec*nd c*ntainer *9 #+all plane#, and !henever y*u create a plane *34ect y*u al#* put it in thi# #ec*nd c*ntainer i9 it# a #+all plane) Then #*+e 3ackgr*und pr*ce## per9*r+# *perati*n# *n the *34ect# in thi# c*ntainer during idle +*+ent#) *! the pr*3le+ i# +*re di99icult1 h*! can y*u p*##i3ly kn*! !hen t* de#tr*y the *34ect#F ,hen y*ure d*ne !ith the *34ect, #*+e *ther part *9 the #y#te+ +ight n*t 3e) Thi# #a+e pr*3le+ can ari#e in a nu+3er *9 *ther #ituati*n#, and in pr*gra++ing #y#te+# G#uch a# C@@H in !hich y*u +u#t e;plicitly delete an *34ect !hen y*ure d*ne !ith it thi# can 3ec*+e Duite c*+ple;) ,ith C#, the gar3age c*llect*r i# de#igned t* take care *9 the pr*3le+ *9 relea#ing the +e+*ry Galth*ugh thi# d*e#nt include *ther a#pect# *9 cleaning up an *34ectH) The gar3age c*llect*r Ikn*!#J !hen an *34ect i# n* l*nger in u#e, and it then aut*+atically relea#e# the +e+*ry 9*r that *34ect) Thi# Gc*+3ined !ith the 9act that all *34ect# are inherited 9r*+ the #ingle r**t cla## ob)ect and that y*u can create *34ect# *nly *ne !ay, *n the heapH +ake# the pr*ce## *9 pr*gra++ing in C# +uch #i+pler than pr*gra++ing in C@@) :*u have 9ar 9e!er deci#i*n# t* +ake and hurdle# t* *verc*+e)

Gar+age collectors vs. e00icienc5 and 0le&i+ilit5


-9 all thi# i# #uch a g**d idea, !hy didnt they d* the #a+e thing in C@@F ,ell *9 c*ur#e there# a price y*u pay 9*r all thi# pr*gra++ing c*nvenience, and that price i# runEti+e *verhead) =# +enti*ned 3e9*re, in C@@ y*u can create *34ect# *n the #tack, and in thi# ca#e theyre aut*+atically cleaned up G3ut y*u d*nt have the 9le;i3ility *9 creating a# +any a# y*u !ant at runEti+eH) Creating *34ect# *n the #tack i# the +*#t e99icient !ay t* all*cate #t*rage 9*r *34ect# and t* 9ree that #t*rage)

4)

Thinking in C

www.ThinkingIn.!et

Creating *34ect# *n the heap can 3e +uch +*re e;pen#ive) =l!ay# inheriting 9r*+ a 3a#e cla## and +aking all 9uncti*n call# p*ly+*rphic al#* e;act# a #+all t*ll) But the gar3age c*llect*r i# a particular pr*3le+ 3ecau#e y*u never Duite kn*! !hen it# g*ing t* #tart up *r h*! l*ng it !ill take) Thi# +ean# that there# an inc*n#i#tency in the rate *9 e;ecuti*n *9 a C# pr*gra+, #* y*u cant u#e it in certain #ituati*n#, #uch a# !hen the rate *9 e;ecuti*n *9 a pr*gra+ i# uni9*r+ly critical) GThe#e are generally called real ti+e pr*gra+#, alth*ugh n*t all real ti+e pr*gra++ing pr*3le+# are thi# #tringent)H The de#igner# *9 the C@@ language, trying t* !** C pr*gra++er# Gand +*#t #ucce##9ully, at thatH, did n*t !ant t* add any 9eature# t* the language that !*uld i+pact the #peed *r the u#e *9 C@@ in any #ituati*n !here pr*gra++er# +ight *ther!i#e ch**#e C) Thi# g*al !a# reali7ed, 3ut at the price *9 greater c*+ple;ity !hen pr*gra++ing in C@@) C# i# #i+pler than C@@, 3ut the tradeE*99 i# in e99iciency and #*+eti+e# applica3ility) 5*r a #igni9icant p*rti*n *9 pr*gra++ing pr*3le+#, h*!ever, C# i# the #uperi*r ch*ice)

%&ce$tion handling, dealing with errors


Ever #ince the 3eginning *9 pr*gra++ing language#, err*r handling ha# 3een *ne *9 the +*#t di99icult i##ue#) Becau#e it# #* hard t* de#ign a g**d err*r handling #che+e, +any language# #i+ply ign*re the i##ue, pa##ing the pr*3le+ *n t* li3rary de#igner# !h* c*+e up !ith hal9!ay +ea#ure# that can !*rk in +any #ituati*n# 3ut can ea#ily 3e circu+vented, generally 3y 4u#t ign*ring the+) = +a4*r pr*3le+ !ith +*#t err*r handling #che+e# i# that they rely *n pr*gra++er vigilance in 9*ll*!ing an agreedEup*n c*nventi*n that i# n*t en9*rced 3y the language) -9 the pr*gra++er i# n*t vigilantR*9ten the ca#e i9 they are in a hurryRthe#e #che+e# can ea#ily 3e 9*rg*tten) E;cepti*n handling !ire# err*r handling directly int* the pr*gra++ing language and #*+eti+e# even the *perating #y#te+) =n e;cepti*n i# an *34ect that i# Ithr*!nJ 9r*+ the #ite *9 the err*r and can 3e IcaughtJ 3y an appr*priate e;cepti*n handler de#igned t* handle that particular type *9

Cha"ter 1* Introduction to 123ects

43

err*r) -t# a# i9 e;cepti*n handling i# a di99erent, parallel path *9 e;ecuti*n that can 3e taken !hen thing# g* !r*ng) =nd 3ecau#e it u#e# a #eparate e;ecuti*n path, it d*e#nt need t* inter9ere !ith y*ur n*r+ally e;ecuting c*de) Thi# +ake# that c*de #i+pler t* !rite #ince y*u arent c*n#tantly 9*rced t* check 9*r err*r#) -n additi*n, a thr*!n e;cepti*n i# unlike an err*r value that# returned 9r*+ a 9uncti*n *r a 9lag that# #et 3y a 9uncti*n in *rder t* indicate an err*r c*nditi*nRthe#e can 3e ign*red) =n e;cepti*n cann*t 3e ign*red, #* it# guaranteed t* 3e dealt !ith at #*+e p*int) 5inally, e;cepti*n# pr*vide a !ay t* relia3ly rec*ver 9r*+ a 3ad #ituati*n) -n#tead *9 4u#t e;iting y*u are *9ten a3le t* #et thing# right and re#t*re the e;ecuti*n *9 a pr*gra+, !hich pr*duce# +uch +*re r*3u#t pr*gra+#) -t# !*rth n*ting that e;cepti*n handling i#nt an *34ectE*riented 9eature, alth*ugh in *34ectE*riented language# the e;cepti*n i# n*r+ally repre#ented !ith an *34ect) E;cepti*n handling e;i#ted 3e9*re *34ectE *riented language#)

@ultithreading
= 9unda+ental c*ncept in c*+puter pr*gra++ing i# the idea *9 handling +*re than *ne ta#k at a ti+e) Aany pr*gra++ing pr*3le+# reDuire that the pr*gra+ 3e a3le t* #t*p !hat it# d*ing, deal !ith #*+e *ther pr*3le+, and then return t* the +ain pr*ce##) The #*luti*n ha# 3een appr*ached in +any !ay#) -nitially, pr*gra++er# !ith l*!Elevel kn*!ledge *9 the +achine !r*te interrupt #ervice r*utine# and the #u#pen#i*n *9 the +ain pr*ce## !a# initiated thr*ugh a hard!are interrupt) =lth*ugh thi# !*rked !ell, it !a# di99icult and n*np*rta3le, #* it +ade +*ving a pr*gra+ t* a ne! type *9 +achine #l*! and e;pen#ive) S*+eti+e# interrupt# are nece##ary 9*r handling ti+eEcritical ta#k#, 3ut there# a large cla## *9 pr*3le+# in !hich y*ure #i+ply trying t* partiti*n the pr*3le+ int* #eparately running piece# #* that the !h*le pr*gra+ can 3e +*re re#p*n#ive) ,ithin a pr*gra+, the#e #eparately running piece# are called thread#, and the general c*ncept i# called multithreading. = c*++*n e;a+ple *9 +ultithreading i# the u#er inter9ace) By u#ing

44

Thinking in C

www.ThinkingIn.!et

thread#, a u#er can pre## a 3utt*n and get a Duick re#p*n#e rather than 3eing 9*rced t* !ait until the pr*gra+ 9ini#he# it# current ta#k) Ordinarily, thread# are 4u#t a !ay t* all*cate the ti+e *9 a #ingle pr*ce##*r) But i9 the *perating #y#te+ #upp*rt# +ultiple pr*ce##*r#, each thread can 3e a##igned t* a di99erent pr*ce##*r and they can truly run in parallel) One *9 the c*nvenient 9eature# *9 +ultithreading at the language level i# that the pr*gra++er d*e#nt need t* !*rry a3*ut !hether there are +any pr*ce##*r# *r 4u#t *ne) The pr*gra+ i# l*gically divided int* thread# and i9 the +achine ha# +*re than *ne pr*ce##*r then the pr*gra+ run# 9a#ter, !ith*ut any #pecial ad4u#t+ent#) =ll thi# +ake# threading #*und pretty #i+ple) There i# a catch1 #hared re#*urce#) -9 y*u have +*re than *ne thread running that# e;pecting t* acce## the #a+e re#*urce y*u have a pr*3le+) 5*r e;a+ple, t!* pr*ce##e# cant #i+ultane*u#ly #end in9*r+ati*n t* a printer) T* #*lve the pr*3le+, re#*urce# that can 3e #hared, #uch a# the printer, +u#t 3e l*cked !hile they are 3eing u#ed) S* a thread l*ck# a re#*urce, c*+plete# it# ta#k, and then relea#e# the l*ck #* that #*+e*ne el#e can u#e the re#*urce) C## threading i# 3uilt int* the language, !hich +ake# a c*+plicated #u34ect +uch #i+pler) The threading i# #upp*rted *n an *34ect level, #* *ne thread *9 e;ecuti*n i# repre#ented 3y *ne *34ect) C# al#* pr*vide# li+ited re#*urce l*cking) -t can l*ck the +e+*ry *9 any *34ect G!hich i#, a9ter all, *ne kind *9 #hared re#*urceH #* that *nly *ne thread can u#e it at a ti+e) Thi# i# acc*+pli#hed !ith the loc( key!*rd) Other type# *9 re#*urce# +u#t 3e l*cked e;plicitly 3y the pr*gra++er, typically 3y creating an *34ect t* repre#ent the l*ck that all thread# +u#t check 3e9*re acce##ing that re#*urce)

Persistence
tk

C# and the Internet


tk

Cha"ter 1* Introduction to 123ects

45

What is the We+<


tk

Client?'erver co#$uting
tk

-he We+ as a giant server


tk

Client;side $rogra##ing
tk

Plug;ins
tk

'cri$ting languages
tk

6ich clients in C#
tk

'ecurit5
tk

Internet vs. intranet


tk

'erver;side $rogra##ing
tk

) se$arate arena, a$$lications


tk

46

Thinking in C

www.ThinkingIn.!et

)nal5sis and design


tk

%&tre#e $rogra##ing
tk

Wh5 .(%- succeeds


'5ste#s are easier to e&$ress and understand @a&i#al leverage with li+raries %rror handling
Err*r handling in C i# a n*t*ri*u# pr*3le+, and *ne that i# *9ten ign*red R9ingerEcr*##ing i# u#ually inv*lved) -9 y*ure 3uilding a large, c*+ple; pr*gra+, there# n*thing !*r#e than having an err*r 3uried #*+e!here !ith n* clue a# t* !here it ca+e 9r*+) "ava e%ce"tion handling i# a !ay t* guarantee that an err*r i# n*ticed, and that #*+ething happen# a# a re#ult)

Progra##ing in the large


Aany traditi*nal language# have 3uiltEin li+itati*n# t* pr*gra+ #i7e and c*+ple;ity) B=S-C, 9*r e;a+ple, can 3e great 9*r pulling t*gether Duick #*luti*n# 9*r certain cla##e# *9 pr*3le+#, 3ut i9 the pr*gra+ get# +*re than a 9e! page# l*ng, *r venture# *ut *9 the n*r+al pr*3le+ d*+ain *9 that language, it# like trying t* #!i+ thr*ugh an everE+*re vi#c*u# 9luid) There# n* clear line that tell# y*u !hen y*ur language i# 9ailing y*u, and even i9 there !ere, y*ud ign*re it) :*u d*nt #ay, IAy B=S-C pr*gra+ 4u#t g*t t** 3igQ -ll have t* re!rite it in CKJ -n#tead, y*u try t* #h*eh*rn a 9e! +*re line# in t* add that *ne ne! 9eature) S* the e;tra c*#t# c*+e creeping up *n y*u)

Cha"ter 1* Introduction to 123ects

4#

C# i# de#igned t* aid "rogramming in the largeRthat i#, t* era#e th*#e creepingEc*+ple;ity 3*undarie# 3et!een a #+all pr*gra+ and a large *ne) :*u certainly d*nt need t* u#e OOP !hen y*ure !riting a Ihell* !*rldJ #tyle utility pr*gra+, 3ut the 9eature# are there !hen y*u need the+) =nd the c*+piler i# aggre##ive a3*ut 9erreting *ut 3ugEpr*ducing err*r# 9*r #+all and large pr*gra+# alike)

'trategies 0or transition


tk

Guidelines
Here are #*+e guideline# t* c*n#ider !hen +aking the tran#iti*n t* ) ET and C#1

1. -raining
The 9ir#t #tep i# #*+e 9*r+ *9 educati*n) Re+e+3er the c*+pany# inve#t+ent in c*de, and try n*t t* thr*! everything int* di#array 9*r #i; t* nine +*nth# !hile every*ne pu77le# *ver h*! inter9ace# !*rk) Pick a #+all gr*up 9*r ind*ctrinati*n, pre9era3ly *ne c*+p*#ed *9 pe*ple !h* are curi*u#, !*rk !ell t*gether, and can 9uncti*n a# their *!n #upp*rt net!*rk !hile theyre learning C# and ) ET) =n alternative appr*ach that i# #*+eti+e# #ugge#ted i# the educati*n *9 all c*+pany level# at *nce, including *vervie! c*ur#e# 9*r #trategic +anager# a# !ell a# de#ign and pr*gra++ing c*ur#e# 9*r pr*4ect 3uilder#) Thi# i# e#pecially g**d 9*r #+aller c*+panie# +aking 9unda+ental #hi9t# in the !ay they d* thing#, *r at the divi#i*n level *9 larger c*+panie#) Becau#e the c*#t i# higher, h*!ever, #*+e +ay ch**#e t* #tart !ith pr*4ectElevel training, d* a pil*t pr*4ect Gp*##i3ly !ith an *ut#ide +ent*rH, and let the pr*4ect tea+ 3ec*+e the teacher# 9*r the re#t *9 the c*+pany)

2. Low;ris* $ro/ect
Try a l*!Eri#k pr*4ect 9ir#t and all*! 9*r +i#take#) Once y*uve gained #*+e e;perience, y*u can either #eed *ther pr*4ect# 9r*+ +e+3er# *9 thi# 9ir#t tea+ *r u#e the tea+ +e+3er# a# a ) ET technical #upp*rt #ta99) Thi#

4&

Thinking in C

www.ThinkingIn.!et

9ir#t pr*4ect +ay n*t !*rk right the 9ir#t ti+e, #* it #h*uld n*t 3e +i##i*nE critical 9*r the c*+pany) -t #h*uld 3e #i+ple, #el9Ec*ntained, and in#tructiveQ thi# +ean# that it #h*uld inv*lve creating cla##e# that !ill 3e +eaning9ul t* the *ther pr*gra++er# in the c*+pany !hen they get their turn t* learn C# and ) ET)

3. @odel 0ro# success


Seek *ut e;a+ple# *9 g**d *34ectE*riented de#ign 3e9*re #tarting 9r*+ #cratch) There# a g**d pr*3a3ility that #*+e*ne ha# #*lved y*ur pr*3le+ already, and i9 they havent #*lved it e;actly y*u can pr*3a3ly apply !hat y*uve learned a3*ut a3#tracti*n t* +*di9y an e;i#ting de#ign t* 9it y*ur need#) Thi# i# the general c*ncept *9 design "atterns6 c*vered in Thinking in /atterns with ,a-a, d*!nl*ada3le at www.BruceEckel.com)

. >se e&isting class li+raries


The pri+ary ec*n*+ic +*tivati*n 9*r #!itching t* OOP i# the ea#y u#e *9 e;i#ting c*de in the 9*r+ *9 cla## li3rarie# Gin particular, the ) ET 5ra+e!*rk S?N li3rarie#, !hich are c*vered thr*ugh*ut thi# 3**kH) The #h*rte#t applicati*n devel*p+ent cycle !ill re#ult !hen y*u can create and u#e *34ect# 9r*+ *99EtheE#hel9 li3rarie#) H*!ever, #*+e ne! pr*gra++er# d*nt under#tand thi#, are una!are *9 e;i#ting cla## li3rarie#, *r, thr*ugh 9a#cinati*n !ith the language, de#ire t* !rite cla##e# that +ay already e;i#t) :*ur #ucce## !ith OOP, ) ET, and C# !ill 3e *pti+i7ed i9 y*u +ake an e99*rt t* #eek *ut and reu#e *ther pe*ple# c*de early in the tran#iti*n pr*ce##)

!. 4ont rewrite e&isting code in C#


-t i# n*t u#ually the 3e#t u#e *9 y*ur ti+e t* take e;i#ting, 9uncti*nal c*de and re!rite it in C#) G-9 y*u +u#t turn it int* *34ect#, y*u can inter9ace t* the C *r C@@ c*de a# di#cu##ed in #re9#)H There are incre+ental 3ene9it#, e#pecially i9 the c*de i# #lated 9*r reu#e) But chance# are y*u arent g*ing t* #ee the dra+atic increa#e# in pr*ductivity that y*u h*pe 9*r in y*ur 9ir#t 9e! pr*4ect# unle## that pr*4ect i# a ne! *ne) C# and ) ET #hine 3e#t !hen taking a pr*4ect 9r*+ c*ncept t* reality)

Cha"ter 1* Introduction to 123ects

4'

@anage#ent o+stacles
-9 y*ure a +anager, y*ur 4*3 i# t* acDuire re#*urce# 9*r y*ur tea+, t* *verc*+e 3arrier# t* y*ur tea+# #ucce##, and in general t* try t* pr*vide the +*#t pr*ductive and en4*ya3le envir*n+ent #* y*ur tea+ i# +*#t likely t* per9*r+ th*#e +iracle# that are al!ay# 3eing a#ked *9 y*u) A*ving t* ) ET 9all# in all three *9 the#e categ*rie#, and it !*uld 3e !*nder9ul i9 it didnt c*#t y*u anything a# !ell) =lth*ugh +*ving t* ) ET +ay 3e cheaperRdepending *n y*ur c*n#traint#Rthan the alternative# 9*r a tea+ *9 Ci#ual Ba#ic pr*gra++er# Gand pr*3a3ly 9*r pr*gra++er# in *ther pr*cedural language#H, it i#nt 9ree, and there are *3#tacle# y*u #h*uld 3e a!are *9 3e9*re trying t* #ell the +*ve t* C# !ithin y*ur c*+pany and e+3arking *n the +*ve it#el9)

'tartu$ costs
tk

Per0or#ance issues
tk

Co##on design errors


tk

C# vs. Aava<
tk

'u##ar5
tk

5(

Thinking in C

www.ThinkingIn.!et

3, 9ello. O+/ects
=lth*ugh it i# 3a#ed *n C@@, C# i# +*re *9 a IpureJ *34ectE*riented language)
B*th C@@ and C# are hy3rid language#, 3ut in C# the de#igner# 9elt that the hy3ridi7ati*n !a# n*t a# i+p*rtant a# it !a# in C@@) = hy3rid language all*!# +ultiple pr*gra++ing #tyle#Q the rea#*n C@@ i# hy3rid i# t* #upp*rt 3ack!ard c*+pati3ility !ith the C language) Becau#e C@@ i# a #uper#et *9 the C language, it include# +any *9 that language# unde#ira3le 9eature#, !hich can +ake #*+e a#pect# *9 C@@ *verly c*+plicated) The C# language a##u+e# that y*u !ant t* d* *nly *34ectE*riented pr*gra++ing) Thi# +ean# that 3e9*re y*u can 3egin y*u +u#t #hi9t y*ur +ind#et int* an *34ectE*riented !*rld Gunle## it# already thereH. The 3ene9it *9 thi# initial e99*rt i# the a3ility t* pr*gra+ in a language that i# #i+pler t* learn and t* u#e than +any *ther OOP language#) -n thi# chapter !ell #ee the 3a#ic c*+p*nent# *9 a C# pr*gra+ and !ell learn that everything in C# i# an *34ect, even a C# pr*gra+)

Bou #ani$ulate o+/ects with re0erences


Each pr*gra++ing language ha# it# *!n +ean# *9 +anipulating data) S*+eti+e# the pr*gra++er +u#t 3e c*n#tantly a!are *9 !hat type *9 +anipulati*n i# g*ing *n) =re y*u +anipulating the *34ect directly, *r are y*u dealing !ith #*+e kind *9 indirect repre#entati*n Ga p*inter in C *r C@@H that +u#t 3e treated !ith a #pecial #ynta;F =ll thi# i# #i+pli9ied in C#) :*u treat everything a# an *34ect, #* there i# a #ingle c*n#i#tent #ynta; that y*u u#e every!here) =lth*ugh y*u treat everything a# an *34ect, the identi9ier y*u +anipulate i# actually a

51

Ire9erenceJ t* an *34ect) :*u +ight i+agine thi# #cene a# a televi#i*n Gthe *34ectH !ith y*ur re+*te c*ntr*l Gthe re9erenceH) =# l*ng a# y*ure h*lding thi# re9erence, y*u have a c*nnecti*n t* the televi#i*n, 3ut !hen #*+e*ne #ay# Ichange the channelJ *r Il*!er the v*lu+e,J !hat y*ure +anipulating i# the re9erence, !hich in turn +*di9ie# the *34ect) -9 y*u !ant t* +*ve ar*und the r**+ and #till c*ntr*l the televi#i*n, y*u take the re+*te<re9erence !ith y*u, n*t the televi#i*n) =l#*, the re+*te c*ntr*l can #tand *n it# *!n, !ith n* televi#i*n) That i#, 4u#t 3ecau#e y*u have a re9erence d*e#nt +ean there# nece##arily an *34ect c*nnected t* it) S* i9 y*u !ant t* h*ld a !*rd *r #entence, y*u create a string re9erence1 #tring #3 But here y*uve created onl4 the re9erence, n*t an *34ect) -9 y*u decided t* #end a +e##age t* s at thi# p*int, y*ull get an err*r Gat runEti+eH 3ecau#e s i#nt actually attached t* anything Gthere# n* televi#i*nH) = #a9er practice, then, i# al!ay# t* initiali7e a re9erence !hen y*u create it1 #tring # 9 &a#df&3 H*!ever, thi# u#e# a #pecial 9eature1 #tring# can 3e initiali7ed !ith Du*ted te;t) *r+ally, y*u +u#t u#e a +*re general type *9 initiali7ati*n 9*r *34ect#)

Bou #ust create all the o+/ects


,hen y*u create a re9erence, y*u !ant t* c*nnect it !ith a ne! *34ect) :*u d* #*, in general, !ith the new key!*rd) new #ay#, IAake +e a ne! *ne *9 the#e *34ect#)J S* in the a3*ve e;a+ple, y*u can #ay1 #tring # 9 ne. #tring0&a#df&13 *t *nly d*e# thi# +ean IAake +e a ne! string,J 3ut it al#* give# in9*r+ati*n a3*ut how t* +ake the string 3y #upplying an initial character #tring)

5)

O9 c*ur#e, string i# n*t the *nly type that e;i#t#) C# c*+e# !ith a pleth*ra *9 readyE+ade type#) ,hat# +*re i+p*rtant i# that y*u can create y*ur *!n type#) -n 9act, that# the 9unda+ental activity in C# pr*gra++ing, and it# !hat y*ull 3e learning a3*ut in the re#t *9 thi# 3**k)

Where storage lives


-t# u#e9ul t* vi#uali7e #*+e a#pect# *9 h*! thing# are laid *ut !hile the pr*gra+ i# running, in particular h*! +e+*ry i# arranged) There are #i; di99erent place# t* #t*re data1 1. *egisters) Thi# i# the 9a#te#t #t*rage 3ecau#e it e;i#t# in a place di99erent 9r*+ that *9 *ther #t*rage1 in#ide the pr*ce##*r) H*!ever, the nu+3er *9 regi#ter# i# #everely li+ited, #* regi#ter# are all*cated 3y the c*+piler acc*rding t* it# need#) :*u d*nt have direct c*ntr*l, n*r d* y*u #ee any evidence in y*ur pr*gra+# that regi#ter# even e;i#t) +he stac() Thi# live# in the general R=A Grand*+Eacce## +e+*ryH area, 3ut ha# direct #upp*rt 9r*+ the pr*ce##*r via it# stack "ointer) The #tack p*inter i# +*ved d*!n t* create ne! +e+*ry and +*ved up t* relea#e that +e+*ry) Thi# i# an e;tre+ely 9a#t and e99icient !ay t* all*cate #t*rage, #ec*nd *nly t* regi#ter#) The C# 4u#tEinEti+e c*+piler +u#t kn*!, !hile it i# creating the pr*gra+, the e;act #i7e and li9eti+e *9 all the data that i# #t*red *n the #tack, 3ecau#e it +u#t generate the c*de t* +*ve the #tack p*inter up and d*!n) Thi# c*n#traint place# li+it# *n the 9le;i3ility *9 y*ur pr*gra+#, #* !hile #*+e C# #t*rage e;i#t# *n the #tackRin particular, *34ect re9erence#RC# *34ect# the+#elve# are n*t placed *n the #tack) +he heap) Thi# i# a generalEpurp*#e p**l *9 +e+*ry Gal#* in the R=A areaH !here all C# *34ect# live) The nice thing a3*ut the heap i# that, unlike the #tack, the c*+piler d*e#nt need t* kn*! h*! +uch #t*rage it need# t* all*cate 9r*+ the heap *r h*! l*ng that #t*rage +u#t #tay *n the heap) Thu#, there# a great deal *9 9le;i3ility in u#ing #t*rage *n the heap) ,henever y*u need t* create an *34ect, y*u #i+ply !rite the c*de t* create it u#ing new,

2.

3.

Cha"ter )* E-er4thing is an 123ect

53

and the #t*rage i# all*cated *n the heap !hen that c*de i# e;ecuted) O9 c*ur#e there# a price y*u pay 9*r thi# 9le;i3ility1 it take# +*re ti+e t* all*cate heap #t*rage than it d*e# t* all*cate #tack #t*rage Gthat i#, i9 y*u even could create *34ect# *n the #tack in C#, a# y*u can in C@@H) . #tatic storage) IStaticJ i# u#ed here in the #en#e *9 Iin a 9i;ed l*cati*nJ Galth*ugh it# al#* in R=AH) Static #t*rage c*ntain# data that i# availa3le 9*r the entire ti+e a pr*gra+ i# running) :*u can u#e the static key!*rd t* #peci9y that a particular ele+ent *9 an *34ect i# #tatic, 3ut C# *34ect# the+#elve# are never placed in #tatic #t*rage) Constant storage) C*n#tant value# are *9ten placed directly in the pr*gra+ c*de, !hich i# #a9e #ince they can never change) S*+eti+e# c*n#tant# are c*rd*ned *99 3y the+#elve# #* that they can 3e *pti*nally placed in readE*nly +e+*ry GROAH) ,on-*'. storage) -9 data live# c*+pletely *ut#ide a pr*gra+ it can e;i#t !hile the pr*gra+ i# n*t running, *ut#ide the c*ntr*l *9 the pr*gra+) The t!* pri+ary e;a+ple# *9 thi# are streamed o23ects6 in !hich *34ect# are turned int* #trea+# *9 3yte#, generally t* 3e #ent t* an*ther +achine, and "ersistent o23ects6 in !hich the *34ect# are placed *n di#k #* they !ill h*ld their #tate even !hen the pr*gra+ i# ter+inated) The trick !ith the#e type# *9 #t*rage i# turning the *34ect# int* #*+ething that can e;i#t *n the *ther +ediu+, and yet can 3e re#urrected int* a regular R=AE3a#ed *34ect !hen nece##ary) C# pr*vide# #upp*rt 9*r lightweight "ersistence, and 9uture ver#i*n# *9 ) ET +ight pr*vide +*re c*+plete #*luti*n# 9*r per#i#tence)

!.

".

)rra5s in Aava
Cirtually all pr*gra++ing language# #upp*rt array#) U#ing array# in C and C@@ i# peril*u# 3ecau#e th*#e array# are *nly 3l*ck# *9 +e+*ry) -9 a pr*gra+ acce##e# the array *ut#ide *9 it# +e+*ry 3l*ck *r u#e# the +e+*ry 3e9*re initiali7ati*n Gc*++*n pr*gra++ing err*r#H there !ill 3e unpredicta3le re#ult#)

54

Thinking in C

www.ThinkingIn.!et

One *9 the pri+ary g*al# *9 C# i# #a9ety, #* +any *9 the pr*3le+# that plague pr*gra++er# in C and C@@ are n*t repeated in C#) = C# array i# guaranteed t* 3e initiali7ed and cann*t 3e acce##ed *ut#ide *9 it# range) The range checking c*+e# at the price *9 having a #+all a+*unt *9 +e+*ry *verhead *n each array a# !ell a# veri9ying the inde; at runEti+e, 3ut the a##u+pti*n i# that the #a9ety and increa#ed pr*ductivity i# !*rth the e;pen#e) ,hen y*u create an array *9 *34ect#, y*u are really creating an array *9 re9erence#, and each *9 th*#e re9erence# i# aut*+atically initiali7ed t* a #pecial value !ith it# *!n key!*rd1 null) ,hen C# #ee# null, it rec*gni7e# that the re9erence in Due#ti*n i#nt p*inting t* an *34ect) :*u +u#t a##ign an *34ect t* each re9erence 3e9*re y*u u#e it, and i9 y*u try t* u#e a re9erence that# #till null, the pr*3le+ !ill 3e rep*rted at runEti+e) Thu#, typical array err*r# are prevented in C#) :*u can al#* create an array *9 value type#) =gain, the c*+piler guarantee# initiali7ati*n 3ecau#e it 7er*e# the +e+*ry 9*r that array) =rray# !ill 3e c*vered in detail in later chapter#)

'$ecial case, value t5$es


Unlike IpureJ *34ectE*riented language# #uch a# S+alltalk, C# d*e# n*t in#i#t that every varia3le +u#t 3e an *34ect) ,hile the per9*r+ance *9 +*#t #y#te+# i# n*t deter+ined 3y a #ingle 9act*r, the all*cati*n *9 +any #+all *34ect# can 3e n*t*ri*u#ly c*#tly) = #t*ry g*e# that in the early 066$#, a +anager decreed that hi# pr*gra++ing tea+ #!itch t* S+alltalk t* gain the 3ene9it# *9 *34ectE*rientati*nQ an *3#tinate C pr*gra++er i++ediately p*rted the applicati*n# c*re +atri;E+anipulating alg*rith+ t* S+alltalk) The +anager !a# plea#ed !ith thi# #urpri#ingly c**perative 3ehavi*r, a# the pr*gra++er +ade #ure that every*ne kne! that he !a# integrating the ne! S+alltalk c*de that very a9tern**n and running it thr*ugh the #tre## te#t 3e9*re +aking it the 9ir#t S+alltalk c*de t* 3e integrated int* the pr*ducti*n c*de) T!entyE9*ur h*ur# later, !hen the +atri; +anipulati*n had n*t c*+pleted, the +anager reali7ed that hed 3een had, and never #p*ke *9 S+alltalk again) ,hen "ava 3eca+e p*pular, +any pe*ple predicted #i+ilar per9*r+ance pr*3le+#) H*!ever, "ava ha# Ipri+itiveJ type# 9*r integer# and character#

Cha"ter )* E-er4thing is an 123ect

55

and #* 9*rth and +any pe*ple have 9*und that thi# ha# 3een #u99icient t* +ake "ava appr*priate 9*r al+*#t all per9*r+anceE*riented ta#k#) C# g*e# a #tep 3ey*ndQ n*t *nly are value# Grather than cla##e#H u#ed 9*r 3a#ic nu+eric type#, devel*per# can create ne! value type# in the 9*r+ *9 enu+erati*n# Genum#H and #tructure# Gstruct#H) Calue type# can 3e tran#parently c*nverted t* *34ect re9erence# via a pr*ce## kn*!n a# I3*;ing)J Thi# i# a nice advantage *9 C# *ver "ava, !here turning a pri+itive type int* an *34ect re9erence reDuire# an e;plicit +eth*d call)

Bou never need to destro5 an o+/ect


-n +*#t pr*gra++ing language#, the c*ncept *9 the li9eti+e *9 a varia3le *ccupie# a #igni9icant p*rti*n *9 the pr*gra++ing e99*rt) H*! l*ng d*e# the varia3le la#tF -9 y*u are #upp*#ed t* de#tr*y it, !hen #h*uld y*uF C*n9u#i*n *ver varia3le li9eti+e# can lead t* a l*t *9 3ug#, and thi# #ecti*n #h*!# h*! C# greatly #i+pli9ie# the i##ue 3y d*ing all the cleanup !*rk 9*r y*u)

'co$ing
A*#t pr*cedural language# have the c*ncept *9 sco"e) Thi# deter+ine# 3*th the vi#i3ility and li9eti+e *9 the na+e# de9ined !ithin that #c*pe) -n C, C@@, and C#, #c*pe i# deter+ined 3y the place+ent *9 curly 3race# /0) S* 9*r e;a+ple1 ; int x 9 "23 /= on y x a*ai a$ e =/ ; int 7 9 >?3 /= $oth x @ 7 a*ai a$ e =/ < /= on y x a*ai a$ e =/ /= 7 Aout of #copeB =/ <

56

Thinking in C

www.ThinkingIn.!et

= varia3le de9ined !ithin a #c*pe i# availa3le *nly t* the end *9 that #c*pe) -ndentati*n +ake# C# c*de ea#ier t* read) Since C# i# a 9reeE9*r+ language, the e;tra #pace#, ta3#, and carriage return# d* n*t a99ect the re#ulting pr*gra+) *te that y*u cannot d* the 9*ll*!ing, even th*ugh it i# legal in C and C@ @1 ; int x 9 "23 ; int x 9 >?3 /= i < < The c*+piler !ill ann*unce that the varia3le x ha# already 3een de9ined) Thu# the C and C@@ a3ility t* IhideJ a varia3le in a larger #c*pe i# n*t all*!ed 3ecau#e the C# de#igner# th*ught that it led t* c*n9u#ing pr*gra+#) ega =/

'co$e o0 o+/ects
C# *34ect# d* n*t have the #a+e li9eti+e# a# value type#) ,hen y*u create a C# *34ect u#ing new, it hang# ar*und pa#t the end *9 the #c*pe) Thu# i9 y*u u#e1 ; #tring # 9 ne. #tring0&a #tring&13 < /= end of #cope =/ the re9erence s vani#he# at the end *9 the #c*pe) H*!ever, the string *34ect that s !a# p*inting t* i# #till *ccupying +e+*ry) -n thi# 3it *9 c*de, there i# n* !ay t* acce## the *34ect 3ecau#e the *nly re9erence t* it i# *ut *9 #c*pe) -n later chapter# y*ull #ee h*! the re9erence t* the *34ect can 3e pa##ed ar*und and duplicated during the c*ur#e *9 a pr*gra+) -t turn# *ut that 3ecau#e *34ect# created !ith new #tay ar*und 9*r a# l*ng a# y*u !ant the+, a !h*le #le! *9 C@@ pr*gra++ing pr*3le+# #i+ply vani#h in C#) The harde#t pr*3le+# #ee+ t* *ccur in C@@ 3ecau#e y*u d*nt get any help 9r*+ the language in +aking #ure that the *34ect# are

Cha"ter )* E-er4thing is an 123ect

5#

availa3le !hen theyre needed) =nd +*re i+p*rtant, in C@@ y*u +u#t +ake #ure that y*u de#tr*y the *34ect# !hen y*ure d*ne !ith the+) That 3ring# up an intere#ting Due#ti*n) -9 C# leave# the *34ect# lying ar*und, !hat keep# the+ 9r*+ 9illing up +e+*ry and halting y*ur pr*gra+F Thi# i# e;actly the kind *9 pr*3le+ that !*uld *ccur in C@@) Thi# i# !here a 3it *9 +agic happen#) The ) ET runti+e ha# a gar2age collector, !hich l**k# at all the *34ect# that !ere created !ith new and 9igure# *ut !hich *ne# are n*t 3eing re9erenced any+*re) Then it relea#e# the +e+*ry 9*r th*#e *34ect#, #* the +e+*ry can 3e u#ed 9*r ne! *34ect#) Thi# +ean# that y*u never need t* !*rry a3*ut reclai+ing +e+*ry y*ur#el9) :*u #i+ply create *34ect#, and !hen y*u n* l*nger need the+ they !ill g* a!ay 3y the+#elve#) Thi# eli+inate# a certain cla## *9 pr*gra++ing pr*3le+1 the #*Ecalled I+e+*ry leak,J in !hich a pr*gra++er 9*rget# t* relea#e +e+*ry)

Creating new data t5$es, class


-9 everything i# an *34ect, !hat deter+ine# h*! a particular cla## *9 *34ect l**k# and 3ehave#F Put an*ther !ay, !hat e#ta3li#he# the t4"e *9 an *34ectF :*u +ight e;pect there t* 3e a key!*rd called Itype,J and that certainly !*uld have +ade #en#e) Hi#t*rically, h*!ever, +*#t *34ectE *riented language# have u#ed the key!*rd class t* +ean I-+ a3*ut t* tell y*u !hat a ne! type *9 *34ect l**k# like)J The class key!*rd G!hich i# #* c*++*n that it !ill n*t 3e e+3*ldened thr*ugh*ut thi# 3**kH i# 9*ll*!ed 3y the na+e *9 the ne! type) 5*r e;a+ple1 c a## )'ypeCa!e ; /= c a## $ody goe# here =/ < Thi# intr*duce# a ne! type, #* y*u can n*! create an *34ect *9 thi# type u#ing new1 )'ypeCa!e a 9 ne. )'ypeCa!e013 -n '+ype,ame, the cla## 3*dy c*n#i#t# *nly *9 a c*++ent Gthe #tar# and #la#he# and !hat i# in#ide, !hich !ill 3e di#cu##ed later in thi# chapterH, #* there i# n*t t** +uch that y*u can d* !ith it) -n 9act, y*u cann*t tell it

5&

Thinking in C

www.ThinkingIn.!et

t* d* +uch *9 anything Gthat i#, y*u cann*t #end it any intere#ting +e##age#H until y*u de9ine #*+e +eth*d# 9*r it)

7ields. Pro$erties. and #ethods


,hen y*u de9ine a cla##, y*u can put t!* type# *9 ele+ent# in y*ur cla##1 data +e+3er# G#*+eti+e# called $ieldsH, +e+3er 9uncti*n# Gtypically called methodsH, and pr*pertie#) = data +e+3er i# an *34ect *9 any type that y*u can c*++unicate !ith via it# re9erence) -t can al#* 3e a value type G!hich i#nt a re9erenceH) -9 it i# a re9erence t* an *34ect, y*u +u#t initiali7e that re9erence t* c*nnect it t* an actual *34ect Gu#ing new, a# #een earlierH in a #pecial 9uncti*n called a constructor Gde#cri3ed 9ully in Chapter &H) -9 it i# a pri+itive type y*u can initiali7e it directly at the p*int *9 de9initi*n in the cla##) G=# y*ull #ee later, re9erence# can al#* 3e initiali7ed at the p*int *9 de9initi*n)H Each *34ect keep# it# *!n #t*rage 9*r it# data +e+3er#Q the data +e+3er# are n*t #hared a+*ng *34ect#) Here i# an e;a+ple *9 a cla## !ith #*+e data +e+3er#1 c a## :ataOn y ; int i3 f oat f3 $oo ean $3 < Thi# cla## d*e#nt do anything, 3ut y*u can create an *34ect1 :ataOn y d 9 ne. :ataOn y013 :*u can a##ign value# t* the data +e+3er#, 3ut y*u +u#t 9ir#t kn*! h*! t* re9er t* a +e+3er *9 an *34ect) Thi# i# acc*+pli#hed 3y #tating the na+e *9 the *34ect re9erence, 9*ll*!ed 3y a peri*d Gd*tH, 9*ll*!ed 3y the na+e *9 the +e+3er in#ide the *34ect1 o$DectReference.!e!$er 5*r e;a+ple1 d.i 9 EF3 d.f 9 "."f3 d.$ 9 fa #e3

Cha"ter )* E-er4thing is an 123ect

5'

-t i# al#* p*##i3le that y*ur *34ect +ight c*ntain *ther *34ect# that c*ntain data y*ud like t* +*di9y) 5*r thi#, y*u 4u#t keep Ic*nnecting the d*t#)J 5*r e;a+ple1 !y- ane. eft'an%.capacity 9 "003 The $ata1nly cla## cann*t d* +uch *9 anything e;cept h*ld data, 3ecau#e it ha# n* +e+3er 9uncti*n# G+eth*d#H) T* under#tand h*! th*#e !*rk, y*u +u#t 9ir#t under#tand arguments and return -alues, !hich !ill 3e de#cri3ed #h*rtly)

4e0ault values 0or $ri#itive #e#+ers


,hen a pri+itive data type i# a +e+3er *9 a cla##, it i# guaranteed t* get a de9ault value i9 y*u d* n*t initiali7e it1 !rimitive type boolean char byte short int long float double $efault false 23u44445 (null) (byte)4 (short)4 4 4L 464f 464d

*te care9ully that the de9ault value# are !hat C# guarantee# !hen the varia3le i# u#ed as a mem2er o$ a class) Thi# en#ure# that +e+3er varia3le# *9 pri+itive type# !ill al!ay# 3e initiali7ed G#*+ething C@@ d*e#nt d*H, reducing a #*urce *9 3ug#) H*!ever, thi# initial value +ay n*t 3e c*rrect *r even legal 9*r the pr*gra+ y*u are !riting) -t# 3e#t t* al!ay# e;plicitly initiali7e y*ur varia3le#) Thi# guarantee d*e#nt apply t* Il*calJ varia3le#Rth*#e that are n*t 9ield# *9 a cla##) Thu#, i9 !ithin a 9uncti*n de9initi*n y*u have1 int x3

6(

Thinking in C

www.ThinkingIn.!et

Then x !ill get #*+e ar3itrary value Ga# in C and C@@HQ it !ill n*t aut*+atically 3e initiali7ed t* 7er*) :*u are re#p*n#i3le 9*r a##igning an appr*priate value 3e9*re y*u u#e x) -9 y*u 9*rget, C# de9initely i+pr*ve# *n C@@1 y*u get a c*+pileEti+e err*r telling y*u the varia3le +ight n*t have 3een initiali7ed) GAany C@@ c*+piler# !ill !arn y*u a3*ut uninitiali7ed varia3le#, 3ut in C# the#e are err*r#)H

@ethods. argu#ents. and return values


Up until n*!, the ter+ $unction ha# 3een u#ed t* de#cri3e a na+ed #u3r*utine) The ter+ that i# +*re c*++*nly u#ed in C# i# method6 a# in Ia !ay t* d* #*+ething)J -9 y*u !ant, y*u can c*ntinue thinking in ter+# *9 9uncti*n#) -t# really *nly a #yntactic di99erence, 3ut 9r*+ n*! *n I+eth*dJ !ill 3e u#ed in thi# 3**k rather than I9uncti*n)J Aeth*d# in C# deter+ine the +e##age# an *34ect can receive) -n thi# #ecti*n y*u !ill learn h*! #i+ple it i# t* de9ine a +eth*d) The 9unda+ental part# *9 a +eth*d are the na+e, the argu+ent#, the return type, and the 3*dy) Here i# the 3a#ic 9*r+1 return'ype GethodCa!e0 /= )rgu!ent /= Gethod $ody =/ < i#t =/ 1 ;

The return type i# the type *9 the value that p*p# *ut *9 the +eth*d a9ter y*u call it) The argu+ent li#t give# the type# and na+e# 9*r the in9*r+ati*n y*u !ant t* pa## int* the +eth*d) The +eth*d na+e and argu+ent li#t t*gether uniDuely identi9y the +eth*d) Aeth*d# in C# can 3e created *nly a# part *9 a cla##) = +eth*d can 3e called *nly 9*r an *34ect,0 and that *34ect +u#t 3e a3le t* per9*r+ that +eth*d call) -9 y*u try t* call the !r*ng +eth*d 9*r an *34ect, y*ull get an err*r +e##age at c*+pileEti+e) :*u call a +eth*d 9*r an *34ect 3y na+ing the *34ect 9*ll*!ed 3y a peri*d Gd*tH, 9*ll*!ed 3y the na+e *9 the +eth*d
0 static +eth*d#, !hich y*ull learn a3*ut #**n, can 3e called $or the class, !ith*ut an

*34ect)

Cha"ter )* E-er4thing is an 123ect

61

and it# argu+ent li#t, like thi#1 ob)ect,ame6.ethod,ame(arg7, arg8, arg9)) 5*r e;a+ple, #upp*#e y*u have a +eth*d :( ) that take# n* argu+ent# and return# a value *9 type int) Then, i9 y*u have an *34ect called a 9*r !hich :( ) can 3e called, y*u can #ay thi#1 int x 9 a.H013 The type *9 the return value +u#t 3e c*+pati3le !ith the type *9 x) Thi# act *9 calling a +eth*d i# c*++*nly re9erred t* a# sending a message to an o23ect) -n the a3*ve e;a+ple, the +e##age i# :( ) and the *34ect i# a) O34ectE*riented pr*gra++ing i# *9ten #u++ari7ed a# #i+ply I#ending +e##age# t* *34ect#)J

-he argu#ent list


The +eth*d argu+ent li#t #peci9ie# !hat in9*r+ati*n y*u pa## int* the +eth*d) =# y*u +ight gue##, thi# in9*r+ati*nRlike everything el#e in C# Rtake# the 9*r+ *9 *34ect#) S*, !hat y*u +u#t #peci9y in the argu+ent li#t are the type# *9 the *34ect# t* pa## in and the na+e t* u#e 9*r each *ne) =# in any #ituati*n in C# !here y*u #ee+ t* 3e handing *34ect# ar*und, y*u are actually pa##ing re9erence#2) The type *9 the re9erence +u#t 3e c*rrect, h*!ever) -9 the argu+ent i# #upp*#ed t* 3e a string, !hat y*u pa## in +u#t 3e a #tring) C*n#ider a +eth*d that take# a string a# it# argu+ent) Here i# the de9initi*n, !hich +u#t 3e placed !ithin a cla## de9initi*n 9*r it t* 3e c*+piled1 int #torage0#tring #1 ; return #.Length = 23 < Thi# +eth*d tell# y*u h*! +any 3yte# are reDuired t* h*ld the in9*r+ati*n in a particular string6 GEach char in a string i# 0. 3it#, *r t!* 3yte#, l*ng, t* #upp*rt Unic*de character#) Check thi# P d*e#nt it have +*re t* d* !ith the Te;tEnc*dingFH The argu+ent i# *9 type string and i# called s) Once s i# pa##ed int* the +eth*d, y*u can treat it 4u#t like any *ther *34ect) G:*u can #end +e##age# t* it)H Here, the Length
2 The C# key!*rd ref all*!# y*u t* *verride thi# 3ehavi*r

6)

Thinking in C

www.ThinkingIn.!et

pr*perty i# u#ed, !hich i# *ne *9 the pr*pertie# *9 string#Q it return# the nu+3er *9 character# in a #tring) :*u can al#* #ee the u#e *9 the return key!*rd, !hich d*e# t!* thing#) 5ir#t, it +ean# Ileave the +eth*d, -+ d*ne)J Sec*nd, i9 the +eth*d pr*duce# a value, that value i# placed right a9ter the return #tate+ent) -n thi# ca#e, the return value i# pr*duced 3y evaluating the e;pre##i*n s6Length ; 8) :*u can return any type y*u !ant, 3ut i9 y*u d*nt !ant t* return anything at all, y*u d* #* 3y indicating that the +eth*d return# void) Here are #*+e e;a+ple#1 $oo ean H ag01 ; return true3 < f oat Catura LogBa#e01 ; return 2.F"If3 < *oid Cothing01 ; return3 < *oid Cothing201 ;< ,hen the return type i# void, then the return key!*rd i# u#ed *nly t* e;it the +eth*d, and i# there9*re unnece##ary !hen y*u reach the end *9 the +eth*d) :*u can return 9r*+ a +eth*d at any p*int, 3ut i9 y*uve given a n*nEvoid return type then the c*+piler !ill 9*rce y*u G!ith err*r +e##age#H t* return the appr*priate type *9 value regardle## *9 !here y*u return) =t thi# p*int, it can l**k like a pr*gra+ i# 4u#t a 3unch *9 *34ect# !ith +eth*d# that take *ther *34ect# a# argu+ent# and #end +e##age# t* th*#e *ther *34ect#) That i# indeed +uch *9 !hat g*e# *n, 3ut in the 9*ll*!ing chapter y*ull learn h*! t* d* the detailed l*!Elevel !*rk 3y +aking deci#i*n# !ithin a +eth*d) 5*r thi# chapter, #ending +e##age# !ill #u99ice)

)ttri+utes and @eta; 3ehavior


The +*#t intriguing l*!Elevel 9eature *9 the ) ET Runti+e i# the attri3ute, !hich all*!# y*u t* #peci9y ar3itrary +etaEin9*r+ati*n t* 3e a##*ciated !ith c*de ele+ent# #uch a# cla##e#, type#, and +eth*d#)

Cha"ter )* E-er4thing is an 123ect

63

=ttri3ute# are #peci9ied in C# u#ing #Duare 3racket# 4u#t 3e9*re the c*de ele+ent) =dding an attri3ute t* a c*de ele+ent d*e#nt change the 3ehavi*r *9 the c*de ele+entQ rather, pr*gra+# can 3e !ritten !hich #ay I5*r all the c*de ele+ent# that have thi# attri3ute, d* thi# 3ehavi*r)J The +*#t i++ediately p*!er9ul de+*n#trati*n *9 thi# i# the <=eb.ethod> attri3ute !hich !ithin Ci#ual Studi* ) ET i# all that i# nece##ary t* trigger the e;p*#ure *9 that +eth*d a# a ,e3 Service) =ttri3ute# can 3e u#ed t* #i+ply tag a c*de ele+ent, a# !ith <=eb.ethod> *r they can c*ntain para+eter# that c*ntain additi*nal in9*r+ati*n) 5*r in#tance, thi# e;a+ple #h*!# an ?.L&lement attri3ute that #peci9ie# that, !hen #eriali7ed t* an BAL d*cu+ent, the :light#egment< > array #h*uld 3e created a# a #erie# *9 individual :light#egment ele+ent#1 J,! + e!ent0 + e!entCa!e 9 &H ightSeg!ent&1K pu$ ic H ightSeg!entJK f ight#3

4elegates
-n additi*n t* cla##e# and value type#, C# ha# an *34ectE*riented type that #peci9ie# a +eth*d signature) = +eth*d# #ignature c*n#i#t# *9 it# argu+ent li#t and it# return type) = delegate i# a type that all*!# any +eth*d !h*#e #ignature i# identical t* that #peci9ied in the delegate de9initi*n t* 3e u#ed a# an Iin#tanceJ *9 that delegate) -n thi# !ay, a +eth*d can 3e u#ed a# i9 it !ere a varia3le P in#tantiated, a##igned t*, pa##ed ar*und in re9erence 9*r+, etc) -n thi# e;a+ple, a delegate na+ed 5** i# de9ined1 de egate *oid Hoo0int x13 c a## GyC a##; *oid So!eGethod0int y1; L < int )notherGethod0int M1; L < < c a## GyOtherC a##; *oid /et)nother01; L <

64

Thinking in C

www.ThinkingIn.!et

#tatic *oid So!eOther0int M1; L < < The +eth*d .yClass6#ome.ethod( ) c*uld 3e u#ed t* in#tantiate the :oo delegate, a# c*uld the +eth*d .y1therClass6#ome1ther( )) either .yClass)'nother.ethod( ) n*r .y1therClass6@et'nother( ) can 3e u#ed a# :oo#, a# they have di99erent #ignature#) -n#tantiating a re9erence t* a delegate i# 4u#t like +aking a re9erence t* a cla##1 Hoo f 9 GyOtherC a##.So!eOther3 The le9tEhand #i7e c*ntain# a declarati*n *9 a varia3le f *9 type delegate :oo) The rightEhand #i7e s"eci$ies a +eth*d, it d*e# n*t actually call the +eth*d #ome1ther( )) ?elegate# are a +a4*r ele+ent in pr*gra++ing ,ind*!# 5*r+#, 3ut they repre#ent a +a4*r de#ign 9eature in C# and are u#e9ul in +any #ituati*n#)

Pro$erties
5ield# #h*uld, e##entially, never 3e availa3le directly t* the *ut#ide !*rld) Ai#take# are *9ten +ade !hen a 9ield i# a##igned t*Q the 9ield i# #upp*#ed t* #t*re a di#tance in +etric n*t Engli#h unit#, #tring# are #upp*#ed t* 3e all l*!erca#e, etc) H*!ever, #uch +i#take# are *9ten n*t $ound until the 9ield i# u#ed at a +uch later ti+e Glike, #ay, !hen preparing t* enter Aar# *r3itH) ,hile #uch l*gical +i#take# cann*t 3e di#c*vered 3y any aut*+atic +ean#, di#c*vering the+ can 3e +ade ea#ier 3y *nly all*!ing 9ield# t* 3e acce##ed via +eth*d# G!hich, in turn, can pr*vide additi*nal #anity check# and l*gging trace#H) C# all*!# y*u t* give y*ur cla##e# the appearance *9 having 9ield# directly e;p*#ed 3ut in 9act hiding the+ 3ehind +eth*d inv*cati*n#) The#e !roperty 9ield# c*+e in t!* varietie#1 readE*nly 9ield# that cann*t 3e a##igned t*, and the +*re c*++*n readEandE!rite 9ield#) =dditi*nally, pr*pertie# all*! y*u t* u#e a di99erent type internally t* #t*re the data 9r*+ the type y*u e;p*#e) 5*r in#tance, y*u +ight !i#h t* e;p*#e a 9ield

Cha"ter )* E-er4thing is an 123ect

65

a# an ea#yEt*Eu#e bool, 3ut #t*re it internally !ithin an e99icient Bit'rray cla## Gdi#cu##ed in Chapter 6H) Pr*pertie# are #peci9ied 3y declaring the type and na+e *9 the Pr*perty, 9*ll*!ed 3y a 3racketed c*de 3l*ck that de9ine# a get c*de 3l*ck G9*r retrieving the valueH and a set c*de 3l*ck) ReadE*nly pr*pertie# de9ine *nly a get c*de 3l*ck Git i# legal, 3ut n*t *3vi*u#ly u#e9ul, t* create a !riteE*nly pr*perty 3y de9ining 4u#t #etH) The get c*de 3l*ck act# a# i9 it !ere a +eth*d de9ined a# taking n* argu+ent# and returning the type de9ined in the Pr*perty declarati*nQ the set c*de 3l*ck act# a# i9 it !ere a +eth*d returning v*id that take# an argu+ent na+ed value *9 the #peci9ied type) Here# an e;a+ple *9 a readE!rite pr*perty called !roperty,ame *9 type .y+ype) c a## GyC a## ; Gy'ype !y5nterna Reference3 //Begin property definition Gy'ype -ropertyCa!e; get ; // ogic return !y5nterna Reference3 < #et; // ogic !y5nterna Reference 9 *a ue3 < < //+nd of property definition < T* u#e a Pr*perty, y*u acce## the na+e *9 the pr*perty directly1 !yC a##5n#tance.Gy-roperty 9 #o!eNa ue3 //Ca Gy'ype t 9 !yC a##5n#tance.Gy-roperty3 //Ca # &#et& # &get&

The C# c*+piler in 9cat does create +eth*d# in *rder t* i+ple+ent pr*pertie# Gy*ull never need t* u#e the+, 3ut i9 y*ure intere#ted, the +eth*d# are called getA!roperty,ame( ) and setA!roperty,ame( )H) Thi# i# a the+e *9 C# EE direct language #upp*rt 9*r 9eature# that are i+ple+ented, n*t directly in Aicr*#*9t

66

Thinking in C

www.ThinkingIn.!et

-nter+ediate Language GAS-L P the I+achine c*deJ *9 the ) ET runti+eH, 3ut via c*de generati*n) Such I#yntactical #ugarJ c*uld 3e re+*ved 9r*+ the C# language !ith*ut actually changing the #et *9 pr*3le+# that can 3e #*lved 3y the languageQ they I4u#tJ +ake ta#k# ea#ier) *t every language i# de#igned !ith ea#eE*9Eu#e a# a +a4*r de#ign g*al and #*+e language de#igner# 9eel that #yntactic #ugar end# up c*n9u#ing pr*gra++er#) 5*r a +a4*r language intended t* 3e u#ed 3y the 3r*ade#t p*##i3le audience, C## language de#ign i# appr*priateQ i9 y*u !ant #*+ething 3*iled d*!n t* pure 9uncti*nality, there# talk *9 L-SP 3eing p*rted t* ) ET)

Creating (ew 8alue -5$es


-n additi*n t* creating ne! cla##e#, y*u can create ne! value type#) ,hen y*u de9ine a value type, the c*+piler aut*+atically create# the additi*nal data nece##ary t* 3*; and un3*; the+, #* y*ur ne! value type# have all the advantage# *9 3*th value type# and *34ect#)

%nu#erations
=n enu+erati*n i# a #et *9 related value#1 UpE?*!n, *rthES*uthEEa#tE ,e#t, PennyE ickelE?i+eEMuarter, etc) =n enu+erati*n i# de9ined u#ing the enum key!*rd and a c*de 3l*ck in !hich the vari*u# value# are de9ined) Here# a #i+ple e;a+ple1 enu! OpOr:o.n; Op2 :o.n < Once de9ined, an enu+erati*n value can 3e u#ed 3y #peci9ying the enu+erati*n type, a d*t, and then the #peci9ic na+e de#ired1 OpOr:o.n coinH ip 9 OpOr:o.n.Op3 The na+e# !ithin an enu+erati*n are actually nu+eric value#) By de9ault, they are integer#, !h*#e value 3egin# at $) :*u can +*di9y 3*th the type *9 #t*rage u#ed 9*r the#e value# and the value# a##*ciated !ith a particular na+e) Here# an e;a+ple, !here a short i# u#ed t* h*ld di99erent c*in value#1 enu! Coin: #hort; -enny 9 "2 Cic%e < 9 P2 :i!e 9 "02 Quarter 9 2P

Cha"ter )* E-er4thing is an 123ect

6#

Then, the na+e# can 3e ca#t t* their i+ple+enting value type1 #hort change 9 0#hort1 0Coin.-enny R Coin.Quarter13 Thi# !ill re#ult in the value *9 change 3eing 2.) -t i# al#* p*##i3le t* d* 3it!i#e *perati*n# *n enu+erati*n# +arked !ith the <:lags> attri3ute1 JH ag#K enu! H a*or; Nani a 9 "2 Choco ate 9 22 Stra.$erry 9 E2 Coffee 9 I< ...etc... H a*or cone-ref 9 H a*or.Nani a S H a*or.Coffee3 =lth*ugh 9*r 3it!i#e *perati*n#, it i# *9 c*ur#e nece##ary 9*r y*u t* de9ine the 9lag# !ith c*+pati3le value#)

'tructs
= struct G#h*rt 9*r I#tructureJH i# very #i+ilar t* a cla## in that it can c*ntain 9ield#, pr*pertie#, and +eth*d#) H*!ever, struct# are value type#, y*u cann*t inherit 9r*+ a struct *r have y*ur struct inherit 9r*+ any cla## e;cept ob)ect Galth*ugh a struct can i+ple+ent an inter9aceH, and struct# have li+ited c*n#truct*r and de#truct*r #e+antic#) Typically, struct# are u#ed t* aggregate a relatively #+all a+*unt *9 l*gically related 9ield#) 5*r in#tance, the 5ra+e!*rk S?N c*ntain# a !oint #tructure that ha# ? and @ pr*pertie#) Structure# are declared in the #a+e !ay a# cla##e#) Thi# e;a+ple #h*!# !hat +ight 3e the #tart *9 a struct 9*r i+aginary nu+3er#1 #truct 5!aginaryCu!$er; dou$ e rea 3 dou$ e Rea ; get ; return rea 3 < #et ; rea 9 *a ue3 < < dou$ e i3 dou$ e 5; get ; return i3 < #et ; i 9 *a ue3 < <

6&

Thinking in C

www.ThinkingIn.!et

<

3uilding a C# $rogra#
There are #everal *ther i##ue# y*u +u#t under#tand 3e9*re #eeing y*ur 9ir#t C# pr*gra+)

(a#e visi+ilit5
= pr*3le+ in any pr*gra++ing language i# the c*ntr*l *9 na+e#) -9 y*u u#e a na+e in *ne +*dule *9 the pr*gra+, and an*ther pr*gra++er u#e# the #a+e na+e in an*ther +*dule, h*! d* y*u di#tingui#h *ne na+e 9r*+ an*ther and prevent the t!* na+e# 9r*+ Icla#hingFJ -n C thi# i# a particular pr*3le+ 3ecau#e a pr*gra+ i# *9ten an un+anagea3le #ea *9 na+e#) C@@ cla##e# G*n !hich C# cla##e# are 3a#edH ne#t 9uncti*n# !ithin cla##e# #* they cann*t cla#h !ith 9uncti*n na+e# ne#ted !ithin *ther cla##e#) H*!ever, C@@ #till all*!ed gl*3al data and gl*3al 9uncti*n#, #* cla#hing !a# #till p*##i3le) T* #*lve thi# pr*3le+, C@@ intr*duced names"aces u#ing additi*nal key!*rd#) -n C#, the namespace key!*rd i# 9*ll*!ed 3y a c*de 3l*ck Gthat i#, a pair *9 curly 3racket# !ith #*+e a+*unt *9 c*de !ithin the+H) Unlike "ava, there i# n* relati*n#hip 3et!een the na+e#pace and cla## na+e# and direct*ry and 9ile #tructure) Organi7ati*nally, it *9ten +ake# #en#e t* gather all the 9ile# a##*ciated !ith a #ingle na+e#pace int* a #ingle direct*ry and t* have a *neEt*E*ne relati*n#hip 3et!een cla## na+e# and 9ile#, 3ut thi# i# #trictly a +atter *9 pre9erence) Thr*ugh*ut thi# 3**k, *ur e;a+ple c*de !ill *9ten c*+3ine +ultiple cla##e# in a #ingle c*+pilati*n unit Gthat i#, a #ingle 9ileH and !e !ill typically n*t u#e na+e#pace#, 3ut in pr*9e##i*nal devel*p+ent, y*u #h*uld av*id #uch #paceE#aving ch*ice#) a+e#pace# can, and #h*uld, 3e ne#ted) By c*nventi*n, the *uter+*#t na+e#pace i# the na+e *9 y*ur *rgani7ati*n, the ne;t the na+e *9 the pr*4ect *r #y#te+ a# a !h*le, and the inner+*#t the na+e *9 the #peci9ic gr*uping *9 intere#t) Here# an e;a+ple1 na!e#pace 'hin%ing5n; na!e#pace CSharp;

Cha"ter )* E-er4thing is an 123ect

6'

na!e#pace ChapT; //c a## and other type dec aration# go here < < < Since na+e#pace# are pu3licly vie!a3le, they #h*uld #tart !ith a capital letter and then u#e Ica+el3ackJ capitali7ati*n G9*r in#tance, +hin(ingBnH) a+e#pace# are navigated u#ing d*t #ynta;1 +hin(ingBn6C#harp6Chap9 and +ay even 3e declared in thi# +anner1 na!e#pace 'hin%ing5n.CSharp.ChapE; L <

>sing other co#$onents


,henever y*u !ant t* u#e a prede9ined cla## in y*ur pr*gra+, the c*+piler +u#t kn*! h*! t* l*cate it) O9 c*ur#e, the cla## +ight already e;i#t in the #a+e #*urce c*de 9ile that it# 3eing called 9r*+) -n that ca#e, y*u #i+ply u#e the cla##Reven i9 the cla## d*e#nt get de9ined until later in the 9ile) C# eli+inate# the I9*r!ard re9erencingJ pr*3le+ #* y*u d*nt need t* think a3*ut it) ,hat a3*ut a cla## that e;i#t# in #*+e *ther 9ileF :*u +ight think that the c*+piler #h*uld 3e #+art en*ugh t* #i+ply g* and 9ind it, 3ut there i# a pr*3le+) -+agine that y*u !ant t* u#e a cla## *9 a particular na+e, 3ut +*re than *ne de9initi*n 9*r that cla## e;i#t# Gpre#u+a3ly the#e are di99erent de9initi*n#H) Or !*r#e, i+agine that y*ure !riting a pr*gra+, and a# y*ure 3uilding it y*u add a ne! cla## t* y*ur li3rary that c*n9lict# !ith the na+e *9 an e;i#ting cla##) T* #*lve thi# pr*3le+, y*u +u#t eli+inate all p*tential a+3iguitie#) Thi# i# acc*+pli#hed 3y telling the C# c*+piler e;actly !hat cla##e# y*u !ant u#ing the using key!*rd) using tell# the c*+piler t* 3ring in a "ackage, !hich i# a li3rary *9 cla##e#) G-n *ther language#, a li3rary c*uld c*n#i#t *9 9uncti*n# and data a# !ell a# cla##e#, 3ut re+e+3er that all c*de in C# +u#t 3e !ritten in#ide a cla##)H

#(

Thinking in C

www.ThinkingIn.!et

A*#t *9 the ti+e y*ull 3e u#ing c*+p*nent# 9r*+ the ) ET 5ra+e!*rk S?N) >enerally, i9 *ne cla## in a na+e#pace i# u#e9ul, y*ull !ant t* u#e +*re than *ne cla## 9r*+ that na+e#pace) Thi# i# ea#ily acc*+pli#hed 3y the using key!*rd1 u#ing Sy#te!.Co ection#3

-t i# +*re c*++*n t* i+p*rt a c*llecti*n *9 cla##e# in thi# +anner than t* i+p*rt cla##e# individually)

-he static *e5word


Ordinarily, !hen y*u create a cla## y*u are de#cri3ing h*! *34ect# *9 that cla## l**k and h*! they !ill 3ehave) :*u d*nt actually get anything until y*u create an *34ect *9 that cla## !ith new, and at that p*int data #t*rage i# created and +eth*d# 3ec*+e availa3le) But there are t!* #ituati*n# in !hich thi# appr*ach i# n*t #u99icient) One i# i9 y*u !ant t* have *nly *ne piece *9 #t*rage 9*r a particular piece *9 data, regardle## *9 h*! +any *34ect# are created, *r even i9 n* *34ect# are created) The *ther i# i9 y*u need a +eth*d that i#nt a##*ciated !ith any particular *34ect *9 thi# cla##) That i#, y*u need a +eth*d that y*u can call even i9 n* *34ect# are created) :*u can achieve 3*th *9 the#e e99ect# !ith the static key!*rd) ,hen y*u #ay #*+ething i# static, it +ean# that data *r +eth*d i# n*t tied t* any particular *34ect in#tance *9 that cla##) S* even i9 y*uve never created an *34ect *9 that cla## y*u can call a static +eth*d *r acce## a piece *9 static data) ,ith *rdinary, n*nEstatic data and +eth*d# y*u +u#t create an *34ect and u#e that *34ect t* acce## the data *r +eth*d, #ince n*nEstatic data and +eth*d# +u#t kn*! the particular *34ect they are !*rking !ith) O9 c*ur#e, #ince static +eth*d# d*nt need any *34ect# t* 3e created 3e9*re they are u#ed, they cann*t directl4 acce## n*nEstatic +e+3er# *r +eth*d# 3y #i+ply calling th*#e *ther +e+3er# !ith*ut re9erring t* a na+ed *34ect G#ince n*nEstatic +e+3er# and +eth*d# +u#t 3e tied t* a particular *34ectH) S*+e *34ectE*riented language# u#e the ter+# class data and class methods, +eaning that the data and +eth*d# e;i#t *nly 9*r the cla## a# a !h*le, and n*t 9*r any particular *34ect# *9 the cla##) S*+eti+e# the C# literature u#e# the#e ter+# t**)

Cha"ter )* E-er4thing is an 123ect

#1

T* +ake a data +e+3er *r +eth*d static, y*u #i+ply place the key!*rd 3e9*re the de9initi*n) 5*r e;a+ple, the 9*ll*!ing pr*duce# a static data +e+3er and initiali7e# it1 c a## Static'e#t ; #tatic int i 9 EF3 < *! even i9 y*u +ake t!* #tatic+est *34ect#, there !ill #till 3e *nly *ne piece *9 #t*rage 9*r #tatic+est6i6 B*th *34ect# !ill #hare the #a+e i) C*n#ider1 Static'e#t #t" 9 ne. Static'e#t013 Static'e#t #t2 9 ne. Static'e#t013 =t thi# p*int, 3*th st76i and st86i have the #a+e value *9 &% #ince they re9er t* the #a+e piece *9 +e+*ry) There are t!* !ay# t* re9er t* a static varia3le) =# indicated a3*ve, y*u can na+e it via an *34ect, 3y #aying, 9*r e;a+ple, st86i) :*u can al#* re9er t* it directly thr*ugh it# cla## na+e, #*+ething y*u cann*t d* !ith a n*nE #tatic +e+3er) GThi# i# the pre9erred !ay t* re9er t* a static varia3le #ince it e+pha#i7e# that varia3le# static nature)H Static'e#t.iRR3 The CC *perat*r incre+ent# the varia3le) =t thi# p*int, 3*th st76i and st86i !ill have the value &() Si+ilar l*gic applie# t* #tatic +eth*d#) :*u can re9er t* a #tatic +eth*d either thr*ugh an *34ect a# y*u can !ith any +eth*d, *r !ith the #pecial additi*nal #ynta; Class,ame6.ethod( )) :*u de9ine a #tatic +eth*d in a #i+ilar !ay1 c a## StaticHun ; #tatic *oid 5ncr01 ; Static'e#t.iRR3 < < :*u can #ee that the #tatic:un +eth*d Bncr( ) incre+ent# the static data i) :*u can call Bncr( ) in the typical !ay, thr*ugh an *34ect1 StaticHun #f 9 ne. StaticHun013 #f.5ncr013

#)

Thinking in C

www.ThinkingIn.!et

Or, 3ecau#e Bncr( ) i# a #tatic +eth*d, y*u can call it directly thr*ugh it# cla##1 StaticHun.5ncr013 ,hile static, !hen applied t* a data +e+3er, de9initely change# the !ay the data i# created G*ne 9*r each cla## v#) the n*nE static *ne 9*r each *34ectH, !hen applied t* a +eth*d it# n*t #* dra+atic) =n i+p*rtant u#e *9 static 9*r +eth*d# i# t* all*! y*u t* call that +eth*d !ith*ut creating an *34ect) Thi# i# e##ential, a# !e !ill #ee, in de9ining the .ain( ) +eth*d that i# the entry p*int 9*r running an applicati*n) Like any +eth*d, a static +eth*d can create *r u#e na+ed *34ect# *9 it# type, #* a static +eth*d i# *9ten u#ed a# a I#hepherdJ 9*r a 9l*ck *9 in#tance# *9 it# *!n type)

Putting It )ll -ogether


Let# !rite a pr*gra+) -t #tart# 3y printing a #tring, and then the date, u#ing the $ate+ime cla## 9r*+ the ) ET 5ra+e!*rk S?N) *te that an additi*nal #tyle *9 c*++ent i# intr*duced here1 the T//, !hich i# a c*++ent until the end *9 the line1 // :c0T:Ue o:ate.c# u#ing Sy#te!3 na!e#pace 'hin%ing5n.CSharp.Chap0T; pu$ ic c a## Ue o:ate ; pu$ ic #tatic *oid Gain01 ; Con#o e.VriteLine0&Ue o2 it'#: &13 Con#o e.VriteLine0:ate'i!e.Co.13 < < <///:8 =t the 3eginning *9 each pr*gra+ 9ile, y*u +u#t place the using #tate+ent t* 3ring in any cla##e# y*ull need 9*r the c*de in that 9ile) -9 y*u are !*rking !ith the d*!nl*aded ) ET 5ra+e!*rk S?N, there i# a Aicr*#*9t Help 9ile that can 3e acce##ed !ith mshelpD//ms6netframewor(sd(, i9 u#ing Ci#ual Studi* ) ET, there i# an

Cha"ter )* E-er4thing is an 123ect

#3

integrated help #y#te+) -9 y*u navigate t* mshelpD//.#6,&+:ramewor(#$E/cpref/html/frlrf#ystem6htm , y*ull #ee the c*ntent# *9 the #ystem na+e#pace) One *9 the+ i# the Console cla##) -9 y*u *pen thi# #u34ect and then click *n Console6.embers, y*ull #ee a li#t *9 pu3lic pr*pertie# and +eth*d#) -n the ca#e *9 the Console cla##, all *9 the+ are +arked !ith an ISJ indicating that they are #tatic) One *9 the #tatic +eth*d# *9 Console i# =riteLine( )) Since it# a #tatic +eth*d, y*u d*nt need t* create an *34ect t* u#e it) Thu#, i9 y*uve #peci9ied using #ystemF y*u can !rite Console6=riteLine(G#omethingG) !heneve y*u !ant t* print #*+ething t* the c*n#*le) =lternately, in an4 C# pr*gra+, y*u can #peci9y the $ull4 8uali$ied na+e #ystem6Console6=riteLine(G#omethingG) even i9 y*u have n*t !ritten using #ystem) Every pr*gra+ +u#t have !hat# called an entr4 "oint, a +eth*d !hich #tart# up thing#) -n C#, the entry p*int i# al!ay# a #tatic +eth*d called .ain( )) .ain( ) can 3e !ritten in #everal di99erent !ay#1 #tatic *oid Gain01; L < #tatic *oid Gain0#tringJK arg#1; L < #tatic int Gain01; L < #tatic int Gain0#tringJK arg#1; L < -9 y*u !i#h t* pa## in para+eter# 9r*+ the c*++andEline t* y*ur pr*gra+, y*u #h*uld u#e *ne *9 the 9*r+# that take an array *9 c*++andE line argu+ent#) args<4> !ill 3e the 9ir#t argu+ent a$ter the na+e *9 the e;ecuta3le) Traditi*nally, pr*gra+# return a $ i9 they ran #ucce##9ully and #*+e *ther integer a# an err*r c*de i9 they 9ailed) C## e;cepti*n# are in9initely #uperi*r 9*r c*++unicating #uch pr*3le+#, 3ut i9 y*u are !riting a pr*gra+ that y*u !i#h t* pr*gra+ !ith 3atch 9ile#, y*u +ay !i#h t* u#e a .ain( ) +eth*d that return# an integer) The line that print# the date illu#trate# the 3ehindEtheE#cene# c*+ple;ity *9 even a #i+ple *34ectE*riented call1 Con#o e.VriteLine0:ate'i!e.Co.13

#4

Thinking in C

www.ThinkingIn.!et

C*n#ider the argu+ent1 i9 y*u 3r*!#e the d*cu+entati*n t* the ?ateTi+e #tructure, y*ull di#c*ver that it ha# a #tatic pr*perty ,ow *9 type $ate+ime) =# thi# pr*perty i# read, the ) ET Runti+e read# the #y#te+ cl*ck, create# a ne! $ate+ime value t* #t*re the ti+e, and return# it) =# #**n a# that pr*perty get 9ini#he#, the $ate+ime #truct i# pa##ed t* the #tatic +eth*d =riteLine( ) *9 the Console cla##) -9 y*u u#e the help9ile t* g* t* that +eth*d# de9initi*n, y*ull #ee +any di99erent o-erloaded ver#i*n# *9 =riteLine( ), *ne !hich take# a bool, *ne !hich take# a char, etc) :*u !*nt 9ind *ne that take# a $ate+ime, th*ugh) Since there i# n* *verl*aded ver#i*n that take# the e;act type *9 the $ate+ime argu+ent, the runti+e l**k# 9*r ancestors *9 the argu+ent type) =ll struct# are de9ined a# de#cending 9r*+ type Halue+ype, !hich in turn de#cend# 9r*+ type ob)ect) There i# n*t a ver#i*n *9 =riteLine( ) that take# a Halue+ype 9*r an argu+ent, 3ut there is *ne that take# an ob)ect) -t i# thi# +eth*d that i# called, pa##ing in the $ate+ime #tructure) Back in the d*cu+entati*n 9*r =riteLine( ), it #ay# it call# the +o#tring( ) +eth*d *9 the ob)ect pa##ed in a# it# argu+ent) -9 y*u 3r*!#e t* 1b)ect6+o#tring( ), th*ugh, y*ull #ee that the de9ault repre#entati*n i# 4u#t the 9ully Duali9ied na+e *9 the *34ect) But !hen run, thi# pr*gra+ d*e#nt print *ut ISy#te+)?ateTi+e,J it print# *ut the ti+e value it#el9) Thi# i# 3ecau#e the i+ple+enter# *9 the $ate+ime cla## o-errode the de9ault i+ple+entati*n *9 +o#tring( ) and the call !ithin =riteLine( ) i# re#*lved "ol4mor"hicall4 3y the $ate+ime i+ple+entati*n, !hich return# a cultureE#peci9ic string repre#entati*n *9 it# value t* 3e printed t* the Console) -9 #*+e *9 that d*e#nt +ake #en#e, d*nt !*rry P al+*#t every a#pect *9 *34ectE*rientati*n i# at !*rk !ithin thi# #ee+ingly trivial e;a+ple)

Co#$iling and running


T* c*+pile and run thi# pr*gra+, and all the *ther pr*gra+# in thi# 3**k, y*u +u#t 9ir#t have a c*++andEline C# c*+piler) ,e strongl4 urge y*u t* re9rain 9r*+ u#ing Aicr*#*9t Ci#ual Studi* ) ET# >U-Eactivated c*+piler 9*r c*+piling the #a+ple pr*gra+# in thi# 3**k) The le## that i# 3et!een ra! te;t c*de and the running pr*gra+, the +*re clear the

Cha"ter )* E-er4thing is an 123ect

#5

learning e;perience) Ci#ual Studi* ) ET intr*duce# additi*nal 9ile# t* #tructure and +anage pr*4ect#, 3ut the#e are n*t nece##ary 9*r the #+all #a+ple pr*gra+# u#ed in thi# 3**k) Ci#ual Studi* ) ET ha# #*+e great t**l# that ea#e certain ta#k#, like c*nnecting t* data3a#e# and devel*ping ,ind*!# 5*r+#, 3ut the#e t**l# #h*uld 3e u#ed t* relieve drudgery, n*t a# a #u3#titute 9*r kn*!ledge) = c*++andEline C# c*+piler i# included in Aicr*#*9t# ) ET 5ra+e!*rk S?N, !hich i# availa3le 9*r 9ree d*!nl*ad at +#dn)+icr*#*9t)c*+<d*!nl*ad#< = c*++andEline c*+piler i# al#* included !ithin Aicr*#*9t Ci#ual Studi* ) ET) The c*++andEline c*+piler i# csc6exe) Once y*uve in#talled the S?N, y*u #h*uld 3e a3le t* run csc 9r*+ a c*++andEline pr*+pt) -n additi*n t* the c*++andEline c*+piler, y*u #h*uld have a decent te;t edit*r) S*+e pe*ple #ee+ #ati#9ied !ith ,ind*!# *tepad, 3ut +*#t pr*gra++er# pre9er either the te;t edit*r !ithin Ci#ual Studi*) ET G4u#t u#e 5ile<OpenL and SaveL t* !*rk directly !ith te;t 9ile#H *r a thirdE party pr*gra++er# edit*r) =ll the c*de #a+ple# in thi# 3**k !ere !ritten !ith Ci#ual SlickEdit 9r*+ Aicr*Edge Gan*ther 9av*rite i# C*+puter S*luti*n -nc)# U/' #hare!are UltraEditH) Once the 5ra+e!*rk S?N i# in#talled, d*!nl*ad and unpack the #*urce c*de 9*r thi# 3**k Gy*u can 9ind it at !!!)Thinking-n)netH) Thi# !ill create a #u3direct*ry 9*r each chapter in the 3**k) A*ve t* the #u3direct*ry c49 and type1 c#c Ue o:ate.c# :*u #h*uld #ee a +e##age that #peci9ie# the ver#i*n# *9 the C# c*+piler and ) ET 5ra+e!*rk that are 3eing u#ed Gthe 3**k !a# 9ini#hed !ith C# C*+piler ver#i*n %)$$)6&.. and ) ET 5ra+e!*rk ver#i*n 0)$)/%$'H) There #h*uld 3e n* !arning# *r err*r#Q i9 there are, it# an indicati*n that #*+ething !ent !r*ng !ith the S?N in#tallati*n and y*u need t* inve#tigate th*#e pr*3le+#) On the *ther hand, i9 y*u 4u#t get y*ur c*++and pr*+pt 3ack, y*u can type1 Ue o:ate

and y*ull get the +e##age and the date a# *utput)

#6

Thinking in C

www.ThinkingIn.!et

Thi# i# the pr*ce## y*u can u#e t* c*+pile and run each *9 the pr*gra+# in thi# 3**k) = #*urce 9ile, #*+eti+e# called a com"ilation unit, i# c*+piled 3y csc int* a ) ET assem2l4) By de9ault, the a##e+3ly i# given an e;ten#i*n *9 6exe and, i9 it ha# a .ain( ), the re#ulting a##e+3ly can 3e run 9r*+ the c*++andEline 4u#t a# any *ther pr*gra+)

7ine;tuning Co#$ilation
=n a##e+3ly +ay 3e generated 9r*+ +*re than *ne c*+pilati*n unit) Thi# i# d*ne 3y #i+ply putting the na+e# *9 the additi*nal c*+pilati*n unit# *n the c*++andEline Gcsc :irstClass6cs #econdClass6cs etc)H) :*u can +*di9y the na+e *9 the a##e+3ly !ith the /outD argu+ent) -9 +*re than *ne cla## ha# a .ain( ) de9ined, y*u can #peci9y !hich *ne i# intended t* 3e the entry p*int *9 the a##e+3ly !ith the /mainD argu+ent) *t every a##e+3ly need# t* 3e a #tandEal*ne e;ecuta3le) Such a##e+3lie# #h*uld 3e given the /targetDlibrary argu+ent and !ill 3e c*+piled int* an a##e+3ly !ith a 6$LL e;ten#i*n) By de9ault, a##e+3lie# Ikn*! *9J the #tandard li3rary re9erence mscorlib6dll, !hich c*ntain# the +a4*rity *9 the ) ET 5ra+e!*rk S?N cla##e#) -9 a pr*gra+ u#e# a cla## in a na+e#pace not !ithin the mscorlib6dll a##e+3ly, an a##e+3ly c*ntaining that cla## +u#t 3e either !ithin the current direct*ry, *r the /libD argu+ent #h*uld 3e u#ed t* p*int t* a direct*ry that h*ld# the appr*priate a##e+3ly)

-he Co##on Language 6unti#e


:*u d* n*t need t* kn*! thi#) But !e 3et y*ure curi*u#) The ) ET 5ra+e!*rk ha# #everal layer# *9 a3#tracti*n, 9r*+ very highE level li3rarie# #uch a# ,ind*!# 5*r+# and the SO=P ,e3 Service# #upp*rt, t* the c*re li3rarie# *9 the S?N1

Cha"ter )* E-er4thing is an 123ect

##

Everything in thi# diagra+ e;cept the C*++*n Language Runti+e GCLRH i# #t*red *n the c*+puter in C*++*n -nter+ediate Language GC-L, #*+eti+e# re9erred t* a# Aicr*#*9t -nter+ediate Language, *r AS-L, *r #*+eti+e# 4u#t a# -LH, a very #i+ple I+achine c*deJ 9*r an a3#tract c*+puter) The C# c*+piler, like all ) ET language c*+piler#, tran#9*r+# hu+anE reada3le #*urce c*de int* C-L, n*t the actual *pc*de# *9 any particular CPU) =n a##e+3ly c*n#i#t# *9 C-L, +etadata de#cri3ing the a##e+3ly, and *pti*nal re#*urce#) ,ell di#cu## +etadata in detail in Chapter #re9# !hile re#*urce# !ill 3e di#cu##ed in Chapter 0/) The r*le *9 the C*++*n Language Runti+e can 3e 3*iled d*!n t* I+ediate 3et!een the !*rld *9 C-L and the !*rld *9 the actual plat9*r+)J Thi# reDuire# #everal c*+p*nent#1

?i99erent CPU# and language# have traditi*nally repre#ented #tring# in di99erent !ay# and nu+eric type# u#ing value# *9 di99erent 3itElength#) The

#&

Thinking in C

www.ThinkingIn.!et

value pr*p*#iti*n *9 ) ET i# I=ny language, *ne plat9*r+J Gin c*ntra#t !ith "ava# value pr*p*#iti*n *9 I=ny plat9*r+, *ne language)JH -n *rder t* a##ure that all language# can inter*perate #ea+le##ly ) ET pr*vide# a uni9*r+ de9initi*n *9 #everal 3a#ic type# in the C*++*n Type Sy#te+) Once I3el*!J thi# level, the hu+anEreada3le language in !hich a +*dule !a# *riginal !ritten i# irrelevant) Ta3le # #h*!# the tran#9*r+ati*n *9 a #i+ple +eth*d 9r*+ C# t* C-L t* Pentiu+ +achine c*de) c a## Si!p e; pu$ ic #tatic *oid Gain01; int #u! 9 03 for0int i 9 03 i W P3 iRR1; #u! R9 i3 < Sy#te!.Con#o e.VriteLine0#u!13 < < .!ethod pu$ ic hide$y#ig #tatic *oid !anaged ; .entrypoint // Code #iMe 2P 00x">1 .!ax#tac% 2 . oca # init 0intT2 NX02 intT2 NX"1 5LX0000: dc.iE.0 5LX000": #t oc.0 5LX0002: dc.iE.0 5LX000T: #t oc." 5LX000E: $r.# 5LX000e 5LX000?: d oc.0 5LX000F: d oc." 5LX000I: add 5LX000>: #t oc.0 5LX000a: d oc." 5LX000$: dc.iE." 5LX000c: add 5LX000d: #t oc." 5LX000e: d oc."

Gain01 ci

Cha"ter )* E-er4thing is an 123ect

#'

5LX000f: dc.iE.P 5LX00"0: $ t.# 5LX000? 5LX00"2: d oc.0 5LX00"T: ca *oid J!#cor i$KSy#te!.Con#o e::VriteLine0intT21 5LX00"I: ret < // end of !ethod Si!p e::Gain Security re#tricti*n# are i+ple+ented at thi# level in *rder t* +ake it e;tre+ely di99icult t* 3ypa##) T* #ea+le##ly 3ypa## #ecurity !*uld reDuire replacing the CLR !ith a hacked CLR, n*t i+p*##i3le t* c*nceive, 3ut h*pe9ully 3ey*nd the range *9 #cript kiddie# and reDuiring an ad+ini#trati*nElevel c*+pr*+i#e 9r*+ !hich t* #tart) The #ecurity +*del *9 ) ET c*n#i#t# *9 check# that *ccur at 3*th the +*+ent the cla## i# l*aded int* +e+*ry and at the +*+ent that p*##i3lyEre#tricted *perati*n# are reDue#ted) =lth*ugh C-L i# n*t repre#entative *9 any real +achine c*de, it i# not interpreted) =9ter the C-L *9 a cla## i# l*aded int* +e+*ry, a "u#tE-nETi+e c*+piler G"-TH tran#9*r+# it 9r*+ C-L int* +achine language appr*priate t* the native CPU) One intere#ting 3ene9it *9 thi# i# that it# c*nceiva3le that di99erent "-T c*+piler# +ight 3ec*+e availa3le 9*r di99erent CPU# !ithin a general 9a+ily Gthu#, !e +ight eventually have an -taniu+ "-T, a Pentiu+ "-T, an =thl*n "-T, etc)H) The CLR c*ntain# a #u3#y#te+ re#p*n#i3le 9*r +e+*ry +anage+ent in#ide !hat i# called I+anaged c*de)J -n additi*n t* gar3age c*llecti*n Gthe pr*ce## *9 recycling +e+*ryH, the CLR +e+*ry +anager de9rag+ent# +e+*ry and decrea#e# the #pan *9 re9erence *9 inE+e+*ry re9erence# G3*th *9 !hich are 3ene9icial #ide e99ect# *9 the gar3age c*llecti*n architectureH) 5inally, all pr*gra+# reDuire #*+e 3a#ic e;ecuti*n #upp*rt at the level *9 thread #cheduling, c*de e;ecuti*n, and *ther #y#te+ #ervice#) Once again, at thi# l*! level, all *9 thi# #upp*rt can 3e #hared 3y any ) ET applicati*n, n* +atter !hat the *riginating pr*gra++ing language) The C*++*n Language Runti+e, the 3a#e 9ra+e!*rk cla##e# !ithin +#c*rli3)dll, and the C# language have all 3een #u3+itted t* Aicr*#*9t t* the Eur*pean C*+puter Aanu9acturer# =##*ciati*n GECA=H 9*r

&(

Thinking in C

www.ThinkingIn.!et

rati9icati*n a# #tandard#) The A*n* Pr*4ect G!!!)g*E+*n*)c*+H i# an e99*rt t* create an Open S*urce i+ple+entati*n *9 the#e #tandard# that include# Linu; #upp*rt)

Co##ents and e#+edded docu#entation


There are t!* type# *9 c*++ent# in C#) The 9ir#t i# the traditi*nal CE#tyle c*++ent that !a# inherited 3y C@@) The#e c*++ent# 3egin !ith a /; and c*ntinue, p*##i3ly acr*## +any line#, until a ;/) *te that +any pr*gra++er# !ill 3egin each line *9 a c*ntinued c*++ent !ith a ;, #* y*ull *9ten #ee1 /= 'hi# i# a co!!ent = that continue# = acro## ine# =/ Re+e+3er, h*!ever, that everything in#ide the /; and ;/ i# ign*red, #* there# n* di99erence in #aying1 /= 'hi# i# a co!!ent that continue# acro## ine# =/ The #ec*nd 9*r+ *9 c*++ent c*+e# 9r*+ C@@) -t i# the #ingleEline c*++ent, !hich #tart# at a // and c*ntinue# until the end *9 the line) Thi# type *9 c*++ent i# c*nvenient and c*++*nly u#ed 3ecau#e it# ea#y) :*u d*nt need t* hunt *n the key3*ard t* 9ind / and then ; Gin#tead, y*u 4u#t pre## the #a+e key t!iceH, and y*u d*nt need t* cl*#e the c*++ent) S* y*u !ill *9ten #ee1 // thi# i# a one6 ine co!!ent

4ocu#entation Co##ents
One *9 the th*ught9ul part# *9 the C# language i# that the de#igner# didnt c*n#ider !riting c*de t* 3e the *nly i+p*rtant activityRthey al#* th*ught a3*ut d*cu+enting it) P*##i3ly the 3igge#t pr*3le+ !ith d*cu+enting c*de ha# 3een +aintaining that d*cu+entati*n) -9 the d*cu+entati*n and

Cha"ter )* E-er4thing is an 123ect

&1

the c*de are #eparate, it 3ec*+e# a ha##le t* change the d*cu+entati*n every ti+e y*u change the c*de) The #*luti*n #ee+# #i+ple1 link the c*de t* the d*cu+entati*n) The ea#ie#t !ay t* d* thi# i# t* put everything in the #a+e 9ile) T* c*+plete the picture, h*!ever, y*u need a #pecial c*++ent #ynta; t* +ark #pecial d*cu+entati*n, and a t**l t* e;tract th*#e c*++ent# and put the+ in a u#e9ul 9*r+) Thi# i# !hat C# ha# d*ne) C*++ent# that 3egin !ith <<< can 3e e;tracted 9r*+ #*urce 9ile# 3y running csc /docD1utput:ile6?.L) -n#ide the c*++ent# y*u can place any valid BAL tag# including #*+e tag# !ith prede9ined +eaning# di#cu##ed ne;t) The re#ulting BAL 9ile i# interpreted in certain !ay# in#ide *9 Ci#ual Studi* ) ET *r can 3e #tyled !ith BSLT t* pr*duce a ,e3 page *r printa3le d*cu+entati*n) -9 y*u d*nt under#tand BAL, d*nt !*rry a3*ut itQ y*ull 3ec*+e +uch +*re 9a+iliar !ith it in Chapter 0&K -9 y*u run c#c /doc:Ue o:ate.x! Ue o:ate.c#

The re#ulting BAL !ill 3e1 WYx! *er#ion9&".0&YZ WdocZ Wa##e!$ yZ Wna!eZUe o:ateW/na!eZ W/a##e!$ yZ W!e!$er#Z W/!e!$er#Z W/docZ The BAL c*n#i#t# *9 a Id*cJ ele+ent, !hich i# 9*r the a##e+3ly na+ed IHell*?ateJ and !hich d*e#nt have any d*cu+entati*n c*++ent#) Tag V#u++aryW V<#u++aryW Vre+ark#W V<re+ark#W Vpara+ Sugge#ted U#e = 3rie9 *vervie! *9 the c*de ele+ent Thi# i# u#ed 9*r a +*re c*+prehen#ive di#cu##i*n *9 the ele+ent# intended 3ehavi*r One *9 the#e tag# #h*uld 3e !ritten 9*r each argu+ent

&)

Thinking in C

www.ThinkingIn.!et

na+eXYna+eYW V<para+W

t* a +eth*dQ the value *9 the name attri3ute #peci9ie# !hich argu+ent) The de#cripti*n #h*uld include any prec*nditi*n# a##*ciated !ith the argu+ent) Prec*nditi*n# are !hat the +eth*d reDuire# *9 it# argu+ent# #* that the +eth*d can 9uncti*n c*rrectly) 5*r in#tance, a prec*nditi*n *9 a #Duare r**t 9uncti*n +ight 3e that the input integer 3e p*#itive) Aeth*d# that return anything *ther than v*id #h*uld have *ne *9 the#e tag#) The c*ntent# *9 the tag #h*uld de#cri3e !hat a3*ut the return value can 3e guaranteed) Can it 3e nullF ?*e# it al!ay# 9all !ithin a certain rangeF -# it al!ay# in a certain #tateF etc) Every e;cepti*n that i# e;plicitly rai#ed !ithin the +eth*d# 3*dy #h*uld 3e d*cu+ented in a tag #uch a# thi# Gthe type *9 the e;cepti*n #h*uld 3e the value *9 the cref attri3uteH) T* the e;tent p*##i3le, the circu+#tance# !hich give ri#e t* the e;cepti*n 3eing thr*!n #h*uld 3e detailed) Becau#e *9 C## e;cepti*n +*del Gdi#cu##ed in chapter #re9#H, #pecial attenti*n #h*uld 3e paid t* +aking #ure that the#e c*++ent# are c*n#i#tently and uni9*r+ly !ritten and +aintained) Thi# tag de#cri3e# the #ecurity per+i##i*n# that are reDuired 9*r the type) The cref attri3ute i# *pti*nal, 3ut i9 it e;i#t#, it #h*uld re9er t* a Per+i##i*nSet a##*ciated !ith the type) The Ve;a+pleW tag #h*uld c*ntain a de#cripti*n *9 a #a+ple u#e *9 the c*de ele+ent) The VcW tag i# intended t* #peci9y an inline c*de ele+ent !hile the Vc*deW tag i# intended 9*r +ultiline #nippet#)

Vreturn#W V<return#W

Ve;cepti*n cre9XYtypeYW V<e;cepti*nW

Vper+i##i*n cre9XYtypeYW V<per+i##i*nW Ve;a+pleW VcWV<cW Vc*deWV<c*deW V<e;a+pleW

Cha"ter )* E-er4thing is an 123ect

&3

V#ee cre9XY*therYW V<#eeW V#eeal#* cre9XY*therYW V<#eeal#*W VvalueW V<valueW Vpara+re9 na+eXYargY<W Vli#t typeX Z3ullet [ nu+3er [ ta3le\W Vli#theaderW Vter+WV<ter+W Vde#cripti*nW V<de#cripti*nW V<li#theaderW Vite+W Vter+WV<ter+W Vde#cripti*nW V<de#cripti*nW V<ite+W V<li#tW VparaWV<paraW

The#e tag# are intended 9*r cr*## re9erence# t* *ther c*de ele+ent# *r *ther d*cu+entati*n 9rag+ent#) The V#eeW tag i# intended 9*r inline cr*##Ere9erence#, !hile the V#eeal#*W tag i# intended t* 3e 3r*ken *ut int* a #eparate ISee =l#*J #ecti*n Every e;ternally vi#i3le pr*perty !ithin a cla## #h*uld 3e d*cu+ented !ith thi# tag Thi# e+pty tag i# u#ed !hen c*++enting a +eth*d t* indicate that the value *9 the name attri3ute i# actually the na+e *9 *ne *9 the +eth*d# argu+ent#) -ntended t* pr*vide a hint t* the BAL #tyler *n h*! t* generate d*cu+entati*n)

-ntended t* #peci9y #eparate paragraph# !ithin a de#cripti*n *r *ther lengthy te;t 3l*ck

4ocu#entation e&a#$le
Here# the Hell*?ate C# pr*gra+, thi# ti+e !ith d*cu+entati*n c*++ent# added1 // :c0T:Ue o:ate2.c# u#ing Sy#te!3

&4

Thinking in C

www.ThinkingIn.!et

na!e#pace 'hin%ing5n.CSharp.Chap0T; ///W#u!!aryZSho.# doc co!!ent#W/#u!!aryZ ///Wre!ar%#Z'he docu!entation co!!ent# .ithin C( ///are re!ar%a$ y u#efu 2 $oth .ithin the Ni#ua ///Studio en*iron!ent and a# the $a#i# for !ore ///#ignificant printed docu!entationW/re!ar%#Z pu$ ic c a## Ue o:ate2 ; ///W#u!!aryZ+ntry pointW/#u!!aryZ ///Wre!ar%#Z-rint# greeting to /// Wpara!ref na!e9&arg#J0K&/Z2 get# a /// W#ee cref9&Sy#te!.:ate'i!e&Z:ate'i!eW/#eeZ /// and #u$#e7uent y print# itW/re!ar%#Z ///Wpara! na!e9&arg#&ZCo!!and6 ine #hou d ha*e a ///#ing e na!e. ) other arg# .i $e ignored ///W/para!Z pu$ ic #tatic *oid Gain0#tringJK arg#1 ; Con#o e.VriteLine0&Ue o2 ;0< it'#: &2 arg#J0K13 Con#o e.VriteLine0:ate'i!e.Co.13 < < <//:8 ,hen csc e;tract# the data, it i# in thi# 9*r+1 WYx! *er#ion9&".0&YZ WdocZ Wa##e!$ yZ Wna!eZUe o:ateW/na!eZ W/a##e!$ yZ W!e!$er#Z W!e!$er na!e9&':'hin%ing5n.CSharp.Chap0T.Ue o:ate2&Z W#u!!aryZSho.# doc co!!ent#W/#u!!aryZ Wre!ar%#Z'he docu!entation co!!ent# .ithin C( are re!ar%a$ y u#efu 2 $oth .ithin the Ni#ua Studio en*iron!ent and a# the $a#i# for !ore #ignificant printed docu!entationW/re!ar%#Z W/!e!$erZ W!e!$er

Cha"ter )* E-er4thing is an 123ect

&5

na!e9&G:'hin%ing5n.CSharp.Chap0T.Ue o:ate2.Gain0Sy#te !.StringJK1&Z W#u!!aryZ+ntry pointW/#u!!aryZ Wre!ar%#Z-rint# greeting to Wpara!ref na!e9&arg#J0K&/Z2 get# a W#ee cref9&':Sy#te!.:ate'i!e&Z:ate'i!eW/#eeZ and #u$#e7uent y print# itW/re!ar%#Z Wpara! na!e9&arg#&ZCo!!and6 ine #hou d ha*e a #ing e na!e. ) other arg# .i $e ignored W/para!Z W/!e!$erZ W/!e!$er#Z W/docZ The 9ir#t line *9 the Hell*?ate2)c# 9ile u#e# a c*nventi*n that !ill 3e u#ed thr*ugh*ut the 3**k) Every c*+pila3le #a+ple 3egin# !ith a c*++ent 9*ll*!ed 3y a T1 the chapter nu+3er, an*ther c*l*n, and the na+e *9 the 9ile that the e;a+ple #h*uld 3e #aved t*) The la#t line al#* 9ini#he# !ith a c*++ent, and thi# *ne indicate# the end *9 the #*urce c*de li#ting, !hich all*!# it t* 3e aut*+atically e;tracted 9r*+ the te;t *9 thi# 3**k and checked !ith a c*+piler) Thi# c*nventi*n #upp*rt# a t**l !hich can aut*+atically e;tract and c*+pile c*de directly 9r*+ the I#*urceJ ,*rd d*cu+ent)

Coding st5le
The un*99icial #tandard in C# i# t* capitali7e the 9ir#t letter *9 a cla## na+e) -9 the cla## na+e c*n#i#t# *9 #everal !*rd#, they are run t*gether Gthat i#, y*u d*nt u#e under#c*re# t* #eparate the na+e#H, and the 9ir#t letter *9 each e+3edded !*rd i# capitali7ed, #uch a#1 c a## ) 'heCo or#Of'heRain$o. ; // ...

Thi# #a+e #tyle i# al#* u#ed 9*r the part# *9 the cla## !hich are intended t* 3e re9ered t* 3y *ther# G+eth*d na+e# and pr*pertie#H) 5*r internal part# 9ield# G+e+3er varia3le#H and *34ect re9erence na+e#, the accepted #tyle i# 4u#t a# it i# 9*r cla##e# e%ce"t that the 9ir#t letter *9 the identi9ier i# l*!erca#e) 5*r e;a+ple1 c a## ) 'heCo or#Of'heRain$o. ; int an5ntegerRepre#entingCo or#3

&6

Thinking in C

www.ThinkingIn.!et

*oid Change'heUueOf'heCo or0int ne.Uue1 ; // ... < // ... < O9 c*ur#e, y*u #h*uld re+e+3er that the u#er +u#t al#* type all the#e l*ng na+e#, and #* 3e +erci9ul)

'u##ar5
-n thi# chapter y*u have #een en*ugh *9 C# pr*gra++ing t* under#tand h*! t* !rite a #i+ple pr*gra+, and y*u have g*tten an *vervie! *9 the language and #*+e *9 it# 3a#ic idea#) H*!ever, the e;a+ple# #* 9ar have all 3een *9 the 9*r+ Id* thi#, then d* that, then d* #*+ething el#e)J ,hat i9 y*u !ant the pr*gra+ t* +ake ch*ice#, #uch a# Ii9 the re#ult *9 d*ing thi# i# red, d* thatQ i9 n*t, then d* #*+ething el#eJF The #upp*rt in C# 9*r thi# 9unda+ental pr*gra++ing activity !ill 3e c*vered in the ne;t chapter)

%&ercises
1.
5*ll*!ing the "ello$ate6cs e;a+ple in thi# chapter, create a Ihell*, !*rldJ pr*gra+ that #i+ply print# *ut that #tate+ent) :*u need *nly a #ingle +eth*d in y*ur cla## Gthe IAainJ *ne that get# e;ecuted !hen the pr*gra+ #tart#H) Re+e+3er t* +ake it static) C*+pile the pr*gra+ !ith csc and run it 9r*+ the c*++andEline) 5ind the c*de 9rag+ent# inv*lving '+ype,ame and turn the+ int* a pr*gra+ that c*+pile# and run#) Turn the $ata1nly c*de 9rag+ent# int* a pr*gra+ that c*+pile# and run#) A*di9y E;erci#e / #* that the value# *9 the data in $ata1nly are a##igned t* and printed in .ain( )) ,rite a pr*gra+ that include# and call# the #torage( ) +eth*d de9ined a# a c*de 9rag+ent in thi# chapter)

2. 3. . !.

Cha"ter )* E-er4thing is an 123ect

&#

". C.

Turn the #tatic:un c*de 9rag+ent# int* a !*rking pr*gra+) ,rite a pr*gra+ that print# three argu+ent# taken 9r*+ the c*++and line) T* d* thi#, y*ull need t* inde; int* the c*++andE line array *9 string#) Turn the 'll+heColors1f+he*ainbow e;a+ple int* a pr*gra+ that c*+pile# and run#) 5ind the c*de 9*r the #ec*nd ver#i*n *9 "ello$ate6cs, !hich i# the #i+ple c*++ent d*cu+entati*n e;a+ple) E;ecute csc /doc *n the 9ile and vie! the re#ult# !ith y*ur BALEa!are ,e3 3r*!#er) Turn $oc+est int* a 9ile that c*+pile# and then c*+pile it !ith csc /doc) Ceri9y the re#ulting d*cu+entati*n !ith y*ur ,e3 3r*!#er) =dd an HTAL li#t *9 ite+# t* the d*cu+entati*n in E;erci#e 0$) Take the pr*gra+ in E;erci#e 0 and add c*++ent d*cu+entati*n t* it) E;tract thi# c*++ent d*cu+entati*n and vie! it !ith y*ur ,e3 3r*!#er)

D. E.

1F.

11. 12.

&&

Thinking in C

www.ThinkingIn.!et

, Controlling Progra# 7low


Ot*d*1 Break 9ir#t part int* a chapter called, +ay3e IType# and *perat*r#J and the #ec*nd part G#tarting at I5l*! C*ntr*lJH int* IC*ntr*lling pr*gra+ 9l*!)J Ot*d*1 Sh*rt #ecti*n *n re9erence v#) value type#) Aay3e #*+e diagra+# *n #tack, heap, p*inter#, etc)F Like a #entient creature, a pr*gra+ +u#t +anipulate it# !*rld and +ake ch*ice# during e;ecuti*n)
-n C# y*u +anipulate *34ect# and data u#ing *perat*r#, and y*u +ake ch*ice# !ith e;ecuti*n c*ntr*l #tate+ent#) The #tate+ent# u#ed !ill 3e 9a+iliar t* pr*gra++er# !ith "ava, C@@, *r C 3ackgr*und#, 3ut there are a 9e! that +ay #ee+ unu#ual t* pr*gra++er# c*+ing 9r*+ Ci#ual Ba#ic 3ackgr*und#)

>sing C#o$erators
=n *perat*r take# *ne *r +*re argu+ent# and pr*duce# a ne! value) The argu+ent# are in a di99erent 9*r+ than *rdinary +eth*d call#, 3ut the e99ect i# the #a+e) :*u #h*uld 3e rea#*na3ly c*+9*rta3le !ith the general c*ncept *9 *perat*r# 9r*+ y*ur previ*u# pr*gra++ing e;perience) =dditi*n GCH, #u3tracti*n and unary +inu# G-H, +ultiplicati*n G;H, divi#i*n G/H, and a##ign+ent GIH all !*rk +uch the #a+e in any pr*gra++ing language) =ll *perat*r# pr*duce a value 9r*+ their *perand#) -n additi*n, an *perat*r can change the value *9 an *perand) Thi# i# called a side e$$ect) The +*#t c*++*n u#e 9*r *perat*r# that +*di9y their *perand# i# t* generate the #ide e99ect, 3ut y*u #h*uld keep in +ind that the value

&'

pr*duced i# availa3le 9*r y*ur u#e 4u#t a# in *perat*r# !ith*ut #ide e99ect#) Operat*r# !*rk !ith all pri+itive# and +any *34ect#) ,hen y*u pr*gra+ y*ur *!n *34ect#, y*u !ill 3e a3le t* e;tend the+ t* #upp*rt !hichever pri+itive# +ake #en#e Gy*ull 9ind y*ur#el9 creating T@ *perati*n# 9ar +*re *9ten than T< *perati*n#KH The *perat*r# 2I, TII and T!I, !*rk 9*r all *34ect# and are a p*int *9 c*n9u#i*n 9*r *34ect# that !ell deal !ith in #re9erence#)

Precedence
Operat*r precedence de9ine# h*! an e;pre##i*n evaluate# !hen #everal *perat*r# are pre#ent) C# ha# #peci9ic rule# that deter+ine the *rder *9 evaluati*n) The ea#ie#t *ne t* re+e+3er i# that +ultiplicati*n and divi#i*n happen 3e9*re additi*n and #u3tracti*n) Pr*gra++er# *9ten 9*rget the *ther precedence rule#, #* y*u #h*uld u#e parenthe#e# t* +ake the *rder *9 evaluati*n e;plicit) 5*r e;a+ple1 a 9 x R y 6 2/2 R M3 ha# a very di99erent +eaning 9r*+ the #a+e #tate+ent !ith a particular gr*uping *9 parenthe#e#1 a 9 x R 0y 6 21/02 R M13

)ssign#ent
=##ign+ent i# per9*r+ed !ith the *perat*r X) -t +ean# Itake the value *9 the rightEhand #ide G*9ten called the r-alueH and c*py it int* the le9tEhand #ide G*9ten called the l-alueH) =n rvalue i# any c*n#tant, varia3le *r e;pre##i*n that can pr*duce a value, 3ut an lvalue +u#t 3e a di#tinct, na+ed varia3le) GThat i#, there +u#t 3e a phy#ical #pace t* #t*re a value)H 5*r in#tance, y*u can a##ign a c*n#tant value t* a varia3le G ' I JFH, 3ut y*u cann*t a##ign anything t* c*n#tant valueRit cann*t 3e an lvalue) G:*u cant #ay J I 'F)H =##ign+ent *9 pri+itive# i# Duite #traight9*r!ard) Since the pri+itive h*ld# the actual value and n*t a re9erence t* an *34ect, !hen y*u a##ign pri+itive# y*u c*py the c*ntent# 9r*+ *ne place t* an*ther) 5*r e;a+ple, i9 y*u #ay ' I B 9*r pri+itive#, then the c*ntent# *9 B are c*pied int* ') -9

'(

y*u then g* *n t* +*di9y ', B i# naturally una99ected 3y thi# +*di9icati*n) =# a pr*gra++er, thi# i# !hat y*uve c*+e t* e;pect 9*r +*#t #ituati*n#) ,hen y*u a##ign *34ect#, h*!ever, thing# change) ,henever y*u +anipulate an *34ect, !hat y*ure +anipulating i# the re9erence, #* !hen y*u a##ign I9r*+ *ne *34ect t* an*therJ y*ure actually c*pying a re9erence 9r*+ *ne place t* an*ther) Thi# +ean# that i9 y*u #ay C I $ 9*r *34ect#, y*u end up !ith 3*th C and $ p*inting t* the *34ect that, *riginally, *nly $ p*inted t*) The 9*ll*!ing e;a+ple !ill de+*n#trate thi#) Here# the e;a+ple1 //: c0T: )##ign!ent.c# c a## Cu!$er; pu$ ic int i3 < pu$ ic c a## )##ign!ent; pu$ ic #tatic *oid Gain01; Cu!$er n" 9 ne. Cu!$er013 Cu!$er n2 9 ne. Cu!$er013 n".i 9 >3 n2.i 9 EF3 Sy#te!.Con#o e.VriteLine0 &": n".i: & R n".i R &2 n2.i: & R n2.i13 n".i 9 n2.i3 Sy#te!.Con#o e.VriteLine0 &2: n".i: & R n".i R &2 n2.i: & R n2.i13 n".i 9 2F3 Sy#te!.Con#o e.VriteLine0 &T: n".i: & R n".i R &2 n2.i: & R n2.i13 < < ///:8
]

The ,umber cla## i# #i+ple, and t!* in#tance# *9 it Gn7 and n8H are created !ithin Aain( )) The i value !ithin each ,umber i# given a di99erent value, and then n8 i# a##igned t* n7, and n7 i# changed) -n +any pr*gra++ing language# y*u !*uld e;pect n7 and n8 t* 3e independent

Cha"ter 3* Controlling /rogram +low

'1

at all ti+e#, 3ut 3ecau#e y*uve a##igned a re9erence here# the *utput y*ull #ee1 ": n".i: >2 n2.i: EF 2: n".i: EF2 n2.i: EF T: n".i: 2F2 n2.i: 2F Changing the n7 *34ect appear# t* change the n8 *34ect a# !ellK Thi# i# 3ecau#e 3*th n7 and n8 c*ntain the #a+e re9erence, !hich i# p*inting t* the #a+e *34ect) GThe *riginal re9erence that !a# in n7 that p*inted t* the *34ect h*lding a value *9 6 !a# *ver!ritten during the a##ign+ent and e99ectively l*#tQ it# *34ect !ill 3e cleaned up 3y the gar3age c*llect*r)H Thi# phen*+en*n i# called aliasing and it# a 9unda+ental !ay that C# !*rk# !ith *34ect#) But !hat i9 y*u d*nt !ant alia#ing t* *ccur in thi# ca#eF :*u c*uld 9*reg* the a##ign+ent and #ay1 n".i 9 n2.i3 Thi# retain# the t!* #eparate *34ect# in#tead *9 t*##ing *ne and tying n7 and n8 t* the #a+e *34ect, 3ut y*ull #**n reali7e that +anipulating the 9ield# !ithin *34ect# i# +e##y and g*e# again#t g**d *34ectE*riented de#ign principle#)

)liasing during #ethod calls


=lia#ing !ill al#* *ccur !hen y*u pa## an *34ect int* a +eth*d1 //: c0T: -a##O$Dect.c# na!e#pace c0T; c a## Letter; pu$ ic char c3 < pu$ ic c a## -a##O$Dect; #tatic *oid f0Letter y1; y.c 9 'M'3 < pu$ ic #tatic *oid Gain01; Letter x 9 ne. Letter013 x.c 9 'a'3

')

Thinking in C

www.ThinkingIn.!et

Sy#te!.Con#o e.VriteLine0&": x.c: & R x.c13 f0x13 Sy#te!.Con#o e.VriteLine0&2: x.c: & R x.c13 < < <///:8 -n +any pr*gra++ing language#, the +eth*d :( ) !*uld appear t* 3e +aking a c*py *9 it# argu+ent Letter y in#ide the #c*pe *9 the +eth*d) But *nce again a re9erence i# 3eing pa##ed #* the line y.c 9 'M'3 i# actually changing the *34ect *ut#ide *9 :( )) The *utput #h*!# thi#1 ": x.c: a 2: x.c: M

@athe#atical o$erators
The 3a#ic +athe+atical *perat*r# are the #a+e a# the *ne# availa3le in +*#t pr*gra++ing language#1 additi*n GCH, #u3tracti*n G-H, divi#i*n G/H, +ultiplicati*n G;H and +*dulu# GK, !hich pr*duce# the re+ainder 9r*+ integer divi#i*nH) -nteger divi#i*n truncate#, rather than r*und#, the re#ult) "ava al#* u#e# a #h*rthand n*tati*n t* per9*r+ an *perati*n and an a##ign+ent at the #a+e ti+e) Thi# i# den*ted 3y an *perat*r 9*ll*!ed 3y an eDual #ign, and i# c*n#i#tent !ith all the *perat*r# in the language G!henever it +ake# #en#eH) 5*r e;a+ple, t* add & t* the varia3le x and a##ign the re#ult t* x, u#e1 x CI J) Thi# e;a+ple #h*!# the u#e *9 the +athe+atical *perat*r#1 //: c0T:GathOp#.c# na!e#pace c0T; u#ing Sy#te!3 pu$ ic c a## GathOp#;

Cha"ter 3* Controlling /rogram +low

'3

///Create a #horthand function to #a*e typing #tatic *oid -rt0String #1; Sy#te!.Con#o e.VriteLine0#13 < ///-rint# a #tring and an int: #tatic *oid -5nt0String #2 int i1; -rt0# R & 9 & R i13 < //Shorthand to print a #tring and a f oat #tatic *oid -:ou$ e0String #2 dou$ e f1; -rt0# R & 9 & R f13 < pu$ ic #tatic *oid Gain01; //Create a rando! nu!$er generator2 //#eed# .ith current ti!e $y defau t Rando! rand 9 ne. Rando!013 int i2 D2 %3 //get a po#iti*e rando! nu!$er e## than the #pecified !axi!u! D 9 rand.Cext0"0013 % 9 rand.Cext0"0013 -5nt0&D&2D13 -5nt0&%&2%13 i 9 D R %3 -5nt0&D R %&2 i13 i 9 D 6 %3 -5nt0&D 6 %&2 i13 i 9 % / D3 -5nt0&% / D&2 i13 i 9 % = D3 -5nt0&% = D&2 i13 //Li!it# i to a po#iti*e nu!$er e## than D i 9 % [ D3 -5nt0&% [ D&2 i13 D [9 %3 -5nt0&D [9 %&2 D13 //H oating6point nu!$er te#t#: dou$ e u2 *2 .3 * 9 rand.Cext:ou$ e013 .9 rand.Cext:ou$ e013 -:ou$ e0&*&2 *13 -:ou$ e0&.&2.13 u 9 * R .3 -:ou$ e0&* R .&2 u13 u 9 * 6 .3 -:ou$ e0&* 6 .&2 u13 u 9 * = .3 -:ou$ e0&* = .&2 u13

'4

Thinking in C

www.ThinkingIn.!et

u 9 * / .3 -:ou$ e0&* / .&2 u13 //the fo o.ing a #o .or%# for //char2 $yte2 #hort2 int2 ong2 //and f oat \todo chec% u R9 *3 -:ou$ e0&u R9 *&2 u13 u 69 *3 -:ou$ e0&u 69 *&2 u13 u =9 *3 -:ou$ e0&u =9 *&2 u13 u /9 *3 -:ou$ e0&u /9 *&2 u13 < < <///:8 The 9ir#t thing y*u !ill #ee are #*+e #h*rthand +eth*d# 9*r printing1 the !rt( ) +eth*d print# a #tring, the !Bnt( ) print# a #tring 9*ll*!ed 3y an int and the !$ouble( ) print# a #tring 9*ll*!ed 3y a double) O9 c*ur#e, they all ulti+ately end up u#ing #ystem6Console6=riteLine( )) T* generate nu+3er#, the pr*gra+ 9ir#t create# a *andom *34ect) Becau#e n* argu+ent# are pa##ed during creati*n, C# u#e# the current ti+e a# a #eed 9*r the rand*+ nu+3er generat*r) The pr*gra+ generate# a nu+3er *9 di99erent type# *9 rand*+ nu+3er# !ith the *andom *34ect #i+ply 3y calling the +eth*d#1 ,ext ( ) and ,ext$ouble( ) Gy*u can al#* call extLong( ) *r ,ext(int)H)

>nar5 #inus and $lus o$erators


The unary +inu# GEH and unary plu# G@H are the #a+e *perat*r# a# 3inary +inu# and plu#) The c*+piler 9igure# *ut !hich u#e i# intended 3y the !ay y*u !rite the e;pre##i*n) 5*r in#tance, the #tate+ent x 9 6a3 ha# an *3vi*u# +eaning) The c*+piler i# a3le t* 9igure *ut1 x 9 a = 6$3 3ut the reader +ight get c*n9u#ed, #* it i# clearer t* #ay1

Cha"ter 3* Controlling /rogram +low

'5

x 9 a = 06$13 The unary +inu# pr*duce# the negative *9 the value) Unary plu# pr*vide# #y++etry !ith unary +inu#, alth*ugh it d*e#nt have any e99ect)

)uto incre#ent and decre#ent


C#, like C, i# 9ull *9 #h*rtcut#) Sh*rtcut# can +ake c*de +uch ea#ier t* type, and either ea#ier *r harder t* read) T!* *9 the nicer #h*rtcut# are the incre+ent and decre+ent *perat*r# G*9ten re9erred t* a# the aut*Eincre+ent and aut*Edecre+ent *perat*r#H) The decre+ent *perat*r i# -- and +ean# Idecrea#e 3y *ne unit)J The incre+ent *perat*r i# CC and +ean# Iincrea#e 3y *ne unit)J -9 a i# an int, 9*r e;a+ple, the e;pre##i*n CCa i# eDuivalent t* Ga I a C 7H) -ncre+ent and decre+ent *perat*r# pr*duce the value *9 the varia3le a# a re#ult) There are t!* ver#i*n# *9 each type *9 *perat*r, *9ten called the pre9i; and p*#t9i; ver#i*n#) PreEincre+ent +ean# the CC *perat*r appear# 3e9*re the varia3le *r e;pre##i*n, and p*#tEincre+ent +ean# the CC *perat*r appear# a9ter the varia3le *r e;pre##i*n) Si+ilarly, preEdecre+ent +ean# the -- *perat*r appear# 3e9*re the varia3le *r e;pre##i*n, and p*#tE decre+ent +ean# the -- *perat*r appear# a9ter the varia3le *r e;pre##i*n) 5*r preEincre+ent and preEdecre+ent, Gi)e), CCa *r --aH, the *perati*n i# per9*r+ed and the value i# pr*duced) 5*r p*#tEincre+ent and p*#tE decre+ent Gi)e) aCC *r a--H, the value i# pr*duced, then the *perati*n i# per9*r+ed) =# an e;a+ple1 //: c0T:)uto5nc.c# na!e#pace c0T; u#ing Sy#te!3 pu$ ic c a## )uto5nc; pu$ ic #tatic *oid Gain01; int i 9 "3 prt0&i: & R i13 prt0&RRi: & R RRi13 //-re6incre!ent prt0&iRR: & R iRR13 //-o#t6incre!ent prt0&i: & R i13 prt0&66i: & R 66i13 //-re6incre!ent

'6

Thinking in C

www.ThinkingIn.!et

prt0&i66: & R i6613 //-o#t6incre!ent prt0&i: & R i13 < #tatic *oid prt0String #1; Sy#te!.Con#o e.VriteLine0#13 < < <///:8
]

The *utput 9*r thi# pr*gra+ i#1 i : RRi iRR i : 66i i66 i : " : : T : : " 2 2 2 2

:*u can #ee that 9*r the pre9i; 9*r+ y*u get the value a9ter the *perati*n ha# 3een per9*r+ed, 3ut !ith the p*#t9i; 9*r+ y*u get the value 3e9*re the *perati*n i# per9*r+ed) The#e are the *nly *perat*r# G*ther than th*#e inv*lving a##ign+entH that have #ide e99ect#) GThat i#, they change the *perand rather than u#ing 4u#t it# value)H The incre+ent *perat*r i# *ne e;planati*n 9*r the na+e C@@, i+plying I*ne #tep 3ey*nd C)J =# 9*r C#, the e;planati*n #ee+# t* 3e in +u#ic, !here the # #y+3*li7e# I#harpJ P a hal9E#tep Iup)J

6elational o$erators
Relati*nal *perat*r# generate a 3**lean re#ult) They evaluate the relati*n#hip 3et!een the value# *9 the *perand#) = relati*nal e;pre##i*n pr*duce# true i9 the relati*n#hip i# true, and false i9 the relati*n#hip i# untrue) The relati*nal *perat*r# are le## than GVH, greater than GWH, le## than *r eDual t* GVXH, greater than *r eDual t* GWXH, eDuivalent GXXH and n*t eDuivalent GKXH) EDuivalence and n*neDuivalence !*rk !ith all 3uiltE in data type#, 3ut the *ther c*+pari#*n# !*nt !*rk !ith type bool)

Cha"ter 3* Controlling /rogram +low

'#

-esting o+/ect equivalence


The relati*nal *perat*r# II and !I al#* !*rk !ith all *34ect#, 3ut their +eaning *9ten c*n9u#e# the 9ir#tEti+e C# pr*gra++er) Here# an e;a+ple1 //: c0T:+7ua #Operator.c# na!e#pace c0T; u#ing Sy#te!3 c a## Gy5nt; 5ntT2 i3 pu$ ic Gy5nt0int D1; i 9 D3 < < ///:e!on#trate# hand e ine7ui*a ence. pu$ ic c a## +7ua #Operator; pu$ ic #tatic *oid Gain01; Gy5nt !" 9 ne. Gy5nt0EF13 Gy5nt !2 9 ne. Gy5nt0EF13 Sy#te!.Con#o e.VriteLine0&!" 99 !2: & R 0!" 99 !2113 < < <///:8 The e;pre##i*n #ystem6Console6=riteLine(n7 II n8) !ill print the re#ult *9 the bool c*+pari#*n !ithin it) Surely the *utput #h*uld 3e true and then false, #ince 3*th .yBnt *34ect# have the #a+e value) But !hile the contents *9 the *34ect# are the #a+e, the re9erence# are n*t the #a+e and the *perat*r# II and !I c*+pare *34ect re9erence#) S* the *utput i# actually false and then true) aturally, thi# #urpri#e# pe*ple at 9ir#t) ,hat i9 y*u !ant t* c*+pare the actual c*ntent# *9 an *34ect 9*r eDuivalenceF 5*r *34ect# in a !ellEde#igned cla## li3rary G#uch a# the ) ET 9ra+e!*rkH, y*u 4u#t u#e the eDuivalence *perat*r#) H*!ever, i9 y*u create y*ur *!n cla##, y*u +u#t o-erride 2II5 in y*ur ne! cla## t* get the de#ired 3ehavi*r) Un9*rtunately, y*u !*nt learn a3*ut *verriding until Chapter %, 3ut 3eing a!are *9 the !ay 2II5 3ehave# +ight #ave y*u #*+e grie9 in the +eanti+e)

'&

Thinking in C

www.ThinkingIn.!et

Logical o$erators
Each *9 the l*gical *perat*r# = ? G88H, OR G[[H and OT GKH pr*duce# a bool value *9 true *r false 3a#ed *n the l*gical relati*n#hip *9 it# argu+ent#) Thi# e;a+ple u#e# the relati*nal and l*gical *perat*r#1 //: c0T:Boo .c# na!e#pace c0T; u#ing Sy#te!3 // Re ationa and ogica operator#. pu$ ic c a## Boo ; pu$ ic #tatic *oid Gain01 ; Rando! rand 9 ne. Rando!013 int i 9 rand.Cext0"0013 int D 9 rand.Cext0"0013 prt0&i 9 & R i13 prt0&D 9 & R D13 prt0&i Z D i# & R 0i Z D113 prt0&i W D i# & R 0i W D113 prt0&i Z9 D i# & R 0i Z9 D113 prt0&i W9 D i# & R 0i W9 D113 prt0&i 99 D i# & R 0i 99 D113 prt0&i !9 D i# & R 0i !9 D113 // 'reating an int a# a $oo ean i# // not ega C( //! prt0&i @@ D i# & R 0i @@ D113 //! prt0&i SS D i# & R 0i SS D113 //! prt0&!i i# & R !i13 prt0&0i W "01 @@ 0D W "01 i# & R 00i W "01 @@ 0D W "011 13 prt0&0i W "01 SS 0D W "01 i# & R 00i W "01 SS 0D W "011 13 < #tatic *oid prt0String #1 ; Sy#te!.Con#o e.VriteLine0#13 < < <///:8

Cha"ter 3* Controlling /rogram +low

''

:*u can apply = ?, OR, *r OT t* bool value# *nly) :*u cant u#e a n*nE bool a# i9 it !ere a bool in a l*gical e;pre##i*n a# y*u can in #*+e *ther language#) :*u can #ee the 9ailed atte+pt# at d*ing thi# c*++ented *ut !ith a //! c*++ent +arker) The #u3#eDuent e;pre##i*n#, h*!ever, pr*duce bool value# u#ing relati*nal c*+pari#*n#, then u#e l*gical *perati*n# *n the re#ult#) One *utput li#ting l**ked like thi#1 i 9 IP D 9 E i Z D i# true i W D i# fa #e i Z9 D i# true i W9 D i# fa #e i 99 D i# fa #e i !9 D i# true 0i W "01 @@ 0D W "01 i# fa #e 0i W "01 SS 0D W "01 i# true *te that a bool value i# aut*+atically c*nverted t* an appr*priate te;t 9*r+ i9 it# u#ed !here a string i# e;pected) :*u can replace the de9initi*n 9*r int in the a3*ve pr*gra+ !ith any *ther pri+itive data type e;cept bool) Be a!are, h*!ever, that the c*+pari#*n *9 9l*atingEp*int nu+3er# i# very #trict) = nu+3er that i# the tinie#t 9racti*n di99erent 9r*+ an*ther nu+3er i# #till In*t eDual)J = nu+3er that i# the tinie#t 3it a3*ve 7er* i# #till n*n7er*)

'hort;circuiting
,hen dealing !ith l*gical *perat*r# y*u run int* a phen*+en*n called I#h*rt circuiting)J Thi# +ean# that the e;pre##i*n !ill 3e evaluated *nly until the truth *r 9al#eh**d *9 the entire e;pre##i*n can 3e una+3igu*u#ly deter+ined) =# a re#ult, all the part# *9 a l*gical e;pre##i*n +ight n*t 3e evaluated) Here# an e;a+ple that de+*n#trate# #h*rtEcircuiting1 //: c0T:ShortCircuit.c# na!e#pace c0T; u#ing Sy#te!3 // :e!on#trate# #hort6circuiting $eha*ior.

1((

Thinking in C

www.ThinkingIn.!et

// .ith ogica operator#. pu$ ic c a## ShortCircuit ; #tatic $oo 'e#t"0int *a 1 ; Sy#te!.Con#o e.VriteLine0&'e#t"0& R *a R &1&13 Sy#te!.Con#o e.VriteLine0&re#u t: & R 0*a W "113 return *a W "3 < #tatic $oo 'e#t20int *a 1 ; Sy#te!.Con#o e.VriteLine0&'e#t20& R *a R &1&13 Sy#te!.Con#o e.VriteLine0&re#u t: & R 0*a W 2113 return *a W 23 < #tatic $oo 'e#tT0int *a 1 ; Sy#te!.Con#o e.VriteLine0&'e#tT0& R *a R &1&13 Sy#te!.Con#o e.VriteLine0&re#u t: & R 0*a W T113 return *a W T3 < pu$ ic #tatic *oid Gain01 ; if 0'e#t"001 @@ 'e#t2021 @@ 'e#tT0211 Sy#te!.Con#o e.VriteLine0&expre##ion i# true&13 e #e Sy#te!.Con#o e.VriteLine0&expre##ion i# fa #e&13 < < < ///:8 Each te#t per9*r+# a c*+pari#*n again#t the argu+ent and return# true *r 9al#e) -t al#* print# in9*r+ati*n t* #h*! y*u that it# 3eing called) The te#t# are u#ed in the e;pre##i*n1 if0te#t"001 @@ te#t2021 @@ te#tT0211

Cha"ter 3* Controlling /rogram +low

1(1

:*u +ight naturally think that all three te#t# !*uld 3e e;ecuted, 3ut the *utput #h*!# *ther!i#e1 te#t"001 re#u t: true te#t2021 re#u t: fa #e expre##ion i# fa #e The 9ir#t te#t pr*duced a true re#ult, #* the e;pre##i*n evaluati*n c*ntinue#) H*!ever, the #ec*nd te#t pr*duced a false re#ult) Since thi# +ean# that the !h*le e;pre##i*n +u#t 3e false, !hy c*ntinue evaluating the re#t *9 the e;pre##i*nF -t c*uld 3e e;pen#ive) The rea#*n 9*r #h*rtE circuiting, in 9act, i# preci#ely thatQ y*u can get a p*tential per9*r+ance increa#e i9 all the part# *9 a l*gical e;pre##i*n d* n*t need t* 3e evaluated)

3itwise o$erators
The 3it!i#e *perat*r# all*! y*u t* +anipulate individual 3it# in an integral pri+itive data type) Bit!i#e *perat*r# per9*r+ 3**lean alge3ra *n the c*rre#p*nding 3it# in the t!* argu+ent# t* pr*duce the re#ult) The 3it!i#e *perat*r# c*+e 9r*+ C# l*!Elevel *rientati*nQ y*u !ere *9ten +anipulating hard!are directly and had t* #et the 3it# in hard!are regi#ter#) =lth*ugh +*#t applicati*n and ,e3 Service devel*per# !ill n*t 3e u#ing the 3it!i#e *perat*r# +uch, devel*per# 9*r Handheld PC#, #etE t*p 3*;e#, and the B B*; *9ten need every 3itEt!iddling advantage they can get) The 3it!i#e = ? *perat*r GLH pr*duce# a *ne in the *utput 3it i9 3*th input 3it# are *neQ *ther!i#e it pr*duce# a 7er*) The 3it!i#e OR *perat*r GMH pr*duce# a *ne in the *utput 3it i9 either input 3it i# a *ne and pr*duce# a 7er* *nly i9 3*th input 3it# are 7er*) The 3it!i#e EBCLUS-CE OR, *r BOR GNH, pr*duce# a *ne in the *utput 3it i9 *ne *r the *ther input 3it i# a *ne, 3ut n*t 3*th) The 3it!i#e OT GO, al#* called the ones com"lement *perat*rH i# a unary *perat*rQ it take# *nly *ne argu+ent) G=ll *ther 3it!i#e *perat*r# are 3inary *perat*r#)H Bit!i#e OT pr*duce#

1()

Thinking in C

www.ThinkingIn.!et

the *pp*#ite *9 the input 3itRa *ne i9 the input 3it i# 7er*, a 7er* i9 the input 3it i# *ne) The 3it!i#e *perat*r# and l*gical *perat*r# u#e the #a+e character#, #* it i# help9ul t* have a +ne+*nic device t* help y*u re+e+3er the +eaning#1 #ince 3it# are I#+all,J there i# *nly *ne character in the 3it!i#e *perat*r#) Bit!i#e *perat*r# can 3e c*+3ined !ith the I #ign t* unite the *perati*n and a##ign+ent1 LI, MI and NI are all legiti+ate) GSince O i# a unary *perat*r it cann*t 3e c*+3ined !ith the I #ign)H The bool type i# treated a# a *neE3it value #* it i# #*+e!hat di99erent) :*u can per9*r+ a 3it!i#e = ?, OR and BOR, 3ut y*u cant per9*r+ a 3it!i#e OT Gpre#u+a3ly t* prevent c*n9u#i*n !ith the l*gical OTH) 5*r bool# the 3it!i#e *perat*r# have the #a+e e99ect a# the l*gical *perat*r# e;cept that they d* n*t #h*rt circuit) =l#*, 3it!i#e *perati*n# *n bool# include an BOR l*gical *perat*r that i# n*t included under the li#t *9 Il*gicalJ *perat*r#) :*ure prevented 9r*+ u#ing bool# in #hi9t e;pre##i*n#, !hich i# de#cri3ed ne;t)

'hi0t o$erators
The #hi9t *perat*r# al#* +anipulate 3it#) They can 3e u#ed #*lely !ith pri+itive, integral type#) The le9tE#hi9t *perat*r GPPH pr*duce# the *perand t* the le9t *9 the *perat*r #hi9ted t* the le9t 3y the nu+3er *9 3it# #peci9ied a9ter the *perat*r Gin#erting 7er*e# at the l*!erE*rder 3it#H) The #igned rightE#hi9t *perat*r GQQH pr*duce# the *perand t* the le9t *9 the *perat*r #hi9ted t* the right 3y the nu+3er *9 3it# #peci9ied a9ter the *perat*r) The #igned right #hi9t QQ u#e# sign e%tension1 i9 the value i# p*#itive, 7er*e# are in#erted at the higherE*rder 3it#Q i9 the value i# negative, *ne# are in#erted at the higherE*rder 3it#) GC# d*e# n*t have an un#igned right #hi9t QQQ)H -9 y*u #hi9t a char, byte, *r short, it !ill 3e pr*+*ted t* int 3e9*re the #hi9t take# place, and the re#ult !ill 3e an int) Only the 9ive l*!E*rder 3it# *9 the rightEhand #ide !ill 3e u#ed) Thi# prevent# y*u 9r*+ #hi9ting +*re than the nu+3er *9 3it# in an int) -9 y*ure *perating *n a long, y*ull get a long re#ult) Only the #i; l*!E*rder 3it# *9 the rightEhand #ide !ill 3e u#ed #* y*u cant #hi9t +*re than the nu+3er *9 3it# in a long)

Cha"ter 3* Controlling /rogram +low

1(3

Shi9t# can 3e c*+3ined !ith the eDual #ign GPPI *r QQIH) The lvalue i# replaced 3y the lvalue #hi9ted 3y the rvalue) Here# an e;a+ple that de+*n#trate# the u#e *9 all the *perat*r# inv*lving 3it#1 //: c0T:BitGanipu ation.c# na!e#pace c0T; u#ing Sy#te!3 pu$ ic c a## BitGanipu ation ; pu$ ic #tatic *oid Gain01 ; Rando! rand 9 ne. Rando!013 int i 9 rand.Cext013 int D 9 rand.Cext013 -Bin5nt0&6"&2 6"13 -Bin5nt0&R"&2 R"13 int !axpo# 9 5ntT2.GaxNa ue3 -Bin5nt0&!axpo#&2 !axpo#13 int !axneg 9 5ntT2.GinNa ue3 -Bin5nt0&!axneg&2 !axneg13 -Bin5nt0&i&2 i13 -Bin5nt0&8i&2 8i13 -Bin5nt0&6i&2 6i13 -Bin5nt0&D&2 D13 -Bin5nt0&i @ D&2 i @ D13 -Bin5nt0&i S D&2 i S D13 -Bin5nt0&i ] D&2 i ] D13 -Bin5nt0&i WW P&2 i WW P13 -Bin5nt0&i ZZ P&2 i ZZ P13 -Bin5nt0&08i1 ZZ P&2 08i1 ZZ P13 ///\todo On#igned #hift# don't .or%! /= -Bin5nt0&i ZZZ P&2 i ZZZ P13 -Bn5nt0&08i1 ZZZ P&2 08i1 ZZZ P13 =/ ong XhighX$it# 9 rand.Cext013 XhighX$it# WW9 T23 ong 9 XhighX$it# R rand.Cext013 ong !XhighX$it# 9 rand.Cext013 !XhighX$it# WW9T23

1(4

Thinking in C

www.ThinkingIn.!et

ong ! 9 !XhighX$it# R rand.Cext013 -BinLong0&6"L&2 6"L13 -BinLong0&R"L&2 R"L13 ong 9 5nt?E.GaxNa ue3 -BinLong0&!axpo#&2 13 ong n 9 5nt?E.GinNa ue3 -BinLong0&!axneg&2 n13 -BinLong0& XhighX$it#&2 XhighX$it#13 -BinLong0& &2 13 -BinLong0&8 &2 8 13 -BinLong0&6 &2 6 13 -BinLong0&!XhighX$it#&2 !XhighX$it#13 -BinLong0&!&2 !13 -BinLong0& @ !&2 @ !13 -BinLong0& S !&2 S !13 -BinLong0& ] !&2 ] !13 -BinLong0& WW P&2 WW P13 -BinLong0& ZZ P&2 ZZ P13 -BinLong0&08 1 ZZ P&2 08 1 ZZ P13 /= \todo -BinLong0& ZZZ P&2 ZZZ P13 -BinLong0&08 1 ZZZ P&2 08 1 ZZZ P13 =/ < #tatic *oid -Bin5nt0String #2 int i1 ; Sy#te!.Con#o e.VriteLine0 # R &2 int: & R i R &2 $inary: &13 Sy#te!.Con#o e.Vrite0& &13 for0int D 9 T"3 D Z903 D661 if000" WW D1 @ i1 !9 01 Sy#te!.Con#o e.Vrite0&"&13 e #e Sy#te!.Con#o e.Vrite0&0&13 Sy#te!.Con#o e.VriteLine013 < #tatic *oid -BinLong0String #2 ong 1 ; Sy#te!.Con#o e.VriteLine0 # R &2 ong: & R R &2 $inary: &13 Sy#te!.Con#o e.Vrite0& &13 for0int i 9 ?T3 i Z903 i661

Cha"ter 3* Controlling /rogram +low

1(5

if000"L WW i1 @ 1 !9 01 Sy#te!.Con#o e.Vrite0&"&13 e #e Sy#te!.Con#o e.Vrite0&0&13 Sy#te!.Con#o e.VriteLine013 < < < //:8 The t!* +eth*d# at the end, PBinBnt( ) and !BinLong( ) take an int *r a long, re#pectively, and print it *ut in 3inary 9*r+at al*ng !ith a de#criptive #tring) :*u can ign*re the i+ple+entati*n *9 the#e 9*r n*!) :*ull n*te the u#e *9 #ystem6Console6=rite( ) in#tead *9 #ystem6Console6=riteLine( )) The =rite( ) +eth*d d*e# n*t e+it a ne! line, #* it all*!# y*u t* *utput a line in piece#) =# !ell a# de+*n#trating the e99ect *9 all the 3it!i#e *perat*r# 9*r int and long, thi# e;a+ple al#* #h*!# the +ini+u+, +a;i+u+, @0 and E0 value# 9*r int and long #* y*u can #ee !hat they l**k like) *te that the high 3it repre#ent# the #ign1 $ +ean# p*#itive and 0 +ean# negative) The *utput l**k# like thi#1 6"2 int: 6"2 $inary: """""""""""""""""""""""""""""""" R"2 int: "2 $inary: 0000000000000000000000000000000" !axpo#2 int: 2"EFEIT?EF2 $inary: 0""""""""""""""""""""""""""""""" !axneg2 int: 62"EFEIT?EI2 $inary: "0000000000000000000000000000000 i2 int: ""FFE">TT02 $inary: 0"000""000"0""0""""""""00"0000"0 8i2 int: 6""FFE">TT"2 $inary: "0"""00"""0"00"00000000""0""""0" 6i2 int: 6""FFE">TT02 $inary: "0"""00"""0"00"00000000""0"""""0 D2 int: II??>T>T22 $inary: 00""0"00""0""00""""0000000"0""00 i @ D2 int: ?FFP?0T22 $inary:

1(6

Thinking in C

www.ThinkingIn.!et

00000"000000"00""""0000000000000 i S D2 int: ">>?TPF2T02 $inary: 0"""0""0""""""0""""""""00""0"""0 i ] D2 int: ">2I?0"">I2 $inary: 0"""00"0""""0"00000""""00""0"""0 i WW P2 int: 6>FF2IF"0E2 $inary: ""000"0""0""""""""00"0000"000000 i ZZ P2 int: T?F>ETPE2 $inary: 000000"000""000"0""0""""""""00"0 08i1 ZZ P2 int: 6T?F>ETPP2 $inary: """"""0"""00"""0"00"00000000""0" 6"L2 ong: 6"2 $inary: """""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""" R"L2 ong: "2 $inary: 000000000000000000000000000000000000000000000000000000 000000000" !axpo#2 ong: >22TTF20T?IPEFFPI0F2 $inary: 0""""""""""""""""""""""""""""""""""""""""""""""""""""" """""""""" !axneg2 ong: 6>22TTF20T?IPEFFPI0I2 $inary: "00000000000000000000000000000000000000000000000000000 0000000000 XhighX$it#2 ong: E?PE>F2P>F2"2020FT?2 $inary: 0"000000"00""00"""00"000"""0"0"00000000000000000000000 0000000000 2 ong: E?PE>F2P>II2>0"E2>P2 $inary: 0"000000"00""00"""00"000"""0"0"00""000000""0000"0"0""" 0"000"0""" 8 2 ong: 6E?PE>F2P>II2>0"E2>?2 $inary: "0""""""0""00""000""0"""000"0"0""00""""""00""""0"0"000 "0"""0"000 6 2 ong: 6E?PE>F2P>II2>0"E2>P2 $inary:

Cha"ter 3* Controlling /rogram +low

1(#

"0""""""0""00""000""0"""000"0"0""00""""""00""""0"0"000 "0"""0"00" !XhighX$it#2 ong: E?ITPE2T0FTEI"P2T22 $inary: 00000""00""""""""""0""0""0""000"0000000000000000000000 0000000000 !2 ong: E?ITPE2T""PIF0PPEF2 $inary: 00000""00""""""""""0""0""0""000"000""00"0"000"000000"" 0""000"0"" @ !2 ong: F2PFE?T>E22I?P>P2 $inary: 00000000000""00"""00"000"0"00000000000000"0000000000"" 0"000000"" S !2 ong: P""?0?>T??0EPETT2EF2 $inary: 0"000""0"""""""""""0""0""""""0""0""""00"0""00"0"0"0""" 0""00""""" ] !2 ong: P"0II"">02"0T"E??P22 $inary: 0"000""0"""00""000"00"0"0"0""0""0""""00"00"00"0"0"0"00 00"00"""00 WW P2 ong: "TIP"F0PF2IP20EEP"22 $inary: 000"00""00"""00"000"""0"0"00""000000""0000"0"0"""0"000 "0"""00000 ZZ P2 ong: "EPE?FI>TF"TE0??>?2 $inary: 000000"000000"00""00"""00"000"""0"0"00""000000""0000"0 "0"""0"000 08 1 ZZ P2 ong: 6"EPE?FI>TF"TE0??>F2 $inary: """"""0""""""0""00""000""0"""000"0"0""00""""""00""""0" 0"000"0""" The 3inary repre#entati*n *9 the nu+3er# i# re9erred t* a# signed two:s com"lement)

1(&

Thinking in C

www.ThinkingIn.!et

-ernar5 i0;else o$erator


Thi# *perat*r i# unu#ual 3ecau#e it ha# three *perand#) -t i# truly an *perat*r 3ecau#e it pr*duce# a value, unlike the *rdinary i9Eel#e #tate+ent that y*ull #ee in the ne;t #ecti*n *9 thi# chapter) The e;pre##i*n i# *9 the 9*r+1 $oo ean6exp Y *a ue0 : *a ue" -9 2oolean9e%" evaluate# t* true, -alue( i# evaluated and it# re#ult 3ec*+e# the value pr*duced 3y the *perat*r) -9 2oolean9e%" i# false, -alue1 i# evaluated and it# re#ult 3ec*+e# the value pr*duced 3y the *perat*r) O9 c*ur#e, y*u c*uld u#e an *rdinary if-else #tate+ent Gde#cri3ed laterH, 3ut the ternary *perat*r i# +uch ter#er) =lth*ugh C G!here thi# *perat*r *riginatedH pride# it#el9 *n 3eing a ter#e language, and the ternary *perat*r +ight have 3een intr*duced partly 9*r e99iciency, y*u #h*uld 3e #*+e!hat !ary *9 u#ing it *n an everyday 3a#i#Rit# ea#y t* pr*duce unreada3le c*de) The c*nditi*nal *perat*r can 3e u#ed 9*r it# #ide e99ect# *r 9*r the value it pr*duce#, 3ut in general y*u !ant the value #ince that# !hat +ake# the *perat*r di#tinct 9r*+ the if-else) Here# an e;a+ple1 #tatic int 'ernary0int i1 ; return i W "0 Y i = "00 : i = "03 < :*u can #ee that thi# c*de i# +*re c*+pact than !hat y*ud need t* !rite !ith*ut the ternary *perat*r1 #tatic int ) ternati*e0int i1 ; if 0i W "01 return i = "003 e #e return i = "03 <

Cha"ter 3* Controlling /rogram +low

1('

The #ec*nd 9*r+ i# ea#ier t* under#tand, and d*e#nt reDuire a l*t +*re typing) S* 3e #ure t* p*nder y*ur rea#*n# !hen ch**#ing the ternary *perat*r P it# generally !arranted !hen y*ure #etting a varia3le t* *ne *9 t!* value#1 int ternaryRe#u t 9 i W "0 Y i = "00 : i = "03

-he co##a o$erator


The c*++a i# u#ed in C and C@@ n*t *nly a# a #eparat*r in 9uncti*n argu+ent li#t#, 3ut al#* a# an *perat*r 9*r #eDuential evaluati*n) The #*le place that the c*++a o"erator i# u#ed in C# i# in for l**p#, !hich !ill 3e de#cri3ed later in thi# chapter) OT*d*1 C*n9ir+ that thi# i# all the *perat*r# in C#

Co##on $it0alls when using o$erators


One *9 the pit9all# !hen u#ing *perat*r# i# trying t* get a!ay !ith*ut parenthe#e# !hen y*u are even the lea#t 3it uncertain a3*ut h*! an e;pre##i*n !ill evaluate) Thi# i# #till true in C#) =n e;tre+ely c*++*n err*r in C and C@@ l**k# like thi#1 .hi e0x 9 y1 ; // .... < The pr*gra++er !a# trying t* te#t 9*r eDuivalence GIIH rather than d* an a##ign+ent) -n C and C@@ the re#ult *9 thi# a##ign+ent !ill al!ay# 3e true i9 y i# n*n7er*, and y*ull pr*3a3ly get an in9inite l**p) -n C#, the re#ult *9 thi# e;pre##i*n i# n*t a bool, and the c*+piler e;pect# a bool and !*nt c*nvert 9r*+ an int, #* it !ill c*nveniently give y*u a c*+pileE ti+e err*r and catch the pr*3le+ 3e9*re y*u ever try t* run the pr*gra+) S* the pit9all never happen# in C#) GThe *nly ti+e y*u !*nt get a c*+pileEti+e err*r i# !hen x and y are bool, in !hich ca#e x I y i# a legal e;pre##i*n, and in the a3*ve ca#e, pr*3a3ly an err*r)H

11(

Thinking in C

www.ThinkingIn.!et

= #i+ilar pr*3le+ in C and C@@ i# u#ing 3it!i#e = ? and OR in#tead *9 the l*gical ver#i*n#) Bit!i#e = ? and OR u#e *ne *9 the character# G L *r MH !hile l*gical = ? and OR u#e t!* GLL and MMH) "u#t a# !ith I and II, it# ea#y t* type 4u#t *ne character in#tead *9 t!*) -n C#, the c*+piler again prevent# thi# 3ecau#e it !*nt let y*u cavalierly u#e *ne type !here it d*e#nt 3el*ng)

Casting o$erators
The !*rd cast i# u#ed in the #en#e *9 Ica#ting int* a +*ld)J C# !ill aut*+atically change *ne type *9 data int* an*ther !hen appr*priate) 5*r in#tance, i9 y*u a##ign an integral value t* a 9l*atingEp*int varia3le, the c*+piler !ill aut*+atically c*nvert the int t* a float) Ca#ting all*!# y*u t* +ake thi# type c*nver#i*n e;plicit, *r t* 9*rce it !hen it !*uldnt n*r+ally happen) T* per9*r+ a ca#t, put the de#ired data type Gincluding all +*di9ier#H in#ide parenthe#e# t* the le9t *9 any value) Here# an e;a+ple1 *oid ca#t#01 ; int i 9 2003 ong 9 0 ong1i3 ong 2 9 0 ong12003 < =# y*u can #ee, it# p*##i3le t* per9*r+ a ca#t *n a nu+eric value a# !ell a# *n a varia3le) -n 3*th ca#t# #h*!n here, h*!ever, the ca#t i# #uper9lu*u#, #ince the c*+piler !ill aut*+atically pr*+*te an int value t* a long !hen nece##ary) H*!ever, y*u are all*!ed t* u#e #uper9lu*u# ca#t# t* +ake a p*int *r t* +ake y*ur c*de +*re clear) -n *ther #ituati*n#, a ca#t +ay 3e e##ential 4u#t t* get the c*de t* c*+pile) -n C and C@@, ca#ting can cau#e #*+e headache#) -n C#, ca#ting i# #a9e, !ith the e;cepti*n that !hen y*u per9*r+ a #*Ecalled narrowing con-ersion Gthat i#, !hen y*u g* 9r*+ a data type that can h*ld +*re in9*r+ati*n t* *ne that d*e#nt h*ld a# +uchH y*u run the ri#k *9 l*#ing in9*r+ati*n) Here the c*+piler 9*rce# y*u t* d* a ca#t, in e99ect #aying Ithi# can 3e a danger*u# thing t* d*Ri9 y*u !ant +e t* d* it any!ay y*u +u#t +ake the ca#t e;plicit)J ,ith a widening con-ersion an e;plicit ca#t

Cha"ter 3* Controlling /rogram +low

111

i# n*t needed 3ecau#e the ne! type !ill +*re than h*ld the in9*r+ati*n 9r*+ the *ld type #* that n* in9*r+ati*n i# ever l*#t) "ava all*!# y*u t* ca#t any pri+itive type t* any *ther pri+itive type, e;cept 9*r bool, !hich d*e#nt all*! any ca#ting at all) Cla## type# d* n*t all*! ca#ting) T* c*nvert *ne t* the *ther there +u#t 3e #pecial +eth*d#) G:*ull 9ind *ut later in thi# 3**k that *34ect# can 3e ca#t !ithin a $amil4 *9 type#Q an 1a( can 3e ca#t t* a +ree and viceEver#a, 3ut n*t t* a 9*reign type #uch a# a *oc()H

Literals
Ordinarily !hen y*u in#ert a literal value int* a pr*gra+ the c*+piler kn*!# e;actly !hat type t* +ake it) S*+eti+e#, h*!ever, the type i# a+3igu*u#) ,hen thi# happen# y*u +u#t guide the c*+piler 3y adding #*+e e;tra in9*r+ati*n in the 9*r+ *9 character# a##*ciated !ith the literal value) The 9*ll*!ing c*de #h*!# the#e character#1 //: c0T:Litera #.c# na!e#pace c0T; u#ing Sy#te!3 pu$ ic c a## Litera # ; //!char c 9 0xffff3 // !ax char hex *a ue $yte $ 9 0xFf3 // !ax $yte hex *a ue #hort # 9 0xFfff3 // !ax #hort hex *a ue int i" 9 0x2f3 // Uexadeci!a 0 o.erca#e1 int i2 9 0,2H3 // Uexadeci!a 0upperca#e1 int iT 9 0"FF3 // Octa 0 eading Mero1 // Uex and Oct a #o .or% .ith ong. ong n" 9 200L3 // ong #uffix ong n2 9 200 3 // ong #uffix 6 generate# a .arning ong nT 9 2003 //! ong ?020013 // not a o.ed f oat f" 9 "3 f oat f2 9 "H3 // f oat #uffix f oat fT 9 "f3 // f oat #uffix f oat fE 9 "e6EPf3 // "0 to the po.er f oat fP 9 "eR>f3 // f oat #uffix dou$ e d" 9 "d3 // dou$ e #uffix

11)

Thinking in C

www.ThinkingIn.!et

dou$ e d2 9 ":3 // dou$ e #uffix dou$ e dT 9 EFeEFd3 // "0 to the po.er < < //:8 \todo: )ppropriate p ace for ^u00I" type# of thing#Y He;adeci+al G3a#e 0.H, !hich !*rk# !ith all the integral data type#, i# den*ted 3y a leading 4x *r 4? 9*ll*!ed 3y $R6 and aR9 either in upper *r l*!erca#e) -9 y*u try t* initiali7e a varia3le !ith a value 3igger than it can h*ld Gregardle## *9 the nu+erical 9*r+ *9 the valueH, the c*+piler !ill give y*u an err*r +e##age) *tice in the a3*ve c*de the +a;i+u+ p*##i3le he;adeci+al value# 9*r char, byte, and short) -9 y*u e;ceed the#e, the c*+piler !ill aut*+atically +ake the value an int and tell y*u that y*u need a narr*!ing ca#t 9*r the a##ign+ent) :*ull kn*! y*uve #tepped *ver the line) Octal G3a#e (H i# den*ted 3y a leading 7er* in the nu+3er and digit# 9r*+ $E%) :*ud think that, i9 they !ere g*ing t* pr*vide *ctal G!hich - havent #een u#ed in a pr*gra+ in +*re than a decadeH, theyd pr*vide a literal repre#entati*n 9*r 3inary nu+3er#, 3ut #adly, that i# n*t the ca#e) = trailing character a9ter a literal value e#ta3li#he# it# type) Upper *r l*!erca#e L +ean# long, upper *r l*!erca#e : +ean# float and upper *r l*!erca#e $ +ean# double) E;p*nent# u#e a n*tati*n that #*+e 9ind rather di#+aying1 769R e-JSf) -n #cience and engineering, Te re9er# t* the 3a#e *9 natural l*garith+#, appr*;i+ately 2)%0() G= +*re preci#e double value i# availa3le in C# a# .ath6&)H Thi# i# u#ed in e;p*nentiati*n e;pre##i*n# #uch a# 0)/6 ; e E&%, !hich +ean# 0)/6 ; 2)%0(E&%) H*!ever, !hen 5ORTR= !a# invented they decided that e !*uld naturally +ean Iten t* the p*!er,J !hich i# an *dd deci#i*n 3ecau#e 5ORTR= !a# de#igned 9*r #cience and engineering and *ne !*uld think it# de#igner# !*uld 3e #en#itive a3*ut intr*ducing #uch an a+3iguity)0 =t any rate, thi# cu#t*+ !a# 9*ll*!ed in C, C@@ and
0 "*hn Nirkha+ !rite#, I- #tarted c*+puting in 06.2 u#ing 5ORTR=

-- *n an -BA 0.2$) =t that ti+e, and thr*ugh*ut the 06.$# and int* the 06%$#, 5ORTR= !a# an all upperca#e language) Thi# pr*3a3ly #tarted 3ecau#e +any *9 the early input device# !ere *ld teletype unit# that u#ed ' 3it Baud*t c*de, !hich had n* l*!erca#e capa3ility) The TE in the e;p*nential n*tati*n !a# al#* al!ay# upper ca#e and !a# never c*n9u#ed !ith the

Cha"ter 3* Controlling /rogram +low

113

n*! C#) S* i9 y*ure u#ed t* thinking in ter+# *9 e a# the 3a#e *9 natural l*garith+#, y*u +u#t d* a +ental tran#lati*n !hen y*u #ee an e;pre##i*n #uch a# 769R e-JSf in "avaQ it +ean# 0)/6 ; 0$E&%) *te that y*u d*nt need t* u#e the trailing character !hen the c*+piler can 9igure *ut the appr*priate type) ,ith ong nT 9 2003 there# n* a+3iguity, #* an L a9ter the 2$$ !*uld 3e #uper9lu*u#) H*!ever, !ith f oat fE 9 "e6EFf3 // "0 to the po.er the c*+piler n*r+ally take# e;p*nential nu+3er# a# d*u3le#, #* !ith*ut the trailing f it !ill give y*u an err*r telling y*u that y*u +u#t u#e a ca#t t* c*nvert double t* float)

Pro#otion
:*ull di#c*ver that i9 y*u per9*r+ any +athe+atical *r 3it!i#e *perati*n# *n pri+itive data type# that are #+aller than an int Gthat i#, char, byte, *r shortH, th*#e value# !ill 3e pr*+*ted t* int 3e9*re per9*r+ing the *perati*n#, and the re#ulting value !ill 3e *9 type int) S* i9 y*u !ant t* a##ign 3ack int* the #+aller type, y*u +u#t u#e a ca#t) G=nd, #ince y*ure a##igning 3ack int* a #+aller type, y*u +ight 3e l*#ing in9*r+ati*n)H -n general, the large#t data type in an e;pre##i*n i# the *ne that deter+ine# the #i7e *9 the re#ult *9 that e;pre##i*nQ i9 y*u +ultiply a float and a double, the re#ult !ill 3e doubleQ i9 y*u add an int and a long, the re#ult !ill 3e long)

natural l*garith+ 3a#e Te, !hich i# al!ay# l*!erca#e) The TE #i+ply #t**d 9*r e;p*nential, !hich !a# 9*r the 3a#e *9 the nu+3er #y#te+ u#edRu#ually 0$) =t the ti+e *ctal !a# al#* !idely u#ed 3y pr*gra++er#) =lth*ugh - never #a! it u#ed, i9 - had #een an *ctal nu+3er in e;p*nential n*tati*n - !*uld have c*n#idered it t* 3e 3a#e () The 9ir#t ti+e - re+e+3er #eeing an e;p*nential u#ing a l*!erca#e Te !a# in the late 06%$# and - al#* 9*und it c*n9u#ing) The pr*3le+ ar*#e a# l*!erca#e crept int* 5ORTR= , n*t at it# 3eginning) ,e actually had 9uncti*n# t* u#e i9 y*u really !anted t* u#e the natural l*garith+ 3a#e, 3ut they !ere all upperca#e)J

114

Thinking in C

www.ThinkingIn.!et

C# has Gsi:eo0H
The siTeof( ) *perat*r #ati#9ie# a #peci9ic need1 it tell# y*u the nu+3er *9 3yte# all*cated 9*r data ite+#) The +*#t c*+pelling need 9*r siTeof( ) in C and C@@ i# p*rta3ility) ?i99erent data type# +ight 3e di99erent #i7e# *n di99erent +achine#, #* the pr*gra++er +u#t 9ind *ut h*! 3ig th*#e type# are !hen per9*r+ing *perati*n# that are #en#itive t* #i7e) 5*r e;a+ple, *ne c*+puter +ight #t*re integer# in /2 3it#, !herea# an*ther +ight #t*re integer# a# 0. 3it#) Pr*gra+# c*uld #t*re larger value# in integer# *n the 9ir#t +achine) =# y*u +ight i+agine, p*rta3ility i# a huge headache 9*r C and C@@ pr*gra++er#) -n C#, thi# +*#t c*++*n u#e *9 #i7e*9GH i# n*t relevant, 3ut it can c*+e int* play !hen inter9acing !ith e;ternal data #tructure# *r !hen y*ure +anipulating 3l*ck# *9 ra! data and y*ure !illing t* 9*reg* c*nvenience and #a9ety 9*r every la#t 3it *9 #peed G#ay, i9 y*ure !riting a r*utine 9*r pr*ce##ing vide* dataH) The siTeof() *perat*r i# *nly u#a3le in#ide un#a9e c*de G#ee #H)

C#s Pre$rocessor
C## prepr*ce##ing directive# #h*uld 3e u#ed !ith cauti*n) .1*& The#e are "re"rocessor directi-es a# de#cri3ed in chapter #prepr*ce##ing# and +u#t 3e the *nly #tate+ent# *n a line) C# d*e# n*t actually have a #eparate prepr*ce##ing #tep that run# pri*r t* c*+pilati*n 3ut the 9*r+ and u#e *9 the#e #tate+ent# i# intended t* 3e 9a+iliar t* C and C@@ pr*gra++er#) ,hile there# n* har+ in the #regi*n directive#, the *ther directive# #upp*rt conditional com"ilation, !hich all*!# a #ingle c*de3a#e t* generate +ultiple 3inary *utput#) The +*#t c*++*n u#e *9 c*nditi*nal c*+pilati*n i# t* re+*ve de3ugging 3ehavi*r 9r*+ a #hipping pr*ductQ thi# i# d*ne 3y de9ining a #y+3*l *n the c*+pilati*n c*++andEline, and u#ing the Uif, Uendif, Uelse, and Uelif directive# t* create c*nditi*nal l*gic depending *n the e;i#tence *r a3#ence *9 *ne *r +*re #uch #y+3*l#) Here# a #i+ple e;a+ple1 //:c"T:CondCo!p.c# //:e!on#trate# conditiona co!pi ation

Cha"ter 3* Controlling /rogram +low

115

c a## CondCo!p; pu$ ic #tatic *oid Gain01; (if :+BO_ Sy#te!.Con#o e.VriteLine0&:e$ug $eha*ior&13 (endif < < -9 CondComp i# c*+piled !ith the c*++andEline csc /defineD$ebug CondComp6cs it !ill print the lineQ i9 !ith a #traight csc CondComp6cs, it !*nt) ,hile thi# #ee+# like a rea#*na3le idea, in practice it *9ten lead# t* #ituati*n# !here a change i# +ade in *ne c*nditi*nal 3ranch and n*t in an*ther, and the prepr*ce##*r leave# n* trace in the c*de *9 the c*+pilati*n *pti*n#Q in general, it# a 3etter idea t* u#e a readonly bool 9*r #uch thing#) = rea#*na3le c*+pr*+i#e i# t* u#e the prepr*ce##*r directive# t* #et the value# *9 varia3le# that are u#ed t* change runti+e 3ehavi*r1 //:c"T:Gar%edCondCo!p.c# //:e!on#trate# conditiona c a## CondCo!p; #tatic readon y $oo (if :+BO_ true3 (e #e fa #e3 (endif co!pi ation

:+BO_ 9

pu$ ic #tatic *oid Gain01; if0:+BO_1 Sy#te!.Con#o e.VriteLine0&:e$ug $eha*ior&13 < <///:8 -n .ar(edCondComp, i9 a pr*3le+ ar*#e, a de3ugger *r l*gging 9acility !*uld 3e a3le t* read the value *9 the $&BV bool, thu# all*!ing the +aintenance pr*gra++er# t* deter+ine the c*+pilati*n c*++and# that lead t* the tr*u3le#*+e 3ehavi*r) The trivial di#advantage# *9 thi# +*del are the #light penalty *9 a runti+e c*+pari#*n and the increa#e in the a##e+3ly# #i7e due t* the pre#ence *9 the de3ugging c*de)

116

Thinking in C

www.ThinkingIn.!et

Precedence revisited
Operat*r precedence i# di99icult t* re+e+3er, 3ut here i# a help9ul +ne+*nic 1 IUlcer =ddict# Really Like C# = l*t)J .nemonic Ulcer =ddict# Really Like C# = L*t 1perator type Unary =rith+etic Gand #hi9tH Relati*nal L*gical Gand 3it!i#eH C*nditi*nal GternaryH =##ign+ent 1perators C - CC-; / K C - PP QQ Q P QI PI II !I LL MM L M N 'QBW?D@ I Gand c*+p*und a##ign+ent like ;IH

O9 c*ur#e, !ith the #hi9t and 3it!i#e *perat*r# di#tri3uted ar*und the ta3le it i# n*t a per9ect +ne+*nic, 3ut 9*r n*nE3it *perati*n# it !*rk#)

) co#$endiu# o0 o$erators
The 9*ll*!ing e;a+ple #h*!# !hich pri+itive data type# can 3e u#ed !ith particular *perat*r#) Ba#ically, it i# the #a+e e;a+ple repeated *ver and *ver, 3ut u#ing di99erent pri+itive data type#) The 9ile !ill c*+pile !ith*ut err*r 3ecau#e the line# that !*uld cau#e err*r# are c*++ented *ut !ith a //!) //:c0T.) Op#.c# na!e#pace c0T; u#ing Sy#te!3 // 'e#t# a the operator# on a the // pri!iti*e data type# to #ho. .hich // one# are accepted $y the `a*a co!pi er. pu$ ic c a## ) Op# ; // 'o accept the re#u t# of a $oo ean te#t: *oid H0$oo $1 ;< *oid $oo 'e#t0$oo x2 $oo y1 ; // )rith!etic operator#: //! x 9 x = y3 //! x 9 x / y3

Cha"ter 3* Controlling /rogram +low

11#

//! x 9 x [ y3 //! x 9 x R y3 //! x 9 x 6 y3 //! xRR3 //! x663 //! x 9 Ry3 //! x 9 6y3 // Re ationa and ogica : //! H0x Z y13 //! H0x Z9 y13 //! H0x W y13 //! H0x W9 y13 H0x 99 y13 H0x !9 y13 H0!y13 x 9 x @@ y3 x 9 x SS y3 // Bit.i#e operator#: //! x 9 8y3 x 9 x @ y3 x 9 x S y3 x 9 x ] y3 //! x 9 x WW "3 //! x 9 x ZZ "3 //! x 9 x ZZZ "3 // Co!pound a##ign!ent: //! x R9 y3 //! x 69 y3 //! x =9 y3 //! x /9 y3 //! x [9 y3 //! x WW9 "3 //! x ZZ9 "3 //! x ZZZ9 "3 x @9 y3 x ]9 y3 x S9 y3 // Ca#ting: //! char c 9 0char1x3 //! $yte B 9 0$yte1x3 //! #hort # 9 0#hort1x3

11&

Thinking in C

www.ThinkingIn.!et

//! int i 9 0int1x3 //! ong 9 0 ong1x3 //! f oat f 9 0f oat1x3 //! dou$ e d 9 0dou$ e1x3 < *oid char'e#t0char x2 char y1 ; // )rith!etic operator#: x 9 0char10x = y13 x 9 0char10x / y13 x 9 0char10x [ y13 x 9 0char10x R y13 x 9 0char10x 6 y13 xRR3 x663 x 9 0char1Ry3 x 9 0char16y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13 //! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: x9 0char18y3 x 9 0char10x @ y13 x 9 0char10x S y13 x 9 0char10x ] y13 x 9 0char10x WW "13 x 9 0char10x ZZ "13 //! \todo x 9 0char10x ZZZ "13 // Co!pound a##ign!ent: x R9 y3 x 69 y3 x =9 y3 x /9 y3 x [9 y3 x WW9 "3

Cha"ter 3* Controlling /rogram +low

11'

x ZZ9 "3 //\todo x ZZZ9 "3 x @9 y3 x ]9 y3 x S9 y3 // Ca#ting: //! $oo $ 9 0$oo 1x3 $yte B 9 0$yte1x3 #hort # 9 0#hort1x3 int i 9 0int1x3 ong 9 0 ong1x3 f oat f 9 0f oat1x3 dou$ e d 9 0dou$ e1x3 < *oid $yte'e#t0$yte x2 $yte y1 ; // )rith!etic operator#: x 9 0$yte10x= y13 x 9 0$yte10x / y13 x 9 0$yte10x [ y13 x 9 0$yte10x R y13 x 9 0$yte10x 6 y13 xRR3 x663 x 9 0$yte1R y3 x 9 0$yte16 y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13 //! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: x 9 0$yte18y3 x 9 0$yte10x @ y13 x 9 0$yte10x S y13 x 9 0$yte10x ] y13 x 9 0$yte10x WW "13

1)(

Thinking in C

www.ThinkingIn.!et

x 9 0$yte10x ZZ "13 //\todo x 9 0$yte10x ZZZ "13 // Co!pound a##ign!ent: x R9 y3 x 69 y3 x =9 y3 x /9 y3 x [9 y3 x WW9 "3 x ZZ9 "3 //\todo x ZZZ9 "3 x @9 y3 x ]9 y3 x S9 y3 // Ca#ting: //! $oo $ 9 0$oo 1x3 char c 9 0char1x3 #hort # 9 0#hort1x3 int i 9 0int1x3 ong 9 0 ong1x3 f oat f 9 0f oat1x3 dou$ e d 9 0dou$ e1x3 < *oid #hort'e#t0#hort x2 #hort y1 ; // )rith!etic operator#: x 9 0#hort10x = y13 x 9 0#hort10x / y13 x 9 0#hort10x [ y13 x 9 0#hort10x R y13 x 9 0#hort10x 6 y13 xRR3 x663 x 9 0#hort1Ry3 x 9 0#hort16y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13

Cha"ter 3* Controlling /rogram +low

1)1

//! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: x 9 0#hort18y3 x 9 0#hort10x @ y13 x 9 0#hort10x S y13 x 9 0#hort10x ] y13 x 9 0#hort10x WW "13 x 9 0#hort10x ZZ "13 //\todo x 9 0#hort10x ZZZ "13 // Co!pound a##ign!ent: x R9 y3 x 69 y3 x =9 y3 x /9 y3 x [9 y3 x WW9 "3 x ZZ9 "3 //\todo x ZZZ9 "3 x @9 y3 x ]9 y3 x S9 y3 // Ca#ting: //! $oo $ 9 0$oo 1x3 char c 9 0char1x3 $yte B 9 0$yte1x3 int i 9 0int1x3 ong 9 0 ong1x3 f oat f 9 0f oat1x3 dou$ e d 9 0dou$ e1x3 < *oid int'e#t0int x2 int y1 ; // )rith!etic operator#: x 9 x = y3 x 9 x / y3 x 9 x [ y3 x 9 x R y3 x 9 x 6 y3 xRR3 x663

1))

Thinking in C

www.ThinkingIn.!et

x 9 Ry3 x 9 6y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13 //! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: x 9 8y3 x 9 x @ y3 x 9 x S y3 x 9 x ] y3 x 9 x WW "3 x 9 x ZZ "3 //\todo x 9 x ZZZ "3 // Co!pound a##ign!ent: x R9 y3 x 69 y3 x =9 y3 x /9 y3 x [9 y3 x WW9 "3 x ZZ9 "3 //\todo x ZZZ9 "3 x @9 y3 x ]9 y3 x S9 y3 // Ca#ting: //! $oo $ 9 0$oo 1x3 char c 9 0char1x3 $yte B 9 0$yte1x3 #hort # 9 0#hort1x3 ong 9 0 ong1x3 f oat f 9 0f oat1x3 dou$ e d 9 0dou$ e1x3 <

Cha"ter 3* Controlling /rogram +low

1)3

*oid ong'e#t0 ong x2 ong y1 ; // )rith!etic operator#: x 9 x = y3 x 9 x / y3 x 9 x [ y3 x 9 x R y3 x 9 x 6 y3 xRR3 x663 x 9 Ry3 x 9 6y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13 //! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: x 9 8y3 x 9 x @ y3 x 9 x S y3 x 9 x ] y3 x 9 x WW "3 x 9 x ZZ "3 //\todo x 9 x ZZZ "3 // Co!pound a##ign!ent: x R9 y3 x 69 y3 x =9 y3 x /9 y3 x [9 y3 x WW9 "3 x ZZ9 "3 //\todo x ZZZ9 "3 x @9 y3 x ]9 y3 x S9 y3

1)4

Thinking in C

www.ThinkingIn.!et

// Ca#ting: //! $oo $ 9 0$oo 1x3 char c 9 0char1x3 $yte B 9 0$yte1x3 #hort # 9 0#hort1x3 int i 9 0int1x3 f oat f 9 0f oat1x3 dou$ e d 9 0dou$ e1x3 < *oid f oat'e#t0f oat x2 f oat y1 ; // )rith!etic operator#: x 9 x = y3 x 9 x / y3 x 9 x [ y3 x 9 x R y3 x 9 x 6 y3 xRR3 x663 x 9 Ry3 x 9 6y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13 //! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: //! x 9 8y3 //! x 9 x @ y3 //! x 9 x S y3 //! x 9 x ] y3 //! x 9 x WW "3 //! x 9 x ZZ "3 //! x 9 x ZZZ "3 // Co!pound a##ign!ent: x R9 y3 x 69 y3

Cha"ter 3* Controlling /rogram +low

1)5

x =9 y3 x /9 y3 x [9 y3 //! x WW9 "3 //! x ZZ9 "3 //! x ZZZ9 "3 //! x @9 y3 //! x ]9 y3 //! x S9 y3 // Ca#ting: //! $oo $ 9 0$oo 1x3 char c 9 0char1x3 $yte B 9 0$yte1x3 #hort # 9 0#hort1x3 int i 9 0int1x3 ong 9 0 ong1x3 dou$ e d 9 0dou$ e1x3 < *oid dou$ e'e#t0dou$ e x2 dou$ e y1 ; // )rith!etic operator#: x 9 x = y3 x 9 x / y3 x 9 x [ y3 x 9 x R y3 x 9 x 6 y3 xRR3 x663 x 9 Ry3 x 9 6y3 // Re ationa and ogica : H0x Z y13 H0x Z9 y13 H0x W y13 H0x W9 y13 H0x 99 y13 H0x !9 y13 //! H0!x13 //! H0x @@ y13 //! H0x SS y13 // Bit.i#e operator#: //! x 9 8y3

1)6

Thinking in C

www.ThinkingIn.!et

//! x 9 x @ y3 //! x 9 x S y3 //! x 9 x ] y3 //! x 9 x WW "3 //! x 9 x ZZ "3 //! x 9 x ZZZ "3 // Co!pound a##ign!ent: x R9 y3 x 69 y3 x =9 y3 x /9 y3 x [9 y3 //! x WW9 "3 //! x ZZ9 "3 //! x ZZZ9 "3 //! x @9 y3 //! x ]9 y3 //! x S9 y3 // Ca#ting: //! $oo $ 9 0$oo 1x3 char c 9 0char1x3 $yte B 9 0$yte1x3 #hort # 9 0#hort1x3 int i 9 0int1x3 ong 9 0 ong1x3 f oat f 9 0f oat1x3 < < < //:8 *te that bool i# Duite li+ited) :*u can a##ign t* it the value# true and false, and y*u can te#t it 9*r truth *r 9al#eh**d, 3ut y*u cann*t add 3**lean# *r per9*r+ any *ther type *9 *perati*n *n the+) -n char, byte, and short y*u can #ee the e99ect *9 pr*+*ti*n !ith the arith+etic *perat*r#) Each arith+etic *perati*n *n any *9 th*#e type# re#ult# in an int re#ult, !hich +u#t 3e e;plicitly ca#t 3ack t* the *riginal type Ga narr*!ing c*nver#i*n that +ight l*#e in9*r+ati*nH t* a##ign 3ack t* that type) ,ith int value#, h*!ever, y*u d* n*t need t* ca#t, 3ecau#e everything i# already an int) ?*nt 3e lulled int* thinking everything i#

Cha"ter 3* Controlling /rogram +low

1)#

#a9e, th*ugh) -9 y*u +ultiply t!* int# that are 3ig en*ugh, y*ull *ver9l*! the re#ult) The 9*ll*!ing e;a+ple de+*n#trate# thi#1 //:c0T:O*erH o..c# na!e#pace c0T; u#ing Sy#te!3 pu$ ic c a## O*erf o. ; pu$ ic #tatic *oid Gain01 ; int $ig 9 0xFfffffff3 // !ax int *a ue -rt0&$ig 9 & R $ig13 int $igger 9 $ig = E3 -rt0&$igger 9 & R $igger13 $igger 9 chec%ed0$ig = E13 //! -rt0&ne*er reached&13 < #tatic *oid -rt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 < < < //:8 The *utput *9 thi# i#1 $ig 9 2"EFEIT?EF $igger 9 6E Onhand ed +xception: Sy#te!.O*erf o.+xception: +xception of type Sy#te!.O*erf o.+xception .a# thro.n. at c0T.O*erf o..Gain01

-9 a p*tentially *ver9l*!ing +athe+atical *perati*n i# n*t !rapped in the chec(ed() key!*rd, y*u !ill get n* err*r# *r !arning# 9r*+ the c*+piler, and n* e;cepti*n# at runEti+e) Ot*d*1 Mue#ti*n P !hy arent all arith+etic *perati*n# in #a9e c*de checked and all arith+etic in un#a9e c*de n*tF C*+p*und a##ign+ent# d* not reDuire ca#t# 9*r char, byte, *r short, even th*ugh they are per9*r+ing pr*+*ti*n# that have the #a+e re#ult#

1)&

Thinking in C

www.ThinkingIn.!et

a# the direct arith+etic *perati*n#) On the *ther hand, the lack *9 the ca#t certainly #i+pli9ie# the c*de) :*u can #ee that, !ith the e;cepti*n *9 boolean, any pri+itive type can 3e ca#t t* any *ther pri+itive type) =gain, y*u +u#t 3e a!are *9 the e99ect *9 a narr*!ing c*nver#i*n !hen ca#ting t* a #+aller type, *ther!i#e y*u +ight unkn*!ingly l*#e in9*r+ati*n during the ca#t)

%&ecution control
C# u#e# all *9 C# e;ecuti*n c*ntr*l #tate+ent#, #* i9 y*uve pr*gra++ed !ith C *r C@@ then +*#t *9 !hat y*u #ee !ill 3e 9a+iliar) A*#t pr*cedural pr*gra++ing language# have #*+e kind *9 c*ntr*l #tate+ent#, and there i# *9ten *verlap a+*ng language#) -n C#, the key!*rd# include if-else, while, do-while, for, foreach, and a #electi*n #tate+ent called switch) C# 4u+ping key!*rd# are brea(, continue, goto Gye#, gotoH, and return)

true and 0alse


=ll c*nditi*nal #tate+ent# u#e the truth *r 9al#eh**d *9 a c*nditi*nal e;pre##i*n t* deter+ine the e;ecuti*n path) =n e;a+ple *9 a c*nditi*nal e;pre##i*n i# ' II B) Thi# u#e# the c*nditi*nal *perat*r II t* #ee i9 the value *9 ' i# eDuivalent t* the value *9 B) The e;pre##i*n return# true *r false) =ny *9 the relati*nal *perat*r# y*uve #een earlier in thi# chapter can 3e u#ed t* pr*duce a c*nditi*nal #tate+ent) *te that C# d*e#nt all*! y*u t* u#e a nu+3er a# a bool, even th*ugh it# all*!ed in C and C@ @ G!here truth i# n*n7er* and 9al#eh**d i# 7er*H and in Ci#ual Ba#ic G!here truth i# 7er* and 9al#eh**d n*nE7er*H) -9 y*u !ant t* u#e a n*nE bool in a bool te#t, #uch a# if(a), y*u +u#t 9ir#t c*nvert it t* a bool value u#ing a c*nditi*nal e;pre##i*n, #uch a# if(a !I 4))

i0;else
The if-else #tate+ent i# pr*3a3ly the +*#t 3a#ic !ay t* c*ntr*l pr*gra+ 9l*!) The else i# *pti*nal, #* y*u can u#e if in t!* 9*r+#1 if(Boo ean6expre##ion) #tate!ent

Cha"ter 3* Controlling /rogram +low

1)'

*r if(Boo ean6expre##ion) #tate!ent else #tate!ent The c*nditi*nal +u#t pr*duce a bool re#ult) The statement +ean# either a #i+ple #tate+ent ter+inated 3y a #e+ic*l*n *r a c*+p*und #tate+ent, !hich i# a gr*up *9 #i+ple #tate+ent# encl*#ed in 3race#) =ny ti+e the !*rd IstatementJ i# u#ed, it al!ay# i+plie# that the #tate+ent can 3e #i+ple *r c*+p*und) =# an e;a+ple *9 if-else, here i# a test( ) +eth*d that !ill tell y*u !hether a gue## i# a3*ve, 3el*!, *r eDuivalent t* a target nu+3er1 //:c0T:5f+ #e.c# na!e#pace c0T; pu$ ic c a## 5f+ #e ; #tatic int 'e#t0int te#t*a 2 int target1 ; int re#u t 9 03 if 0te#t*a Z target1 re#u t 9 R"3 e #e if 0te#t*a W target1 re#u t 9 6"3 e #e re#u t 9 03 // Gatch return re#u t3 < pu$ ic #tatic *oid Gain01 ; Sy#te!.Con#o e.VriteLine0'e#t0"02 P113 Sy#te!.Con#o e.VriteLine0'e#t0P2 "0113 Sy#te!.Con#o e.VriteLine0'e#t0P2 P113 < < <///:8 -t i# c*nventi*nal t* indent the 3*dy *9 a c*ntr*l 9l*! #tate+ent #* the reader +ight ea#ily deter+ine !here it 3egin# and end#)

13(

Thinking in C

www.ThinkingIn.!et

$eturn
The return key!*rd ha# t!* purp*#e#1 it #peci9ie# !hat value a +eth*d !ill return Gi9 it d*e#nt have a void return valueH and it cau#e# that value t* 3e returned i++ediately) The test( ) +eth*d a3*ve can 3e re!ritten t* take advantage *9 thi#1 //:c0T:5f+ #e2.c# pu$ ic c a## 5f+ #e2 ; #tatic int 'e#t0int te#t*a 2 int target1 ; int re#u t 9 03 if 0te#t*a Z target1 return "3 e #e if 0te#t*a W target1 return 6"3 e #e return 03 // Gatch < pu$ ic #tatic *oid Gain01 ; Sy#te!.Con#o e.VriteLine0'e#t0"02 P113 Sy#te!.Con#o e.VriteLine0'e#t0P2 "0113 Sy#te!.Con#o e.VriteLine0'e#t0P2 P113 < < ///:8 =lth*ugh thi# c*de ha# t!* else#, they are actually unnece##ary, 3ecau#e the +eth*d !ill n*t c*ntinue a9ter e;ecuting a return) -t i# g**d pr*gra++ing practice t* have a# 9e! e;it p*int# a# p*##i3le in a +eth*dQ a reader #h*uld 3e a3le t* #ee at a glance the I#hapeJ *9 a +eth*d !ith*ut having t* think IOhK Unle## #*+ething happen# in thi# c*nditi*nal, in !hich ca#e it never get# t* thi# *ther area)J) =9ter re!riting the +eth*d #* that there# *nly *ne e;it p*int, !e can add e;tra 9uncti*nality t* the +eth*d and kn*! that it !ill al!ay# 3e called1 //:c0T:5f+ #eT.c# pu$ ic c a## 5f+ #eT ; #tatic int 'e#t0int te#t*a 2 int target1 ; int re#u t 9 03 //Gatch if 0te#t*a Z target1

Cha"ter 3* Controlling /rogram +low

131

re#u t 9 "3 e #e if 0te#t*a W target1 re#u t 9 6"3 Sy#te!.Con#o e.VriteLine0&) here&13 return re#u t3

path# pa##

< pu$ ic #tatic *oid Gain01 ; Sy#te!.Con#o e.VriteLine0'e#t0"02 P113 Sy#te!.Con#o e.VriteLine0'e#t0P2 "0113 Sy#te!.Con#o e.VriteLine0'e#t0P2 P113 < < ///:8

Iteration
while, do-while, and for c*ntr*l l**ping and are #*+eti+e# cla##i9ied a# iteration statements) = statement repeat# until the c*ntr*lling BooleanEe%"ression evaluate# t* 9al#e) The 9*r+ 9*r a while l**p i# while(Boo ean6expre##ion) #tate!ent The Boolean9e%"ression i# evaluated *nce at the 3eginning *9 the l**p and again 3e9*re each 9urther iterati*n *9 the statement) Here# a #i+ple e;a+ple that generate# rand*+ nu+3er# until a particular c*nditi*n i# +et1 //:c0T:Vhi e'e#t.c# na!e#pace c0T; u#ing Sy#te!3 // :e!on#trate# the .hi e oop. pu$ ic c a## Vhi e'e#t ; pu$ ic #tatic *oid Gain01 ; Rando! rand 9 ne. Rando!013 dou$ e r 9 03 .hi e 0r W 0.>>d1 ; r 9 rand.Cext:ou$ e013 Sy#te!.Con#o e.VriteLine0r13 <

13)

Thinking in C

www.ThinkingIn.!et

< < <///:8 Thi# u#e# the static +eth*d random( ) in the .ath li3rary, !hich generate# a double value 3et!een $ and 0) G-t include# $, 3ut n*t 0)H The c*nditi*nal e;pre##i*n 9*r the while #ay# Ikeep d*ing thi# l**p until the nu+3er i# $)66 *r greater)J Each ti+e y*u run thi# pr*gra+ y*ull get a di99erentE#i7ed li#t *9 nu+3er#)

do;while
The 9*r+ 9*r do-while i# do #tate!ent while(Boo ean6expre##ion); The #*le di99erence 3et!een while and do-while i# that the #tate+ent *9 the do-while al!ay# e;ecute# at lea#t *nce, even i9 the e;pre##i*n evaluate# t* 9al#e the 9ir#t ti+e) -n a while, i9 the c*nditi*nal i# 9al#e the 9ir#t ti+e the #tate+ent never e;ecute#) -n practice, do-while i# le## c*++*n than while)

0or
= for l**p per9*r+# initiali7ati*n 3e9*re the 9ir#t iterati*n) Then it per9*r+# c*nditi*nal te#ting and, at the end *9 each iterati*n, #*+e 9*r+ *9 I#tepping)J The 9*r+ *9 the for l**p i#1 for(initia iMation; Boo ean6expre##ion; #tep) #tate!ent =ny *9 the e;pre##i*n# initiali;ation, Boolean9e%"ression *r ste" can 3e e+pty) The e;pre##i*n i# te#ted 3e9*re each iterati*n, and a# #**n a# it evaluate# t* false e;ecuti*n !ill c*ntinue at the line 9*ll*!ing the for #tate+ent) =t the end *9 each l**p, the ste" e;ecute#) for l**p# are u#ually u#ed 9*r Ic*untingJ ta#k#1 //:c0T:Li#tCharacter#.c#

Cha"ter 3* Controlling /rogram +low

133

na!e#pace c0T; u#ing Sy#te!3 // :e!on#trate# &for& oop $y i#ting // a the )SC55 character#. pu$ ic c a## Li#tCharacter# ; pu$ ic #tatic *oid Gain01 ; for 0 char c 9 0char1 03 c W 0char1 "2I3 cRR1 if 0c !9 2? 1 // )CS5 C ear #creen Sy#te!.Con#o e.VriteLine0 &*a ue: & R 0int1c R & character: & R c13 < < <///:8 *te that the varia3le c i# de9ined at the p*int !here it i# u#ed, in#ide the c*ntr*l e;pre##i*n *9 the for l**p, rather than at the 3eginning *9 the 3l*ck den*ted 3y the *pen curly 3race) The #c*pe *9 c i# the e;pre##i*n c*ntr*lled 3y the for) Traditi*nal pr*cedural language# like C reDuire that all varia3le# 3e de9ined at the 3eginning *9 a 3l*ck #* !hen the c*+piler create# a 3l*ck it can all*cate #pace 9*r th*#e varia3le#) -n C#, y*u can #pread y*ur varia3le declarati*n# thr*ugh*ut the 3l*ck, de9ining the+ at the p*int that y*u need the+) Thi# all*!# a +*re natural c*ding #tyle and +ake# c*de ea#ier t* under#tand) :*u can de9ine +ultiple varia3le# !ithin a for #tate+ent, 3ut they +u#t 3e *9 the #a+e type1 for0int i 9 02 D 9 "3 i W "0 @@ D !9 ""3 iRR2 DRR1 /= $ody of for oop =/3 The int de9initi*n in the for #tate+ent c*ver# 3*th i and )) The a3ility t* de9ine varia3le# in the c*ntr*l e;pre##i*n i# li+ited t* the for l**p) :*u

134

Thinking in C

www.ThinkingIn.!et

cann*t u#e thi# appr*ach !ith any *9 the *ther #electi*n *r iterati*n #tate+ent#)

0oreach
C# ha# a #peciali7ed iterati*n *perat*r called foreach) Unlike the *ther#, 9*reach d*e# n*t l**p 3a#ed *n a 3**lean e;pre##i*n) Rather, it e;ecute# a 3l*ck *9 c*de *n each ele+ent in an array *r *ther c*llecti*n) The 9*r+ 9*r foreach i#1 foreach0type oopNaria$ e in co ection1; #tate!ent < The foreach #tate+ent i# a ter#e !ay t* #peci9y the +*#t c*++*n type *9 l**p and d*e# #* !ith*ut intr*ducing p*tentially c*n9u#ing inde; varia3le#) C*+pare the clarity *9 foreach and for in thi# e;a+ple1

//:c0T:Hor+ach.c# c a## Hor+ach ; pu$ ic #tatic *oid Gain01 ; #tringJK !onth# 9 ;&`anuary&2 &He$ruary&2 &Garch&2 &)pri &<3 //etc #tringJK .ee%# 9 ;&"#t&2 &2nd&2 &Trd&2 &Eth&<3 #tringJK day# 9 ;&Sunday&2 &Gonday&2 &'ue#day&2 &Vedne#day&<3 //etc foreach0#tring !onth in !onth#1 foreach0#tring .ee% in .ee%#1 foreach0#tring day in day#1 Sy#te!.Con#o e.VriteLine0&;0< ;"< .ee% ;2<&2 !onth2 .ee%2 day13 for0int !onth 9 03 !onth W !onth#.Length3 !onthRR1 for0int .ee% 9 03 .ee% W .ee%#.Length3 .ee%RR1 for0int day 9 03 day W day#.Length3 dayRR1

Cha"ter 3* Controlling /rogram +low

135

Sy#te!.Con#o e.VriteLine0&;0< ;"< .ee% ;2<&2 !onth#J!onthK2 .ee%#J.ee%K2 day#JdayK13 < < ///:8 =n*ther advantage *9 foreach i# that it per9*r+# an i+plicit typeca#t *n *34ect# #t*red in c*llecti*n#, #aving a 9e! +*re key#tr*ke# !hen *34ect# are #t*red n*t in array#, 3ut in +*re c*+ple; data #tructure#) ,ell c*ver thi# a#pect *9 foreach in Chapter #)

-he co##a o$erator


Earlier in thi# chapter - #tated that the c*++a o"erator Gn*t the c*++a se"arator, !hich i# u#ed t* #eparate de9initi*n# and 9uncti*n argu+ent#H ha# *nly *ne u#e in C#1 in the c*ntr*l e;pre##i*n *9 a for l**p) -n 3*th the initiali7ati*n and #tep p*rti*n# *9 the c*ntr*l e;pre##i*n y*u can have a nu+3er *9 #tate+ent# #eparated 3y c*++a#, and th*#e #tate+ent# !ill 3e evaluated #eDuentially) The previ*u# 3it *9 c*de u#e# thi# a3ility) Here# an*ther e;a+ple1 //:c0T:Li#tCharacter#.c# na!e#pace c0T; u#ing Sy#te!3 pu$ ic c a## Co!!aOperator ; pu$ ic #tatic *oid Gain01 ; for0int i 9 "2 D 9 i R "03 i W P3 iRR2 D 9 i = 21 ; Sy#te!.Con#o e.VriteLine0&i9 & R i R & D9 & R D13 < < < <///:8 Here# the *utput1 i9 i9 i9 i9 " 2 T E D9 D9 D9 D9 "" E ? I

136

Thinking in C

www.ThinkingIn.!et

:*u can #ee that in 3*th the initiali7ati*n and #tep p*rti*n# the #tate+ent# are evaluated in #eDuential *rder) =l#*, the initiali7ati*n p*rti*n can have any nu+3er *9 de9initi*n# o$ one t4"e)

+rea* and continue


-n#ide the 3*dy *9 any *9 the iterati*n #tate+ent# y*u can al#* c*ntr*l the 9l*! *9 the l**p 3y u#ing brea( and continue) brea( Duit# the l**p !ith*ut e;ecuting the re#t *9 the #tate+ent# in the l**p) continue #t*p# the e;ecuti*n *9 the current iterati*n and g*e# 3ack t* the 3eginning *9 the l**p t* 3egin the ne;t iterati*n) Thi# pr*gra+ #h*!# e;a+ple# *9 brea( and continue !ithin for and while l**p#1 //:c0T:Brea%)ndContinue.c# na!e#pace c0T; u#ing Sy#te!3 // :e!on#trate# $rea% and continue %ey.ord#. pu$ ic c a## Brea%)ndContinue ; pu$ ic #tatic *oid Gain01 ; //\todo can4t dec are 5 after oop! int i 9 03 for0i 9 03 i W "003 iRR1 ; if0i 99 FE1 $rea%3 // Out of for oop if0i [ > !9 01 continue3 // Cext iteration Sy#te!.Con#o e.VriteLine0i13 < i 9 03 // )n &infinite oop&: .hi e0true1 ; iRR3 int D 9 i = 2F3 if0D 99 "2?>1 $rea%3 // Out of oop if0i [ "0 !9 01 continue3 // 'op of oop Sy#te!.Con#o e.VriteLine0i13 < < <

Cha"ter 3* Controlling /rogram +low

13#

<///:8 -n the for l**p the value *9 i never get# t* 0$$ 3ecau#e the brea( #tate+ent 3reak# *ut *9 the l**p !hen i i# %&) *r+ally, y*ud u#e a brea( like thi# *nly i9 y*u didnt kn*! !hen the ter+inating c*nditi*n !a# g*ing t* *ccur) The continue #tate+ent cau#e# e;ecuti*n t* g* 3ack t* the t*p *9 the iterati*n l**p Gthu# incre+enting iH !henever i i# n*t evenly divi#i3le 3y 6) ,hen it i#, the value i# printed) The #ec*nd p*rti*n #h*!# an Iin9inite l**pJ that !*uld, in the*ry, c*ntinue 9*rever) H*!ever, in#ide the l**p there i# a brea( #tate+ent that !ill 3reak *ut *9 the l**p) -n additi*n, y*ull #ee that the continue +*ve# 3ack t* the t*p *9 the l**p !ith*ut c*+pleting the re+ainder) GThu# printing happen# in the #ec*nd l**p *nly !hen the value *9 i i# divi#i3le 3y 0$)H The *utput i#1 0 > "I 2F T? EP PE ?T F2 "0 20 T0 E0 The value $ i# printed 3ecau#e $ ^ 6 pr*duce# $) = #ec*nd 9*r+ *9 the in9inite l**p i# for(FF)) The c*+piler treat# 3*th while(true) and for(FF) in the #a+e !ay, #* !hichever *ne y*u u#e i# a +atter *9 pr*gra++ing ta#te) G=lth*ugh while(true) i# clearly the *nly ch*ice 9*r a per#*n *9 di#cri+inating ta#te)H

-he in0a#ous GgotoH


The goto key!*rd ha# 3een pre#ent in pr*gra++ing language# 9r*+ the 3eginning) -ndeed, goto !a# the gene#i# *9 pr*gra+ c*ntr*l in a##e+3ly

13&

Thinking in C

www.ThinkingIn.!et

language1 Ii9 c*nditi*n =, then 4u+p here, *ther!i#e 4u+p there)J -9 y*u read the a##e+3ly c*de that i# ulti+ately generated 3y virtually any c*+piler, y*ull #ee that pr*gra+ c*ntr*l c*ntain# +any 4u+p#) H*!ever, a goto i# a 4u+p at the #*urceEc*de level, and that# !hat 3r*ught it int* di#repute) -9 a pr*gra+ !ill al!ay# 4u+p 9r*+ *ne p*int t* an*ther, i#nt there #*+e !ay t* re*rgani7e the c*de #* the 9l*! *9 c*ntr*l i# n*t #* 4u+pyF goto 9ell int* true di#9av*r !ith the pu3licati*n *9 the 9a+*u# 06.( paper I>* T* State+ent C*n#idered Har+9ulJ 3y Ed#ger ?i4k#tra Ghttp1<<!!!)ac+)*rg<cla##ic#<*ct6'<H) ?i4k#tra argued that !hen y*u have a 4u+p, the c*nte;t that created the pr*gra+ #tate 3ec*+e# di99icult t* vi#uali7e) Since then, g*t*E3a#hing ha# 3een a p*pular #p*rt, !ith adv*cate# *9 the ca#tE*ut key!*rd #currying 9*r c*ver) =# i# typical in #ituati*n# like thi#, the +iddle gr*und i# the +*#t 9ruit9ul) The pr*3le+ i# n*t the u#e *9 goto, 3ut the *veru#e *9 goto *r, indeed, any #tate+ent that +ake# it di99icult t* #ay I,hen thi# line i# reached, the #tate *9 the #y#te+ i# nece##arily #uchEandE#uch)J The 3e#t !ay t* !rite c*de that +ake# #y#te+ #tate ea#y t* deter+ine i# t* +ini+i7e cycl*+atic c*+ple;ity, !hich i# a 9ancy !ay *9 #aying Iu#e a# 9e! #electi*n and 4u+p #tate+ent# a# p*##i3le)J Cycl*+atic c*+ple;ity i# the +ea#ure *9 the nu+3er *9 p*##i3le path# thr*ugh a 3l*ck *9 c*de)
Error! Not a valid link.

-n 9igure #, the +eth*d# #i+pleGH and al#*Si+pleGH have a cycl*+atic c*+ple;ity *9 0Q there i# *nly a #ingle path thr*ugh the c*de) -t d*e# n*t +atter h*! l*ng the +eth*d i#, !hether the +eth*d create# *34ect#, *r even i9 the +eth*d call# *ther, +*re c*+ple;, +eth*d# Gi9 th*#e +eth*d# have high c*+ple;ity, #* 3e it, it d*e#nt a99ect the c*+ple;ity *9 the +eth*d at handH) Thi# #i+plicity i# re9lected in the c*ntr*l graph #h*!nQ a #ingle line #h*!ing the directi*n *9 e;ecuti*n t*!ard# the e;it p*int) The +eth*d *neL**pGH i# #lightly +*re c*+ple;) * +atter !hat it# input para+eter, it !ill print *ut IBeginJ and a##ign ; t* y at the very 3eginning *9 the 9*r l**p) That# the 9ir#t edge *n it# c*ntr*l graph Gt* help align !ith the #*urce c*de, the 9igure #h*!# a #ingle IedgeJ a# a #traight length *9 c*de and a curving 4u+pH) Then, it ma4 c*ntinue int* the l**p, a##ign 7 and print it, incre+ent y, and l**pQ that# the #ec*nd edge) 5inally, at #*+e p*int, y !ill 3e eDual t* 0$ and c*ntr*l !ill 4u+p t* the

Cha"ter 3* Controlling /rogram +low

13'

end *9 the +eth*d) Thi# i# the third edge, a# +arked *n the 9igure) Aeth*d t!*E;it#GH al#* ha# a cycl*+atic c*+ple;ity *9 /, alth*ugh it# #ec*nd edge d*e#nt l**p, 3ut e;it#) The ne;t +eth*d, t!*L**p#GH, hardly #ee+# +*re c*+ple; than *neL**pGH, 3ut i9 y*u l**k at it# c*ntr*l graph, y*u can c*unt 9ive di#tinct edge#) 5inally, !e #ee a vi#ual repre#entati*n *9 !hat pr*gra++er# call I#paghetti c*de)J ,ith a cycl*+atic c*+ple;ity *9 02, #paghettiGH i# a3*ut a# c*+ple; a# a +eth*d #h*uld e-er 3e) Once a +eth*d ha# +*re than a3*ut #i; c*nditi*nal and iterati*n *perat*r#, it #tart# t* 3ec*+e di99icult t* under#tand the ra+i9icati*n# *9 any change#) -n the 06'$#, the p#ych*l*gi#t >e*rge Ailler pu3li#hed a paper that #aid that ISeven plu# *r +inu# t!*J i# the li+it *9 *ur I#pan *9 a3#*lute 4udg+ent)J Trying t* keep +*re than thi# nu+3er *9 thing# in *ur head at *nce i# very err*rEpr*ne) Luckily, !e have thi# thing called I!ritingJ G*r, in *ur ca#e, c*ding C#H !hich all*!# u# t* 3reak the pr*3le+ *9 Ia3#*lute 4udg+entJ int* #ucce##ive #u3Epr*3le+#, !hich can then 3e treated a# unit# 9*r the purp*#e *9 +aking higherElevel 4udg+ent#) S*und# like c*+puter pr*gra++ing t* +eK GThe paper p*int# *ut that 3y increa#ing the di+en#i*n *9 vi#ual varia3le#, !e can achieve a#t*ni#hing level# *9 di#cri+inati*n a# !e d*, #ay, !hen !e rec*gni7e a 9riend !eve n*t #een in year# !hile ru#hing thr*ugh an airp*rt) -t# intere#ting t* n*te that c*+puter pr*gra++ing hardly leverage# thi# capacity at all) :*u can read the paper, !hich anticipate# e;actly the #*rt *9 thinking and ch*iceE+aking c*++*n t* pr*gra++ing, at http1<<!!!)!ell)c*+<u#er<#+alin<+iller)ht+lH -n C#, goto can 3e u#ed t* 4u+p !ithin a +eth*d t* a la3el) = la3el i# an identi9ier 9*ll*!ed 3y a c*l*n, like thi#1 a$e ": =lth*ugh it# legal t* place a la3el any!here in a +eth*d, the *nly place !here it# a g**d idea i# right 3e9*re an iterati*n #tate+ent) =nd the #*le rea#*n t* put a la3el 3e9*re an iterati*n i# i9 y*ure g*ing t* ne#t an*ther iterati*n *r a #!itch in#ide it) That# 3ecau#e !hile brea( and continue interrupt *nly the l**p that c*ntain# the+, goto can interrupt the l**p#

14(

Thinking in C

www.ThinkingIn.!et

up t* !here the la3el e;i#t#) Here i# an e;a+ple *9 the u#e and a3u#e *9 goto1 //:c0T:_oto.c# // O#ing _oto u#ing Sy#te!3 pu$ ic c a## _oto ; pu$ ic #tatic *oid Gain01 ; int i 9 03 Rando! rand 9 ne. Rando!013 outer: //La$e $efore iterator for03 true 31 ; // infinite oop prt0&-rior to entering inner oop&13 inner: // )nother a$e for03 i W "03 iRR1 ; prt0&i 9 & R i13 if0i 99 F1 ; prt0&goto outer&13 iRR3 // Other.i#e i ne*er // get# incre!ented. goto outer3 < if0i 99 I1 ; prt0&goto inner&13 iRR3 //Other.i#e i ne*er //get# incre!ented goto inner3 < dou$ e d 9 rand.Cext:ou$ e013 if0i 99 > @@ d W 0.?1; prt0&Lega 2 $ut terri$ e&13 goto $ad5dea3 < prt0&Bac% in the oop&13 if0i 99 >1 goto $u#tOut3 < < $u#tOut: prt0&+xit oop&13

Cha"ter 3* Controlling /rogram +low

141

if0rand.Cext:ou$ e01 W 0.P1; goto #paghetti`u!p3 < $ad5dea: prt0&Uo. did 5 get hereY&13 goto outer3 #paghetti`u!p: prt0&:on't e*er2 e*er do thi#.&13 < #tatic *oid prt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 < < ///:8 Thing# #tart *ut appr*priately en*ugh, !ith the la3eling *9 the t!* l**p# a# outer and inner) =9ter c*unting t* % and getting lulled int* a 9al#e #en#e *9 #ecurity, c*ntr*l 4u+p# *ut *9 3*th l**p#, and reEenter# 9*ll*!ing the outer la3el) On the ne;t l**p, c*ntr*l 4u+p# t* the inner la3el) Then thing# get !eird1 i9 the rand*+ nu+3er generat*r c*+e# up !ith a value le## than $)., c*ntr*l 4u+p# d*!n!ard#, t* the la3el +arked badBdea, the +eth*d print# IH*! did - get hereFJ and then 4u+p# all the !ay 3ack t* the outer la3el) On the ne;t run thr*ugh the inner l**p, i i# #till eDual t* 6 3ut, eventually, the rand*+ nu+3er generat*r !ill c*+e up !ith a value that !ill #kip the 4u+p t* badBdea and print that !ere I3ack in the l**p)J Then, in#tead *9 u#ing the for #tate+ent# ter+inating c*nditi*n, !e decide that !ere g*ing t* 4u+p t* the bust1ut la3el) ,e d* the pr*gra++atic eDuivalent *9 9lipping a c*in and either I9all thr*ughJ int* the badBdea area G!hich, *9 c*ur#e, 4u+p# u# 3ack t* outerH *r 4u+p t* the spaghettiXump la3el) S* !hy i# thi# c*de c*n#idered #* terri3leF 5*r *ne thing, it ha# a high cycl*+atic c*+ple;ity P it# 4u#t plain c*n9u#ing) =l#*, n*te h*! +uch harder it i# t* under#tand pr*gra+ 9l*! !hen *ne cant rely *n 3racket# and indenting) =nd t* +ake thing# !*r#e, let# #ay y*u !ere de3ugging thi# c*de and y*u placed a 3reakp*int at the line prt0AUo. did 5 get hereYB1. ,hen the 3reakp*int i# reached, there i# n* !ay, #h*rt *9 e;a+ining the *utput, 9*r y*u t* deter+ine !hether y*u reached it 9r*+ the 4u+p 9r*+ the inner l**p *r 9r*+ 9alling thr*ugh 9r*+ the i++ediately preceding line# Gin thi# ca#e, the pr*gra+# *utput i#

14)

Thinking in C

www.ThinkingIn.!et

#u99icient t* thi# cau#e, 3ut in the real !*rld *9 c*+ple; #y#te+#, >U-#, and ,e3 Service#, it never i#H) =# ?i4k#tra put it, Iit 3ec*+e# terri3ly hard t* 9ind a +eaning9ul #et *9 c**rdinate# in !hich t* de#cri3e the pr*ce## pr*gre##)J By Ic**rdinate#J ?i4k#tra +eant a !ay t* kn*! the path 3y !hich a #y#te+ arrived in it# current #tate) -t# *nly !ith #uch a path in hand that *ne can de3ug, #ince challenging de9ect# *nly 3ec*+e apparent #*+eti+e a$ter the +i#take ha# 3een +ade) G-t i#, *9 c*ur#e, c*++*n t* +ake +i#take# i++ediately *r 4u#t 3e9*re the pr*3le+ 3ec*+e# apparent, 3ut #uch +i#take# arent hard t* r**t *ut and c*rrect)H ?i4k#tra !ent *n t* #ay that hi# critici#+ !a# n*t 4u#t a3*ut goto, 3ut that all language c*n#truct# Ishould satis$4 the re8uirement that a "rogrammer inde"endent coordinate s4stem can 2e maintained to descri2e the "rocess in a hel"$ul and managea2le wa4.< ,ell revi#it thi# c*ncern !hen #peaking *9 the !ay that C# and the ) ET 9ra+e!*rk handle e;cepti*n# G*3eying the reDuire+entH and threading G!hich d*e#nt *3ey the reDuire+ent, 3ut c*uldH)

'witch
The switch i# #*+eti+e# cla##i9ied a# a selection statement) The switch #tate+ent #elect# 9r*+ a+*ng piece# *9 c*de 3a#ed *n the value *9 an integral e;pre##i*n) -t# 9*r+ i#1 switch(integra 6#e ector) { case integra 6*a ue" : #tate!ent; break; case integra 6*a ue2 : #tate!ent; return; case integra 6*a ueT : #tate!ent; continue; case integra 6*a ueE : #tate!ent; throw exception; case integra 6*a ueP : #tate!ent; goto externa 6 a$e ; case integra 6*a ue? : //Co #tate!ent# case integra 6*a ueF : #tate!ent3 goto case integra 6*a ue3 // ... default: #tate!ent; break; <

Cha"ter 3* Controlling /rogram +low

143

Integral9selector i# an e;pre##i*n that pr*duce# an integral value) The switch c*+pare# the re#ult *9 integral9selector t* each integral9-alue) -9 it 9ind# a +atch, the c*rre#p*nding statement G#i+ple *r c*+p*undH e;ecute#) -9 n* +atch *ccur#, the default statement e;ecute#) :*u !ill n*tice in the a3*ve de9initi*n that each case end# !ith #*+e kind *9 4u+p #tate+ent) The 9ir#t *ne #h*!n, brea(, i# 3y 9ar the +*#t c*++*nly u#ed) *te that goto can 3e u#ed in 3*th the 9*r+ di#cu##ed previ*u#ly, !hich 4u+p# t* an ar3itrary la3el in the encl*#ing #tate+ent 3l*ck, and in a ne! 9*r+, goto case, !hich tran#9er# c*ntr*l t* the #peci9ied ca#e 3l*ck) Unlike "ava and C@@, each ca#e 3l*ck, including the de9ault 3l*ck, +u#t end in a 4u+p #tate+ent) There i# n* I9allEthr*ugh,J alth*ugh #elect*r# +ay i++ediately precede *ther #elect*r#) -n the de9initi*n, thi# i# #een at the #elect*r 9*r integralEvalue., !hich !ill e;ecute the #tate+ent# in integralEvalue%# ca#e 3l*ck) The switch #tate+ent i# a clean !ay t* i+ple+ent +ultiE!ay #electi*n Gi)e), #electing 9r*+ a+*ng a nu+3er *9 di99erent e;ecuti*n path#H, 3ut it reDuire# a #elect*r that evaluate# t* a prede9ined type #uch a# int, char, *r string, *r t* an enu+erati*n) 5*r *ther type#, y*u +u#t u#e either a #erie# *9 if #tate+ent#, *r i+ple+ent #*+e kind *9 c*nver#i*n t* *ne *9 the #upp*rted type#) A*re generally, a !ellEde#igned *34ectE*riented pr*gra+ !ill generally +*ve a l*t *9 c*ntr*l #!itching a!ay 9r*+ e;plicit te#t# in c*de int* p*ly+*rphi#+ G!hich !ell get t* in #H Here# an e;a+ple that create# letter# rand*+ly and deter+ine# !hether theyre v*!el# *r c*n#*nant#1 //:c0T: No.e #)ndCon#onant#.c# /// :e!on#trate# the #.itch #tate!ent. na!e#pace c0T; u#ing Sy#te!3 pu$ ic c a## No.e #)ndCon#onant# ; pu$ ic #tatic *oid Gain01 ; Rando! rand 9 ne. Rando!013 for0int i 9 03 i W "003 iRR1 ; char c 9 0char10rand.Cext0'a'2'M'113

144

Thinking in C

www.ThinkingIn.!et

Sy#te!.Con#o e.VriteLine0c R &: &13 #.itch0c1 ; ca#e 'a': ca#e 'e': ca#e 'i': ca#e 'o': ca#e 'u': Sy#te!.Con#o e.VriteLine0&*o.e &13 $rea%3 ca#e 'y': ca#e '.': Sy#te!.Con#o e.VriteLine0 &So!eti!e# a *o.e &13 $rea%3 defau t: Sy#te!.Con#o e.VriteLine0&con#onant&13 $rea%3 < < < < <///:8 Since char# can 3e i+plicitly pr*+*ted t* int#, Rand*+) e;tGint l*!erB*und, int upperB*undH can 3e u#ed t* return value# in the appr*priate =SC-- range)

Calculation details
TH-S -S N- ? O5 - TEREST- > STU55 BUT -S OT RELEC= T TO THE =BOCE) AOCE ELSE,HEREF RE,R-TE TEBT

The #tate+ent1 char c 9 0char10Gath.rando!01 = 2? R 'a'13 de#erve# a cl*#er l**k) .ath6random( ) pr*duce# a double, #* the value 2. i# c*nverted t* a double t* per9*r+ the +ultiplicati*n, !hich

Cha"ter 3* Controlling /rogram +low

145

al#* pr*duce# a double) Thi# +ean# that 2a5 +u#t 3e c*nverted t* a double t* per9*r+ the additi*n) The double re#ult i# turned 3ack int* a char !ith a ca#t) ,hat d*e# the ca#t t* char d*F That i#, i9 y*u have the value 26)% and y*u ca#t it t* a char, i# the re#ulting value /$ *r 26F The an#!er t* thi# can 3e #een in thi# e;a+ple1 //:c0T:Ca#tingCu!$er#.c# na!e#pace c0T; u#ing Sy#te!3 // Vhat happen# .hen you ca#t a f oat // or dou$ e to an integra *a ueY pu$ ic c a## Ca#tingCu!$er# ; pu$ ic #tatic *oid Gain01 ; dou$ e a$o*e 9 0.F2 $e o. 9 0.E3 Sy#te!.Con#o e.VriteLine0&a$o*e: & R a$o*e13 Sy#te!.Con#o e.VriteLine0&$e o.: & R $e o.13 Sy#te!.Con#o e.VriteLine0 &0int1a$o*e: & R 0int1a$o*e13 Sy#te!.Con#o e.VriteLine0 &0int1$e o.: & R 0int1$e o.13 Sy#te!.Con#o e.VriteLine0 &0char10'a' R a$o*e1: & R 0char10'a' R a$o*e113 Sy#te!.Con#o e.VriteLine0 &0char10'a' R $e o.1: & R 0char10'a' R $e o.113 < <

146

Thinking in C

www.ThinkingIn.!et

<///:8 The *utput i#1 a$o*e: 0.F $e o.: 0.E 0int1a$o*e: 0 0int1$e o.: 0 0char10'a' R a$o*e1: a 0char10'a' R $e o.1: a S* the an#!er i# that ca#ting 9r*+ a float *r double t* an integral value al!ay# truncate#) = #ec*nd Due#ti*n c*ncern# .ath6random( )) ?*e# it pr*duce a value 9r*+ 7er* t* *ne, inclu#ive *r e;clu#ive *9 the value T0F -n +ath ling*, i# it G$,0H, *r Z$,0\, *r G$,0\ *r Z$,0HF GThe #Duare 3racket +ean# Iinclude#J !herea# the parenthe#i# +ean# Id*e#nt include)JH =gain, a te#t pr*gra+ +ight pr*vide the an#!er1 //:c0T:Rando!Bound#.c# na!e#pace c0T; u#ing Sy#te!3 // :oe# Rando!.Cext01 produce 0 and 5ntT2.GaxXNa ueY pu$ ic c a## Rando!Bound# ; #tatic *oid u#age01 ; Sy#te!.Con#o e.VriteLine0&O#age: ^n^t& R &Rando!Bound# o.er^n^t& R &Rando!Bound# upper^n^t& R &Rando!Bound# $ounded&13 +n*iron!ent.+xit0"13 < pu$ ic #tatic *oid Gain0#tringJK arg#1 ; if 0arg#.Length !9 "1 u#age013 Rando! rand 9 ne. Rando!013 if 0arg#J0K 99 & o.er&1 ; .hi e 0rand.Cext01 !9 01 3 // aeep trying

Cha"ter 3* Controlling /rogram +low

14#

Sy#te!.Con#o e.VriteLine0&-roduced 0!&13 < e #e if 0arg#J0K 99 &upper&1 ; .hi e 0rand.Cext01 !9 5ntT2.GaxNa ue1 3 // aeep trying Sy#te!.Con#o e.VriteLine0&-roduced & R 5ntT2.GaxNa ue13 < e #e if 0arg#J0K 99 &$ounded&1 ; $oo foundLo.erBound 9 fa #e3 $oo foundOpperBound 9 fa #e3 do ; int $ounded 9 rand.Cext002 "013 if 0$ounded 99 01 ; Sy#te!.Con#o e.VriteLine0&Hound o.er $ound!&13 foundLo.erBound 9 true3 < if 0$ounded 99 "01 ; Sy#te!.Con#o e.VriteLine0&Hound upper $ound!&13 foundOpperBound 9 true3 < <.hi e 0!foundLo.erBound SS ! foundOpperBound13 < e #e u#age013 < < < ///:8 T* run the pr*gra+, y*u type a c*++and line *9 either1 Rando!Bound# *r Rando!Bound# upper -n 3*th ca#e# y*u are 9*rced t* 3reak *ut *9 the pr*gra+ +anually, #* it !*uld appear that Aath)rand*+G H never pr*duce# either $)$ *r 0)$) But o.er

14&

Thinking in C

www.ThinkingIn.!et

thi# i# !here #uch an e;peri+ent can 3e deceiving) -9 y*u c*n#ider 2 that there are a3*ut 2.2 di99erent d*u3le 9racti*n# 3et!een $ and 0, the likelih**d *9 reaching any *ne value e;peri+entally +ight e;ceed the li9eti+e *9 *ne c*+puter, *r even *ne e;peri+enter) -t turn# *ut that $)$ i# included in the *utput *9 Aath)rand*+G H) Or, in +ath ling*, it i# Z$,0H)

'u##ar5
Thi# chapter c*nclude# the #tudy *9 9unda+ental 9eature# that appear in +*#t pr*gra++ing language#1 calculati*n, *perat*r precedence, type ca#ting, and #electi*n and iterati*n) *! y*ure ready t* 3egin taking #tep# that +*ve y*u cl*#er t* the !*rld *9 *34ectE*riented pr*gra++ing) The ne;t chapter !ill c*ver the i+p*rtant i##ue# *9 initiali7ati*n and cleanup *9 *34ect#, 9*ll*!ed in the #u3#eDuent chapter 3y the e##ential c*ncept *9 i+ple+entati*n hiding)

%&ercises

2 Chuck =lli#*n !rite#1 The t*tal nu+3er *9 nu+3er# in a 9l*atingEp*int nu+3er #y#te+ i#

8(.-mC7)bN(p-7) C 7 !here b i# the 3a#e Gu#ually 2H, p i# the preci#i*n Gdigit# in the +anti##aH, . i# the large#t e;p*nent, and m i# the #+alle#t e;p*nent) -EEE %'& u#e#1 . I 7489, m I -7488, p I Y9, b I 8 #* the t*tal nu+3er *9 nu+3er# i# 8(7489C7488C7)8NY8 I 8((8N74-7) C (8N74-7))8NY8 I (8N74-7)8NYJ I 8NZJ - 8NYJ Hal9 *9 the#e nu+3er# Gc*rre#p*nding t* e;p*nent# in the range ZE0$22, $\H are le## than 0 in +agnitude G3*th p*#itive and negativeH, #* 0<& *9 that e;pre##i*n, *r 2_.2 E 2_'2 @ 0 Gappr*;i+ately 2_.2H i# in the range Z$,0H) See +y paper at http1<<!!!)9re#h#*urce#)c*+<066'$$.a)ht+ Gla#t *9 te;tH)

Cha"ter 3* Controlling /rogram +low

14'

!, Initiali:ation I Cleanu$
=# the c*+puter rev*luti*n pr*gre##e#, Iun#a9eJ pr*gra++ing ha# 3ec*+e *ne *9 the +a4*r culprit# that +ake# pr*gra++ing e;pen#ive)
T!* *9 the#e #a9ety i##ue# are initiali;ation and cleanu") Aany C 3ug# *ccur !hen the pr*gra++er 9*rget# t* initiali7e a varia3le) Thi# i# e#pecially true !ith li3rarie# !hen u#er# d*nt kn*! h*! t* initiali7e a li3rary c*+p*nent, *r even that they +u#t) Cleanup i# a #pecial pr*3le+ 3ecau#e it# ea#y t* 9*rget a3*ut an ele+ent !hen y*ure d*ne !ith it, #ince it n* l*nger c*ncern# y*u) Thu#, the re#*urce# u#ed 3y that ele+ent are retained and y*u can ea#ily end up running *ut *9 re#*urce# G+*#t n*ta3ly, +e+*ryH) C@@ intr*duced the c*ncept *9 a constructor and a destructor, #pecial +eth*d# aut*+atically called !hen an *34ect i# created and de#tr*yed) C# ha# the#e 9acilitie#, and in additi*n ha# a gar3age c*llect*r that aut*+atically relea#e# +e+*ry re#*urce# !hen theyre n* l*nger 3eing u#ed) Thi# chapter e;a+ine# the i##ue# *9 initiali7ati*n and cleanup, and their #upp*rt in C#)

Guaranteed initiali:ation with the constructor


:*u can i+agine creating a +eth*d called BnitialiTe( ) 9*r every cla## y*u !rite) The na+e i# a hint that it #h*uld 3e called 3e9*re u#ing the *34ect) Un9*rtunately, thi# +ean# the u#er +u#t re+e+3er t* call the +eth*d) -n C#, the cla## de#igner can guarantee initiali7ati*n *9 every *34ect 3y pr*viding a #pecial +eth*d called a constructor) -9 a cla## ha# a c*n#truct*r, C# aut*+atically call# that c*n#truct*r !hen an *34ect i#

151

created, 3e9*re u#er# can even get their hand# *n it) S* initiali7ati*n i# guaranteed) The ne;t challenge i# !hat t* na+e thi# +eth*d) There are t!* i##ue#) The 9ir#t i# that any na+e y*u u#e c*uld cla#h !ith a na+e y*u +ight like t* u#e a# a +e+3er in the cla##) The #ec*nd i# that 3ecau#e the c*+piler i# re#p*n#i3le 9*r calling the c*n#truct*r, it +u#t al!ay# kn*! !hich +eth*d t* call) The C@@ #*luti*n #ee+# the ea#ie#t and +*#t l*gical, #* it# al#* u#ed in C#1 the na+e *9 the c*n#truct*r i# the #a+e a# the na+e *9 the cla##) -t +ake# #en#e that #uch a +eth*d !ill 3e called aut*+atically *n initiali7ati*n) Here# a #i+ple cla## !ith a c*n#truct*r1 //:c0E:Si!p eCon#tructor.c# na!e#pace c0E; u#ing Sy#te!3 // :e!on#tration of a #i!p e con#tructor. c a## Roc% ; pu$ ic Roc%01 ; // 'hi# i# the con#tructor Sy#te!.Con#o e.VriteLine0&Creating Roc%&13 < < pu$ ic c a## Si!p eCon#tructor ; pu$ ic #tatic *oid Gain01 ; for0int i 9 03 i W "03 iRR1 ne. Roc%013 < < <///:8 *!, !hen an *34ect i# created1 ne. Roc%013 #t*rage i# all*cated and the c*n#truct*r i# called) -t i# guaranteed that the *34ect !ill 3e pr*perly initiali7ed 3e9*re y*u can get y*ur hand# *n it) *te that the na+e *9 the c*n#truct*r +u#t +atch the na+e *9 the cla## e%actl4)

15)

Like any +eth*d, the c*n#truct*r can have argu+ent# t* all*! y*u t* #peci9y how an *34ect i# created) The a3*ve e;a+ple can ea#ily 3e changed #* the c*n#truct*r take# an argu+ent1 //:c0E:Si!p eCon#trutor2.c# na!e#pace c0E; u#ing Sy#te!3 // :e!on#tration of a #i!p e con#tructor. c a## Roc%2 ; pu$ ic Roc%20int i1 ; // 'hi# i# the con#tructor Sy#te!.Con#o e.VriteLine0&Creating Roc% nu!$er: & R i13 < < pu$ ic c a## Si!p eCon#tructor ; pu$ ic #tatic *oid Gain01 ; for0int i 9 03 i W "03 iRR1 ne. Roc%20i13 < < <///:8 C*n#truct*r argu+ent# pr*vide y*u !ith a !ay t* pr*vide para+eter# 9*r the initiali7ati*n *9 an *34ect) 5*r e;a+ple, i9 the cla## +ree ha# a c*n#truct*r that take# a #ingle integer argu+ent den*ting the height *9 the tree, y*u !*uld create a +ree *34ect like thi#1 'ree t 9 ne. 'ree0"213 // "26foot tree

-9 +ree(int) i# y*ur *nly c*n#truct*r, then the c*+piler !*nt let y*u create a +ree *34ect any *ther !ay) C*n#truct*r# eli+inate a large cla## *9 pr*3le+# and +ake the c*de ea#ier t* read) -n the preceding c*de 9rag+ent, 9*r e;a+ple, y*u d*nt #ee an e;plicit call t* #*+e initialiTe( ) +eth*d that i# c*nceptually #eparate 9r*+ de9initi*n) -n C#, de9initi*n and initiali7ati*n are uni9ied c*ncept#R y*u cant have *ne !ith*ut the *ther) The c*n#truct*r i# an unu#ual type *9 +eth*d 3ecau#e it ha# n* return value) Thi# i# di#tinctly di99erent 9r*+ a void return value, in !hich the

Cha"ter 4* Initiali;ation = Cleanu"

153

+eth*d return# n*thing 3ut y*u #till have the *pti*n t* +ake it return #*+ething el#e) C*n#truct*r# return n*thing and y*u d*nt have an *pti*n) -9 there !a# a return value, and i9 y*u c*uld #elect y*ur *!n, the c*+piler !*uld #*+eh*! need t* kn*! !hat t* d* !ith that return value) =ccidentally typing a return type #uch a# void 3e9*re declaring a +eth*d i# a c*++*n thing t* d* *n a A*nday +*rning, 3ut the C# c*+piler !*nt all*! it, telling y*u I+e+3er na+e# cann*t 3e the #a+e a# their encl*#ing type)J

@ethod overloading
One *9 the i+p*rtant 9eature# in any pr*gra++ing language i# the u#e *9 na+e#) ,hen y*u create an *34ect, y*u give a na+e t* a regi*n *9 #t*rage) = +eth*d i# a na+e 9*r an acti*n) By u#ing na+e# t* de#cri3e y*ur #y#te+, y*u create a pr*gra+ that i# ea#ier 9*r pe*ple t* under#tand and change) -t# a l*t like !riting pr*#eRthe g*al i# t* c*++unicate !ith y*ur reader#) :*u re9er t* all *34ect# and +eth*d# 3y u#ing na+e#) ,ellEch*#en na+e# +ake it ea#ier 9*r y*u and *ther# t* under#tand y*ur c*de) = pr*3le+ ari#e# !hen +apping the c*ncept *9 nuance in hu+an language *nt* a pr*gra++ing language) O9ten, the #a+e !*rd e;pre##e# a nu+3er *9 di99erent +eaning#Rit# o-erloaded) Thi# i# u#e9ul, e#pecially !hen it c*+e# t* trivial di99erence#) :*u #ay I!a#h the #hirt,J I!a#h the car,J and I!a#h the d*g)J -t !*uld 3e #illy t* 3e 9*rced t* #ay, I#hirt,a#h the #hirt,J Icar,a#h the car,J and Id*g,a#h the d*gJ 4u#t #* the li#tener d*e#nt need t* +ake any di#tincti*n a3*ut the acti*n per9*r+ed) A*#t hu+an language# are redundant, #* even i9 y*u +i## a 9e! !*rd#, y*u can #till deter+ine the +eaning) ,e d*nt need uniDue identi9ier#R!e can deduce +eaning 9r*+ c*nte;t) A*#t pr*gra++ing language# GC in particularH reDuire y*u t* have a uniDue identi9ier 9*r each 9uncti*n) S* y*u c*uld n*t have *ne 9uncti*n called print( ) 9*r printing integer# and an*ther called print( ) 9*r printing 9l*at#Reach 9uncti*n reDuire# a uniDue na+e) -n C# and *ther language# in the C@@ 9a+ily, an*ther 9act*r 9*rce# the *verl*ading *9 +eth*d na+e#1 the c*n#truct*r) Becau#e the c*n#truct*r#

154

Thinking in C

www.ThinkingIn.!et

na+e i# predeter+ined 3y the na+e *9 the cla##, there can 3e *nly *ne c*n#truct*r na+e) But !hat i9 y*u !ant t* create an *34ect in +*re than *ne !ayF 5*r e;a+ple, #upp*#e y*u 3uild a cla## that can initiali7e it#el9 in a #tandard !ay *r 3y reading in9*r+ati*n 9r*+ a 9ile) :*u need t!* c*n#truct*r#, *ne that take# n* argu+ent# Gthe de$ault c*n#truct*r, al#* called the no9arg c*n#truct*rH, and *ne that take# a string a# an argu+ent, !hich i# the na+e *9 the 9ile 9r*+ !hich t* initiali7e the *34ect) B*th are c*n#truct*r#, #* they +u#t have the #a+e na+eRthe na+e *9 the cla##) Thu#, method o-erloading i# e##ential t* all*! the #a+e +eth*d na+e t* 3e u#ed !ith di99erent argu+ent type#) =nd alth*ugh +eth*d *verl*ading i# a +u#t 9*r c*n#truct*r#, it# a general c*nvenience and can 3e u#ed !ith any +eth*d) Here# an e;a+ple that #h*!# 3*th *verl*aded c*n#truct*r# and *verl*aded *rdinary +eth*d#1 //:c0E:O*erLoading.c# // :e!on#tration of $oth con#tructor // and ordinary !ethod o*er oading. u#ing Sy#te!3 c a## 'ree ; int height3 pu$ ic 'ree01 ; -rt0&- anting a #eed ing&13 height 9 03 < pu$ ic 'ree0int i1 ; -rt0&Creating ne. 'ree that i# & R i R & feet ta &13 height 9 i3 < interna *oid 5nfo01 ; -rt0&'ree i# & R height R & feet ta &13 < interna *oid 5nfo0#tring #1 ; -rt0# R &: 'ree i# & R height R & feet ta &13 <

Cha"ter 4* Initiali;ation = Cleanu"

155

#tatic *oid -rt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 < < pu$ ic c a## O*er oading ; pu$ ic #tatic *oid Gain01 ; for0int i 9 03 i W P3 iRR1 ; 'ree t 9 ne. 'ree0i13 t.5nfo013 t.5nfo0&o*er oaded !ethod&13 < // O*er oaded con#tructor: ne. 'ree013 < < ///:8 = +ree *34ect can 3e created either a# a #eedling, !ith n* argu+ent, *r a# a plant gr*!n in a nur#ery, !ith an e;i#ting height) T* #upp*rt thi#, there are t!* c*n#truct*r#, *ne that take# n* argu+ent# G!e call c*n#truct*r# that take n* argu+ent# de$ault constructors0H and *ne that take# the e;i#ting height) :*u +ight al#* !ant t* call the info( ) +eth*d in +*re than *ne !ay) 5*r e;a+ple, !ith a string argu+ent i9 y*u have an e;tra +e##age y*u !ant printed, and !ith*ut i9 y*u have n*thing +*re t* #ay) -t !*uld #ee+ #trange t* give t!* #eparate na+e# t* !hat i# *3vi*u#ly the #a+e c*ncept) 5*rtunately, +eth*d *verl*ading all*!# y*u t* u#e the #a+e na+e 9*r 3*th)

4istinguishing overloaded #ethods


-9 the +eth*d# have the #a+e na+e, h*! can C# kn*! !hich +eth*d y*u +eanF There# a #i+ple rule1 each *verl*aded +eth*d +u#t take a uniDue li#t *9 argu+ent type#)

0 S*+eti+e# the#e c*n#truct*r# are de#cri3ed !ith the clu+#y 3ut th*r*ugh na+e In*Earg

c*n#truct*r#)J The ter+ Ide9ault c*n#truct*rJ ha# 3een in u#e 9*r +any year# and #* - !ill u#e that)

156

Thinking in C

www.ThinkingIn.!et

-9 y*u think a3*ut thi# 9*r a #ec*nd, it +ake# #en#e1 h*! el#e c*uld a pr*gra++er tell the di99erence 3et!een t!* +eth*d# that have the #a+e na+e, *ther than 3y the type# *9 their argu+ent#F Even di99erence# in the *rdering *9 argu+ent# are #u99icient t* di#tingui#h t!* +eth*d#1 G=lth*ugh y*u d*nt n*r+ally !ant t* take thi# appr*ach, a# it pr*duce# di99icultEt*E+aintain c*de)H //:c0E:O*erLoadingOrder.c# // O*er oading $a#ed on the order of // the argu!ent#. pu$ ic c a## O*er oadingOrder ; #tatic *oid print0#tring #2 int i1 ; Sy#te!.Con#o e.VriteLine0 &#tring: & R # R &2 int: & R i13 < #tatic *oid print0int i2 #tring #1 ; Sy#te!.Con#o e.VriteLine0 &int: & R i R &2 #tring: & R #13 < pu$ ic #tatic *oid Gain01 ; print0&#tring fir#t&2 ""13 print0>>2 &5nt fir#t&13 < < ///:8 The t!* print( ) +eth*d# have identical argu+ent#, 3ut the *rder i# di99erent, and that# !hat +ake# the+ di#tinct)

Overloading with $ri#itives


= pri+itive can 3e aut*+atically pr*+*ted 9r*+ a #+aller type t* a larger *ne and thi# can 3e #lightly c*n9u#ing in c*+3inati*n !ith *verl*ading) The 9*ll*!ing e;a+ple de+*n#trate# !hat happen# !hen a pri+itive i# handed t* an *verl*aded +eth*d1 //:c0E:-ri!iti*eO*er oading.c# // -ro!otion of pri!iti*e# and o*er oading.

Cha"ter 4* Initiali;ation = Cleanu"

15#

pu$ ic c a## -ri!iti*eO*er oading ; // $oo ean can't $e auto!atica y con*erted #tatic *oid -rt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 < *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid *oid H"0char x1 ; -rt0&H"0char1&13 < H"0$yte x1 ; -rt0&H"0$yte1&13 < H"0#hort x1 ; -rt0&H"0#hort1&13 < H"0int x1 ; -rt0&H"0int1&13 < H"0 ong x1 ; -rt0&H"0 ong1&13 < H"0f oat x1 ; -rt0&H"0f oat1&13 < H"0dou$ e x1 ; -rt0&H"0dou$ e1&13 < H20$yte x1 ; -rt0&H20$yte1&13 < H20#hort x1 ; -rt0&H20#hort1&13 < H20int x1 ; -rt0&H20int1&13 < H20 ong x1 ; -rt0&H20 ong1&13 < H20f oat x1 ; -rt0&H20f oat1&13 < H20dou$ e x1 ; -rt0&H20dou$ e1&13 < HT0#hort x1 ; -rt0&HT0#hort1&13 < HT0int x1 ; -rt0&HT0int1&13 < HT0 ong x1 ; -rt0&HT0 ong1&13 < HT0f oat x1 ; -rt0&HT0f oat1&13 < HT0dou$ e x1 ; -rt0&HT0dou$ e1&13 < HE0int x1 ; -rt0&HE0int1&13 < HE0 ong x1 ; -rt0&HE0 ong1&13 < HE0f oat x1 ; -rt0&HE0f oat1&13 < HE0dou$ e x1 ; -rt0&HE0dou$ e1&13 <

*oid HP0 ong x1 ; -rt0&HP0 ong1&13 < *oid HP0f oat x1 ; -rt0&HP0f oat1&13 < *oid HP0dou$ e x1 ; -rt0&HP0dou$ e1&13 < *oid H?0f oat x1 ; -rt0&H?0f oat1&13 < *oid H?0dou$ e x1 ; -rt0&H?0dou$ e1&13 < *oid HF0dou$ e x1 ; -rt0&HF0dou$ e1&13 <

15&

Thinking in C

www.ThinkingIn.!et

*oid 'e#tCon#tNa 01 ; -rt0&'e#ting .ith P&13 H"0P13H20P13HT0P13HE0P13HP0P13H?0P13HF0P13 < *oid 'e#tChar01 ; char x 9 'x'3 -rt0&char argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < *oid 'e#tByte01 ; $yte x 9 03 -rt0&$yte argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < *oid 'e#tShort01 ; #hort x 9 03 -rt0&#hort argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < *oid 'e#t5nt01 ; int x 9 03 -rt0&int argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < *oid 'e#tLong01 ; ong x 9 03 -rt0& ong argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < *oid 'e#tH oat01 ; f oat x 9 03 -rt0&H oat argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < *oid 'e#t:ou$ e01 ; dou$ e x 9 03 -rt0&dou$ e argu!ent:&13 H"0x13H20x13HT0x13HE0x13HP0x13H?0x13HF0x13 < pu$ ic #tatic *oid Gain01 ; -ri!iti*eO*er oading p 9

Cha"ter 4* Initiali;ation = Cleanu"

15'

ne. -ri!iti*eO*er oading013 p.'e#tCon#tNa 013 p.'e#tChar013 p.'e#tByte013 p.'e#tShort013 p.'e#t5nt013 p.'e#tLong013 p.'e#tH oat013 p.'e#t:ou$ e013 < < ///:8 -9 y*u vie! the *utput *9 thi# pr*gra+, y*ull #ee that the c*n#tant value ' i# treated a# an int, #* i9 an *verl*aded +eth*d i# availa3le that take# an int it i# u#ed) -n all *ther ca#e#, i9 y*u have a data type that i# #+aller than the argu+ent in the +eth*d, that data type i# pr*+*ted) char pr*duce# a #lightly di99erent e99ect, #ince i9 it d*e#nt 9ind an e;act char +atch, it i# pr*+*ted t* int) ,hat happen# i9 y*ur argu+ent i# 2igger than the argu+ent e;pected 3y the *verl*aded +eth*dF = +*di9icati*n *9 the a3*ve pr*gra+ give# the an#!er1 //:c0E::e!otion.c# // :e!otion of pri!iti*e# and o*er oading. pu$ ic c a## :e!otion ; #tatic *oid -rt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 < *oid *oid *oid *oid *oid *oid *oid H"0char x1 ; -rt0&H"0char1&13 < H"0$yte x1 ; -rt0&H"0$yte1&13 < H"0#hort x1 ; -rt0&H"0#hort1&13 < H"0int x1 ; -rt0&H"0int1&13 < H"0 ong x1 ; -rt0&H"0 ong1&13 < H"0f oat x1 ; -rt0&H"0f oat1&13 < H"0dou$ e x1 ; -rt0&H"0dou$ e1&13 <

*oid H20char x1 ; -rt0&H20char1&13 < *oid H20$yte x1 ; -rt0&H20$yte1&13 < *oid H20#hort x1 ; -rt0&H20#hort1&13 <

16(

Thinking in C

www.ThinkingIn.!et

*oid H20int x1 ; -rt0&H20int1&13 < *oid H20 ong x1 ; -rt0&H20 ong1&13 < *oid H20f oat x1 ; -rt0&H20f oat1&13 < *oid *oid *oid *oid *oid *oid *oid *oid *oid HT0char x1 ; -rt0&HT0char1&13 < HT0$yte x1 ; -rt0&HT0$yte1&13 < HT0#hort x1 ; -rt0&HT0#hort1&13 < HT0int x1 ; -rt0&HT0int1&13 < HT0 ong x1 ; -rt0&HT0 ong1&13 < HE0char x1 ; -rt0&HE0char1&13 < HE0$yte x1 ; -rt0&HE0$yte1&13 < HE0#hort x1 ; -rt0&HE0#hort1&13 < HE0int x1 ; -rt0&HE0int1&13 <

*oid HP0char x1 ; -rt0&HP0char1&13 < *oid HP0$yte x1 ; -rt0&HP0$yte1&13 < *oid HP0#hort x1 ; -rt0&HP0#hort1&13 < *oid H?0char x1 ; -rt0&H?0char1&13 < *oid H?0$yte x1 ; -rt0&H?0$yte1&13 < *oid HF0char x1 ; -rt0&HF0char1&13 < *oid 'e#t:ou$ e01 ; dou$ e x 9 03 -rt0&dou$ e argu!ent:&13 H"0x13H200f oat1x13HT00 ong1x13HE00int1x13 HP00#hort1x13H?00$yte1x13HF00char1x13 < pu$ ic #tatic *oid Gain01 ; :e!otion p 9 ne. :e!otion013 p.'e#t:ou$ e013 < < ///:8 Here, the +eth*d# take narr*!er pri+itive value#) -9 y*ur argu+ent i# !ider then y*u +u#t cast t* the nece##ary type u#ing the type na+e in parenthe#e#) -9 y*u d*nt d* thi#, the c*+piler !ill i##ue an err*r +e##age)

Cha"ter 4* Initiali;ation = Cleanu"

161

:*u #h*uld 3e a!are that thi# i# a narrowing con-ersion6 !hich +ean# y*u +ight l*#e in9*r+ati*n during the ca#t) Thi# i# !hy the c*+piler 9*rce# y*u t* d* itRt* 9lag the narr*!ing c*nver#i*n)

Overloading on return values


-t i# c*++*n t* !*nder I,hy *nly cla## na+e# and +eth*d argu+ent li#t#F ,hy n*t di#tingui#h 3et!een +eth*d# 3a#ed *n their return value#FJ 5*r e;a+ple, the#e t!* +eth*d#, !hich have the #a+e na+e and argu+ent#, are ea#ily di#tingui#hed 9r*+ each *ther1 *oid f01 ;< int f01 ;< Thi# !*rk# 9ine !hen the c*+piler can uneDuiv*cally deter+ine the +eaning 9r*+ the c*nte;t, a# in int x I f( )) H*!ever, y*u can call a +eth*d and ign*re the return valueQ thi# i# *9ten re9erred t* a# calling a method $or its side e$$ect #ince y*u d*nt care a3*ut the return value 3ut in#tead !ant the *ther e99ect# *9 the +eth*d call) S* i9 y*u call the +eth*d thi# !ay1 f013 h*! can C# deter+ine !hich f( ) #h*uld 3e calledF =nd h*! c*uld #*+e*ne reading the c*de #ee itF Becau#e *9 thi# #*rt *9 pr*3le+, y*u cann*t u#e return value type# t* di#tingui#h *verl*aded +eth*d#)

4e0ault constructors
=# +enti*ned previ*u#ly, a de9ault c*n#truct*r Ga)k)a) a In*EargJ c*n#truct*rH i# *ne !ith*ut argu+ent#, u#ed t* create a Ivanilla *34ect)J -9 y*u create a cla## that ha# n* c*n#truct*r#, the c*+piler !ill aut*+atically create a de9ault c*n#truct*r 9*r y*u) 5*r e;a+ple1 //:c0E::efau tCon#tructor.c# c a## Bird ; int i3 < pu$ ic c a## :efau tCon#tructor ; pu$ ic #tatic *oid Gain01 ; Bird nc 9 ne. Bird013 // defau t!

16)

Thinking in C

www.ThinkingIn.!et

< <///:8 The line ne. Bird013 create# a ne! *34ect and call# the de9ault c*n#truct*r, even th*ugh *ne !a# n*t e;plicitly de9ined) ,ith*ut it !e !*uld have n* +eth*d t* call t* 3uild *ur *34ect) H*!ever, i9 y*u de9ine any c*n#truct*r# G!ith *r !ith*ut argu+ent#H, the c*+piler !ill not #ynthe#i7e *ne 9*r y*u1 c a## Bu#h ; Bu#h0int i1 ;< Bu#h0dou$ e d1 ;< < *! i9 y*u #ay1 ne. Bu#h013 the c*+piler !ill c*+plain that it cann*t 9ind a c*n#truct*r that +atche#) -t# a# i9 !hen y*u d*nt put in any c*n#truct*r#, the c*+piler #ay# I:*u are 3*und t* need some c*n#truct*r, #* let +e +ake *ne 9*r y*u)J But i9 y*u !rite a c*n#truct*r, the c*+piler #ay# I:*uve !ritten a c*n#truct*r #* y*u kn*! !hat y*ure d*ingQ i9 y*u didnt put in a de9ault it# 3ecau#e y*u +eant t* leave it *ut)J

-he this *e5word


-9 y*u have t!* *34ect# *9 the #a+e type called a and b, y*u +ight !*nder h*! it i# that y*u can call a +eth*d f( ) 9*r 3*th th*#e *34ect#1 c a## Banana ; *oid f0int i1 ; /= ... =/ < < Banana a 9 ne. Banana012 $ 9 ne. Banana013 a.f0"13 $.f0213 -9 there# *nly *ne +eth*d called f( ), h*! can that +eth*d kn*! !hether it# 3eing called 9*r the *34ect a *r bF T* all*! y*u t* !rite the c*de in a c*nvenient *34ectE*riented #ynta; in !hich y*u I#end a +e##age t* an *34ect,J the c*+piler d*e# #*+e underc*ver !*rk 9*r y*u) There# a #ecret 9ir#t argu+ent pa##ed t* the

Cha"ter 4* Initiali;ation = Cleanu"

163

+eth*d f( ), and that argu+ent i# the re9erence t* the *34ect that# 3eing +anipulated) S* the t!* +eth*d call# a3*ve 3ec*+e #*+ething like1 Banana.f0a2"13 Banana.f0$2213 Thi# i# internal and y*u cant !rite the#e e;pre##i*n# and get the c*+piler t* interchange the+ !ith a)9GHE#tyle call#, 3ut it give# y*u an idea *9 !hat# happening) Supp*#e y*ure in#ide a +eth*d and y*ud like t* get the re9erence t* the current *34ect) Since that re9erence i# pa##ed secretl4 3y the c*+piler, there# n* identi9ier 9*r it) H*!ever, 9*r thi# purp*#e there# a key!*rd1 this) The this key!*rd pr*duce# a re9erence t* the *34ect the +eth*d ha# 3een called 9*r) :*u can treat thi# re9erence 4u#t like any *ther *34ect re9erence) Neep in +ind that i9 y*ure calling a +eth*d *9 y*ur cla## 9r*+ !ithin an*ther +eth*d *9 y*ur cla##, y*u d*nt need t* u#e thisQ y*u #i+ply call the +eth*d) The current this re9erence i# aut*+atically u#ed 9*r the *ther +eth*d) Thu# y*u can #ay1 c a## )pricot ; int id3 *oid pic%01 ; /= ... =/ < *oid pit01 ; pic%013 id3 /= ... =/ < < -n#ide pit( ), y*u could #ay this6pic(( ) *r this6id 3ut there# n* need t*) The c*+piler d*e# it 9*r y*u aut*+atically) The this key!*rd i# u#ed *nly 9*r th*#e #pecial ca#e# in !hich y*u need t* e;plicitly u#e the re9erence t* the current *34ect) 5*r e;a+ple, it# *9ten u#ed in return #tate+ent# !hen y*u !ant t* return the re9erence t* the current *34ect1 //:c0E:Leaf.c# // Si!p e u#e of the &thi#& %ey.ord. pu$ ic c a## Leaf ; int i 9 03 Leaf 5ncre!ent01 ; iRR3 return thi#3

164

Thinking in C

www.ThinkingIn.!et

< *oid -rint01 ; Sy#te!.Con#o e.VriteLine0&i 9 & R i13 < pu$ ic #tatic *oid Gain01 ; Leaf x 9 ne. Leaf013 x.5ncre!ent01.5ncre!ent01.5ncre!ent01.-rint013 < < ///:8 Becau#e increment( ) return# the re9erence t* the current *34ect via the this key!*rd, +ultiple *perati*n# can ea#ily 3e per9*r+ed *n the #a+e *34ect) =n*ther place !here it# *9ten u#ed i# t* all*! +eth*d para+eter# t* have the #a+e na+e a# in#tance varia3le#) Previ*u#ly, !e talked a3*ut the value *9 *verl*ading +eth*d# #* that the pr*gra++er *nly had t* re+e+3er the *ne, +*#t l*gical na+e) Si+ilarly, the na+e# *9 +eth*d para+eter# and the na+e# *9 in#tance varia3le# +ay al#* have a #ingle l*gical na+e) C# all*!# y*u t* u#e the this re9erence t* di#a+3iguate +eth*d varia3le# Gal#* called I#tack varia3le#JH 9r*+ in#tance varia3le#) 5*r clarity, y*u #h*uld u#e thi# capa3ility *nly !hen the para+eter i# g*ing t* either 3e a##igned t* the in#tance varia3le G#uch a# in a c*n#truct*rH *r !hen the para+eter i# t* 3e c*+pared again#t the in#tance varia3le) Aeth*d varia3le# that have n* c*rrelati*n !ith #a+eE na+ed in#tance varia3le# are a c*++*n #*urce *9 la7y de9ect#1 //:c0E:Ca!e.c# c a## Ca!e; #tring gi*enCa!e3 #tring #urna!e3 pu$ ic Ca!e0#tring gi*enCa!e2 #tring #urna!e1; thi#.gi*enCa!e 9 gi*enCa!e3 thi#.#urna!e 9 #urna!e3 < pu$ ic $oo perhap#Re ated0#tring #urna!e1; return thi#.#urna!e 99 #urna!e3 <

Cha"ter 4* Initiali;ation = Cleanu"

165

pu$ ic *oid print_i*enCa!e01; /= Lega 2 $ut un.i#e =/ #tring gi*enCa!e 9 &!ethod *aria$ e&3 Sy#te!.Con#o e.VriteLine0&gi*enCa!e i#: & R gi*enCa!e13 Sy#te!.Con#o e.VriteLine0&thi#.gi*enCa!e i#: & R thi#.gi*enCa!e13 < pu$ ic #tatic *oid Gain01; Ca!e *an_ogh 9 ne. Ca!e0&Nincent&2 &*an _ogh&13 *an_ogh.print_i*enCa!e013 $oo $ 9 *an_ogh.perhap#Re ated0&*an _ogh&13 if0$1; Sy#te!.Con#o e.VriteLine0&Ue'# a *an _ogh.&13 < < <///:8 -n the c*n#truct*r, the para+eter# given,ame and surname are a##igned t* the #i+ilarlyEna+ed in#tance varia3le# and thi# i# Duite appr*priate P calling the para+eter# in iven,ame and in#urname G*r !*r#e, u#ing para+eter na+e# #uch a# first,ame *r last,ame that d* n*t c*rre#p*nd t* the in#tance varia3le#H !*uld reDuire e;plaining in the d*cu+entati*n) The perhaps*elated() +eth*d #h*!# the *ther appr*priate u#e P the surname pa##ed in i# t* 3e c*+pared t* the in#tance# surname) Un9*rtunately, the u#age in print iven,ame() i# al#* legal) Here, a varia3le called given,ame i# created *n the #tackQ it ha# n*thing t* d* !ith the in#tance varia3le al#* called given,ame) -t +ay 3e unlikely that #*+e*ne !*uld accidentally create a +eth*d varia3le called given,ame, 3ut y*ud 3e a+a7ed at h*! +any name, id, and flag# -ve #een in +y dayK -t# an*ther rea#*n !hy +eaning9ul varia3le na+e# are i+p*rtant) Side3ar1 Stack, -n#tance, and Para+eter Caria3le# S*+eti+e# y*ull #ee c*de !here hal9 the varia3le# 3egin !ith under#c*re# and hal9 the varia3le# d*nt1

166

Thinking in C

www.ThinkingIn.!et

foo 9 X$ar3 The intent i# t* u#e the pre9i; t* di#tingui#h 3et!een +eth*d varia3le# that are created *n the #tack and g* *ut *9 #c*pe a# #**n a# the +eth*d e;it# and varia3le# that have l*nger li9e#pan#) - hate thi# idi*+) 5*r *ne thing, it# *rigin had t* d* !ith vi#i3ility, n*t #t*rage, and C# ha# e;plicit and in9initely 3etter vi#i3ility #peci9ier#) 5*r an*ther, it# u#ed inc*n#i#tently P al+*#t a# +any pe*ple u#e the under#c*re# 9*r #tack varia3le# a# u#e the+ 9*r in#tance varia3le#) S*+eti+e# y*u #ee c*de that prepend# an T+ t* +e+3er varia3le# na+e#1 foo 9 !Bar3 - hate thi# a little le## than - hate the under#c*re#) Thi# type *9 na+ing c*nventi*n i# an *99#h**t *9 a C na+ing idi*+ called IHungarian n*tati*n,J that prepended type in9*r+ati*n t* a varia3le na+e G#* #tring# !*uld 3e str:ooH) Thi# i# a great idea i9 y*ure pr*gra++ing in C and every*ne !h* ha# pr*gra++ed ,ind*!# ha# #een their #hare *9 varia3le# #tarting !ith Th, 3ut the ti+e 9*r thi# na+ing c*nventi*n ha# pa##ed) -9 y*u !ant t* di#tingui#h 3et!een +eth*d and in#tance varia3le#, u#e this) -t# *34ectE*riented, de#criptive, and e;plicit) <<end #ide3ar

Calling constructors 0ro# constructors


,hen y*u !rite #everal c*n#truct*r# 9*r a cla##, there are ti+e# !hen y*ud like t* call *ne c*n#truct*r 9r*+ an*ther t* av*id duplicating c*de) -n C#, y*u can #peci9y that an*ther c*n#truct*r e;ecute 3e9*re the current c*n#truct*r) :*u d* thi# u#ing the T1 *perat*r and the this key!*rd) *r+ally, !hen y*u #ay this, it i# in the #en#e *9 Ithi# *34ectJ *r Ithe current *34ect,J and 3y it#el9 it pr*duce# the re9erence t* the current *34ect) -n a c*n#truct*r na+e, a c*l*n 9*ll*!ed 3y the this key!*rd take# *n a di99erent +eaning1 it +ake# an e;plicit call t* the c*n#truct*r that +atche# the #peci9ied argu+ent li#t) Thu# y*u have a #traight9*r!ard !ay t* call *ther c*n#truct*r#1

Cha"ter 4* Initiali;ation = Cleanu"

16#

//:c0E:H o.er.c# // Ca ing con#tructor# .ith &: thi#.& pu$ ic c a## H o.er ; int peta Count 9 03 #tring # 9 &nu &3 H o.er0int peta #1 ; peta Count 9 peta #3 Sy#te!.Con#o e.VriteLine0 &Con#tructor ./ int arg on y2 peta Count9 & R peta Count13 < H o.er0#tring ##1 ; Sy#te!.Con#o e.VriteLine0 &Con#tructor ./ #tring arg on y2 #9& R ##13 # 9 ##3 < H o.er0#tring #2 int peta #1 : thi#0peta #1; //! thi#0#13 // Can't ca t.o! thi#.# 9 #3 // )nother u#e of &thi#& Sy#te!.Con#o e.VriteLine0&#tring @ int arg#&13 < H o.er01 : thi#0&hi&2 EF1 ; Sy#te!.Con#o e.VriteLine0 &defau t con#tructor 0no arg#1&13 < *oid -rint01 ; Sy#te!.Con#o e.VriteLine0 &peta Count 9 & R peta Count R & # 9 &R #13 < pu$ ic #tatic *oid Gain01 ; H o.er x 9 ne. H o.er013 x.-rint013 < <//:8 The c*n#truct*r :lower(#tring s, int petals) #h*!# that, !hile y*u can call *ne c*n#truct*r u#ing this, y*u cann*t call t!*) Ot*d*1 c*n9ir+

-he #eaning o0 static


,ith the this key!*rd in +ind, y*u can +*re 9ully under#tand !hat it +ean# t* +ake a +eth*d static) -t +ean# that there i# n* this 9*r that

16&

Thinking in C

www.ThinkingIn.!et

particular +eth*d) :*u cann*t call n*nEstatic +eth*d# 9r*+ in#ide static +eth*d# Galth*ugh the rever#e i# p*##i3leH, and y*u can call a static +eth*d 9*r the cla## it#el9, !ith*ut any *34ect) -n 9act, that# pri+arily !hat a static +eth*d i# 9*r) -t# a# i9 y*ure creating the eDuivalent *9 a gl*3al 9uncti*n G9r*+ CH) E;cept gl*3al 9uncti*n# are n*t per+itted in C#, and putting the static +eth*d in#ide a cla## all*!# it acce## t* *ther static +eth*d# and static 9ield#) S*+e pe*ple argue that static +eth*d# are n*t *34ectE*riented #ince they d* have the #e+antic# *9 a gl*3al 9uncti*nQ !ith a static +eth*d y*u d*nt #end a +e##age t* an *34ect, #ince there# n* this) Thi# i# pr*3a3ly a 9air argu+ent, and i9 y*u 9ind y*ur#el9 u#ing a lot *9 #tatic +eth*d# y*u #h*uld pr*3a3ly rethink y*ur #trategy) H*!ever, static# are prag+atic and there are ti+e# !hen y*u genuinely need the+, #* !hether *r n*t they are Ipr*per OOPJ #h*uld 3e le9t t* the the*retician#) -ndeed, even S+alltalk ha# the eDuivalent in it# Icla## +eth*d#)J Ot*d*1 C*n9ir+ that p*ly+*rphi#+ di#cu##i*n ha# n*nEp*ly+*rphi#+ *9 #tatic +eth*d#

Cleanu$, 0inali:ation and gar+age collection


Pr*gra++er# kn*! a3*ut the i+p*rtance *9 initiali7ati*n, 3ut *9ten 9*rget the i+p*rtance *9 cleanup) =9ter all, !h* need# t* clean up an intF But !ith li3rarie#, #i+ply Iletting g*J *9 an *34ect *nce y*ure d*ne !ith it i# n*t al!ay# #a9e) O9 c*ur#e, C# ha# the gar3age c*llect*r t* reclai+ the +e+*ry *9 *34ect# that are n* l*nger u#ed) *! c*n#ider a very unu#ual ca#e) Supp*#e y*ur *34ect all*cate# I#pecialJ +e+*ry !ith*ut u#ing new) The gar3age c*llect*r kn*!# *nly h*! t* relea#e +e+*ry all*cated with new, #* it !*nt kn*! h*! t* relea#e the *34ect# I#pecialJ +e+*ry) T* handle thi# ca#e, C# pr*vide# a +eth*d called a destructor that y*u can de9ine 9*r y*ur cla##) The de#truct*r, like the c*n#truct*r, #hare# the cla## na+e, 3ut i# pre9aced !ith a tilde1 c a## GyC a##; pu$ ic GyC a##01; //Con#tructor < pu$ ic 8GyC a##01; //:e#tructor < <

Cha"ter 4* Initiali;ation = Cleanu"

16'

C@@ pr*gra++er# !ill 9ind thi# #ynta; 9a+iliar, 3ut thi# i# actually a danger*u# +i+ic P the C# de#truct*r ha# va#tly di99erent #e+antic#, a# y*ull #ee) Here# h*! it# su""osed t* !*rk) ,hen the gar3age c*llect*r i# ready t* relea#e the #t*rage u#ed 9*r y*ur *34ect, it !ill 9ir#t call the *34ect# de#truct*r, and *nly *n the ne;t gar3ageEc*llecti*n pa## !ill it reclai+ the *34ect# +e+*ry) S* i9 y*u ch**#e t* u#e the de#truct*r, it give# y*u the a3ility t* per9*r+ #*+e i+p*rtant cleanup at the time o$ gar2age collection) Thi# i# a p*tential pr*gra++ing pit9all 3ecau#e #*+e pr*gra++er#, e#pecially C@@ pr*gra++er#, 3ecau#e in C@@ o23ects alwa4s get destro4ed Gin a 3ugE9ree pr*gra+H, !herea# in C# *34ect# d* n*t al!ay# get gar3ageEc*llected) Or, put an*ther !ay1

Clean up a9ter y*ur#el9)


-9 y*u re+e+3er thi#, y*u !ill #tay *ut *9 tr*u3le) ,hat it +ean# i# that i9 there i# #*+e activity that +u#t 3e per9*r+ed 3e9*re y*u n* l*nger need an *34ect, y*u +u#t per9*r+ that activity y*ur#el9) 5*r e;a+ple, #upp*#e that y*u *pen a 9ile and !rite #tu99 t* it) -9 y*u d*nt e;plicitly cl*#e that 9ile, it +ight never get pr*perly 9lu#hed t* the di#k) -9 y*u put #*+e kind *9 9lu#hEandEcl*#e 9uncti*nality in#ide y*ur de#truct*r, then i9 the *34ect i# gar3ageEc*llected, the 9ile !ill 3e tidied up pr*perly, 3ut i9 the *34ect i# n*t c*llected, y*u can have an *pen 9ile that +ay *r +ay n*t 3e u#a3le) S* a #ec*nd p*int t* re+e+3er i#1

:*ur *34ect# +ight n*t get gar3ageEc*llected)


:*u +ight 9ind that the #t*rage 9*r an *34ect never get# relea#ed 3ecau#e y*ur pr*gra+ never near# the p*int *9 running *ut *9 #t*rage) -9 y*ur pr*gra+ c*+plete# and the gar3age c*llect*r never get# ar*und t* relea#ing the #t*rage 9*r any *9 y*ur *34ect#, that #t*rage !ill 3e returned t* the *perating #y#te+ en masse a# the pr*gra+ e;it#) Thi# i# a g**d thing, 3ecau#e gar3age c*llecti*n ha# #*+e *verhead, and i9 y*u never d* it y*u never incur that e;pen#e) -n practice, it appear# that the gar3age c*llect*r d*e#, in 9act, get called !hen a C# pr*ce## end#, 3ut thi# i# e;plicitly n*t guaranteed 3y the CLR)

1#(

Thinking in C

www.ThinkingIn.!et

What are destructors 0or<


:*u +ight 3elieve at thi# p*int that y*u #h*uld n*t u#e a de#truct*r a# a generalEpurp*#e cleanup +eth*d) ,hat g**d i# itF = third p*int t* re+e+3er i#1

>ar3age c*llecti*n i# *nly a3*ut +e+*ry)


That i#, the #*le rea#*n 9*r the e;i#tence *9 the gar3age c*llect*r i# t* rec*ver +e+*ry that y*ur pr*gra+ i# n* l*nger u#ing) S* any activity that i# a##*ciated !ith gar3age c*llecti*n, +*#t n*ta3ly y*ur de#truct*r +eth*d, +u#t al#* 3e *nly a3*ut +e+*ry and it# deall*cati*n) Calua3le re#*urce#, #uch a# 9ile handle#, data3a#e c*nnecti*n#, and #*cket# *ught t* 3e +anaged e;plicitly in y*ur c*de, !ith*ut relying *n de#truct*r#) Ot*d*1 add #ecti*n Glater in chapterH a3*ut 9act*ry +eth*d# < #inglet*n# < p**l# ?*e# thi# +ean that i9 y*ur *34ect c*ntain# *ther *34ect#, y*ur de#truct*r #h*uld e;plicitly relea#e th*#e *34ect#F ,ell, n*Rthe gar3age c*llect*r take# care *9 the relea#e *9 all *34ect +e+*ry regardle## *9 h*! the *34ect i# created) -t turn# *ut that the need 9*r de#truct*r# i# li+ited t* #pecial ca#e#, in !hich y*ur *34ect can all*cate #*+e #t*rage in #*+e !ay *ther than creating an *34ect) But, y*u +ight *3#erve, everything in C# i# an *34ect #* h*! can thi# 3eF -t !*uld #ee+ that C# ha# a de#truct*r 3ecau#e *9 it# #upp*rt 9*r un+anaged c*de, in !hich y*u can all*cate +e+*ry in a CElike +anner) Ae+*ry all*cated in un+anaged c*de i# n*t re#t*red 3y the gar3age c*llecti*n +echani#+) The argu+ent i# pr*3a3ly that, 9*r thi# #pecial ca#e, there #h*uld 3e #y++etry in the language de#ign and the de#truct*r i# the c*+ple+ent t* the c*n#truct*r) Thi# i# a !eak argu+ent) R=A +ay n* l*nger 3e a# #carce a c*++*dity a# it !a# in the pa#t G!hen .&N !a# en*ugh 9*r any*neH, 3ut #l*ppine## !ith un+anaged +e+*ry i# a huge practical pr*3le+, e#pecially in the#e day# *9 3u99er *verrun #ecurity attack# and the de#ire 9*r +achine# t* g* !eek# *r +*nth# !ith*ut re3**ting) =9ter reading thi#, y*u pr*3a3ly get the idea that y*u !*nt 3e !riting de#truct*r# t** *9ten) >**d)

Cha"ter 4* Initiali;ation = Cleanu"

1#1

Instead o0 a destructor. use Close12 or 4is$ose12


The +a4*rity *9 *34ect# d*nt u#e re#*urce# that need t* 3e cleaned up) S* +*#t *9 the ti+e, y*u d*nt !*rry a3*ut !hat happen# !hen they Ig* a!ay)J But i9 y*u d* u#e a re#*urce, y*u #h*uld !rite a +eth*d called Close() i9 the re#*urce c*ntinue# t* e;i#t a9ter y*ur u#e *9 it end# *r $ispose() *ther!i#e) A*#t i+p*rtantly, y*u #h*uld e%"licitl4 call the Close() *r $ispose() +eth*d a# #**n a# y*u n* l*nger reDuire the re#*urce) -9 y*u rely *n the gar3age c*llect*r t* +anage re#*urce#, y*u can c*unt *n tr*u3le1 //:c0E:Na ua$ eRe#ource.c# u#ing Sy#te!3 u#ing Sy#te!.'hreading3 c a## Na ua$ eRe#ource; pu$ ic #tatic *oid Gain01; u#eNa ua$ eRe#ource#013 Sy#te!.Con#o e.VriteLine0&Na u#ed and di#carded&13 'hread.S eep0"000013 Sy#te!.Con#o e.VriteLine0&"0 ///ou .ou d Xthin%X thi# .ou Na ua$ eRe#ource *r 9 ne. Na <

ua$ e re#ource# #econd# ater...&13 d $e fine ua$ eRe#ource013

#tatic *oid u#eNa ua$ eRe#ource#01; for0int i 9 03 i W G),XR+SOORC+S3 iRR1; Na ua$ eRe#ource *r 9 ne. Na ua$ eRe#ource013 < < #tatic int idCounter3 #tatic int G),XR+SOORC+S 9 "03 #tatic int 5CN)L5:X5: 9 6"3 int id3

1#)

Thinking in C

www.ThinkingIn.!et

Na ua$ eRe#ource01; if0idCounter 99 G),XR+SOORC+S1; Sy#te!.Con#o e.VriteLine0&Co re#ource# a*ai a$ e&13 id 9 5CN)L5:X5:3 <e #e; id 9 idCounterRR3 Sy#te!.Con#o e.VriteLine0&Re#ourceJ;0<K Con#tructed&2 id13 < < 8Na ua$ eRe#ource01; if0id 99 5CN)L5:X5:1; Sy#te!.Con#o e.VriteLine0&'hing# are a.ry!&13 <e #e; idCounter663 Sy#te!.Con#o e.VriteLine0&Re#ourceJ;0<K :e#tructed&2 id 13 < < <///:8 -n thi# e;a+ple, the 9ir#t thing that happen# up*n entering AainGH i# the u#eCalua3leRe#*urce#GH +eth*d i# called) Thi# i# #traight9*r!ard P the A=B`RESOURCES nu+3er *9 Calua3leRe#*urce *34ect# are created and then i++ediately all*!ed t* Ig* a!ayJ) -n the Calua3leRe#*urceGH c*n#truct*r, the #tatic idC*unter varia3le i# checked t* #ee i9 it eDual# the A=B`RESOURCES value) -9 #*, a I * re#*urce# availa3leJ +e##age i# !ritten and the id *9 the Calua3le Re#*urce i# #et t* an invalid value Gin thi# ca#e, the idC*unter i# the #*urce *9 the I#carceJ re#*urce !hich i# Ic*n#u+edJ 3y the id varia3leH) The Calua3leRe#*urce de#truct*r either *utput# a !arning +e##age *r decre+ent# the idC*unter Gthu#, +aking an*ther Ire#*urceJ availa3leH) ,hen u#eCalua3leRe#*urce#GH return#, the #y#te+ pau#e# 9*r 0$ #ec*nd# G!ell di#cu## Thread)SleepGH in great detail in Chapter #AULT-THRE=?- >#H, and 9inally a ne! Calua3leRe#*urce i# created) -t #ee+# like that #h*uld 3e 9ine, #ince th*#e created in

Cha"ter 4* Initiali;ation = Cleanu"

1#3

u#eCalua3leRe#*urce#GH are l*ng g*ne) But the *utput tell# a di99erent #t*ry1 Re#ourceJ0K Con#tructed Re#ourceJ"K Con#tructed Re#ourceJ2K Con#tructed Re#ourceJTK Con#tructed Re#ourceJEK Con#tructed Re#ourceJPK Con#tructed Re#ourceJ?K Con#tructed Re#ourceJFK Con#tructed Re#ourceJIK Con#tructed Re#ourceJ>K Con#tructed Na ua$ e re#ource# u#ed and di#carded "0 #econd# ater... Co re#ource# a*ai a$ e 'hing# are a.ry! Re#ourceJ>K :e#tructed Re#ourceJIK :e#tructed Re#ourceJFK :e#tructed Re#ourceJ?K :e#tructed Re#ourceJPK :e#tructed Re#ourceJEK :e#tructed Re#ourceJTK :e#tructed Re#ourceJ2K :e#tructed Re#ourceJ"K :e#tructed Re#ourceJ0K :e#tructed Even a9ter ten #ec*nd# Gan eternity in c*+puting ti+eH, n* id# are availa3le and the 9inal atte+pt t* create a Calua3leRe#*urce 9ail#) -ntere#tingly, the AainGH e;it# i++ediately a9ter the I * re#*urce# availa3leKJ +e##age i# !ritten) -n thi# ca#e, the CLR did d* a gar3age c*llecti*n a# the pr*gra+ e;ited and the aCalua3leRe#*urceGH de#truct*r# g*t called) -n thi# ca#e, they happen t* 3e deleted in the rever#e *rder *9 their creati*n, 3ut the *rder *9 de#tructi*n *9 re#*urce# i# yet an*ther Ia3#*lutely n*t guaranteedJ characteri#tic *9 gar3age c*llecti*n) ,*r#e, thi# i# the *utput i9 *ne pre##e# CtlEC during the pau#e1 Re#ourceJ0K Con#tructed Re#ourceJ"K Con#tructed Re#ourceJ2K Con#tructed

1#4

Thinking in C

www.ThinkingIn.!et

Re#ourceJTK Con#tructed Re#ourceJEK Con#tructed Re#ourceJPK Con#tructed Re#ourceJ?K Con#tructed Re#ourceJFK Con#tructed Re#ourceJIK Con#tructed Re#ourceJ>K Con#tructed Na ua$ e re#ource# u#ed and di#carded ]C ::^tic^chapEZ That# it) * cleanup) -9 the valua3le re#*urce# !ere, #ay, net!*rk #*cket# *r data3a#e c*nnecti*n# *r 9ile# *r, !ell, anything that actually had any value, theyd 3e l*#t until y*u re3**t G*r #*+e *ther pr*ce## +anage# t* re#t*re their #tate 3y 3rute 9*rce, a# can happen !ith 9ile#H) //:c0E:Na ua$ eRe#ource2.c# u#ing Sy#te!3 u#ing Sy#te!.'hreading3 c a## Na ua$ eRe#ource; #tatic int idCounter3 #tatic int G),XR+SOORC+S 9 "03 #tatic int 5CN)L5:X5: 9 6"3 int id3 Na ua$ eRe#ource01; if0idCounter 99 G),XR+SOORC+S1; Sy#te!.Con#o e.VriteLine0&Co re#ource# a*ai a$ e&13 id 9 5CN)L5:X5:3 <e #e; id 9 idCounterRR3 Sy#te!.Con#o e.VriteLine0&Re#ourceJ;0<K Con#tructed&2 id13 < < *oid :i#po#e01; idCounter663 Sy#te!.Con#o e.VriteLine0&Re#ourceJ;0<K :e#tructed&2 id 13 if0id 99 5CN)L5:X5:1;

Cha"ter 4* Initiali;ation = Cleanu"

1#5

Sy#te!.Con#o e.VriteLine0&'hing# are a.ry!&13 < _C.Suppre##Hina iMe0thi#13 < 8Na ua$ eRe#ource01; thi#.:i#po#e013 < pu$ ic #tatic *oid Gain01; u#eNa ua$ eRe#ource#013 Sy#te!.Con#o e.VriteLine0&Na ua$ e re#ource# u#ed and di#carded&13 'hread.S eep0"000013 Sy#te!.Con#o e.VriteLine0&"0 #econd# ater...&13 //'hi# Xi#X fine Na ua$ eRe#ource *r 9 ne. Na ua$ eRe#ource013 < #tatic *oid u#eNa ua$ eRe#ource#01; for0int i 9 03 i W G),XR+SOORC+S3 iRR1; Na ua$ eRe#ource *r 9 ne. Na ua$ eRe#ource013 *r.:i#po#e013 < < <///:8 ,eve +*ved the c*de that !a# previ*u#ly in the de#truct*r int* a +eth*d called $ispose()) =dditi*nally, !eve added the line1 _C.Suppre##Hina iMe0thi#13 ,hich tell# the >ar3age C*llect*r Gthe >C *34ectH n*t t* call the de#truct*r during gar3age c*llecti*n) ,eve kept the de#truct*r, 3ut it d*e# n*thing 3ut call $ispose()) -n thi# ca#e, the de#truct*r i# 4u#t a #a9etyEnet) -t re+ain# *ur re#p*n#i3ility t* e;plicitly call ?i#p*#eGH, 3ut i9 !e d*nt and it #* happen# that the gar3age c*llect*r get# 9ir#t up, then *ur 3ac*n i# pulled *ut *9 the 9ire) S*+e argue thi# i# !*r#e than u#ele## EE a +eth*d !hich i#nt guaranteed t* 3e called 3ut !hich per9*r+# a critical 9uncti*n)

1#6

Thinking in C

www.ThinkingIn.!et

,hen Calua3leRe#*urce#2 i# run, n*t *nly are there n* pr*3le+# !ith running *ut *9 re#*urce#, the idC*unter never get# a3*ve $K

4estructors. 4is$ose12. and the using *e5word


,hat 9*ll*!# i# c*n9u#ing) ,eve talked a3*ut the *nly valid u#e *9 the de#truct*r 3eing the guarantee that a valua3le re#*urce that e;i#t# a# an in#tance varia3le !ill 3e cleaned up) The C# language ha# a !ay t* guarantee that a #pecial cleanup +eth*d i# called, even i9 #*+ething unu#ual happen#) ,hat# c*n9u#ing i# that the techniDue call# not the de#truct*r, 3ut the $ispose() +eth*dK The techniDue u#e# *34ectE *riented inheritance, !hich !*nt 3e di#cu##ed until chapter #inheritance#) 5urther, t* illu#trate it, - need t* thr*! an E;cepti*n, a techniDue !hich !*nt 3e di#cu##ed until chapter #e;cepti*n##K Rather than put *99 the di#cu##i*n, th*ugh, - think it# i+p*rtant t* pre#ent the techniDue here) T* en#ure that a Iclean up +eth*dJ i# called1 0) -nherit 9r*+ -?i#p*#a3le 2) -+ple+ent public void $ispose() /) Place the vulnera3le *34ect in#ide a using() 3l*ck The $ispose() +eth*d !ill 3e called *n e;it 9r*+ the using 3l*ck) -+ n*t g*ing t* g* *ver thi# e;a+ple in detail, #ince it u#e# #* +any a#EyetE une;pl*red 9eature#, 3ut the key i# the 3l*ck that 9*ll*!# the using() declarati*n) ,hen y*u run thi# c*de, y*ull #ee that the $ispose() +eth*d i# called, 3ut n*t the de#truct*rK //:c0E:O#ingC eanup.c# u#ing Sy#te!3 c a## O#ingC eanup : 5:i#po#a$ e; pu$ ic #tatic *oid Gain01; u#ing0O#ingC eanup uc 9 ne. O#ingC eanup011; thro. ne. Cot5!p e!ented+xception013 <

Cha"ter 4* Initiali;ation = Cleanu"

1##

< O#ingC eanup01; Sy#te!.Con#o e.VriteLine0&Con#tructor ed&13 < pu$ ic *oid :i#po#e01; Sy#te!.Con#o e.VriteLine0&:i#po#e ca < ed&13

ca

8O#ingC eanup01; Sy#te!.Con#o e.VriteLine0&:e#tructor ca <

ed&13

< //:8 One *9 the thing# $ispose( ) can 3e u#e9ul 9*r i# pr*3ing the #*+eti+e# +y#teri*u# pr*ce## *9 gar3age c*llecti*n) Ot*d*1 ,rite a ne! pr*gra+ that illu#trate# 3etter C## de#truct*r < ?i#p*#e i##ue# The 9*ll*!ing e;a+ple #h*!# y*u !hat# g*ing *n and #u++ari7e# the previ*u# de#cripti*n# *9 gar3age c*llecti*n1 //:c0E:_ar$age.c# // :e!on#tration of the gar$age // co ector and di#po#a c a## Chair ; #tatic $oo gcrun 9 fa #e3 interna #tatic $oo f 9 fa #e3 interna #tatic int created 9 03 interna #tatic int fina iMed 9 03 int i3 interna Chair01 ; i 9 RRcreated3 if0created 99 EF1; Sy#te!.Con#o e.VriteLine0&Created EF&13

1#&

Thinking in C

www.ThinkingIn.!et

Sy#te!.Con#o e.VriteLine0&Byte# of !e!ory a ocated $efore _C: & R Sy#te!._C._et'ota Ge!ory0fa #e113 Sy#te!.Con#o e.VriteLine0&Byte# of !e!ory a ocated after _C: & R Sy#te!._C._et'ota Ge!ory0true113 < < 8Chair01 ; if0!gcrun1 ; // 'he fir#t ti!e the de#tructor i# ca ed: gcrun 9 true3 Sy#te!.Con#o e.VriteLine0 &Beginning to de#truct after & R created R & Chair# ha*e $een created&13 < if0i 99 EF1 ; Sy#te!.Con#o e.VriteLine0 &:e#troying Chair (EF2 & R &Setting f ag to #top Chair creation&13 f 9 true3 < fina iMedRR3 if0fina iMed Z9 created1 Sy#te!.Con#o e.VriteLine0 &) & R fina iMed R & fina iMed&13 < < pu$ ic c a## _ar$age ; pu$ ic #tatic *oid Gain0#tringJK arg#1 ; Sy#te!.Con#o e.VriteLine0&Byte# of !e!ory a ocated: & R Sy#te!._C._et'ota Ge!ory0fa #e113 // )# ong a# the f ag ha#n't $een #et2 // !a%e Chair#: .hi e0!Chair.f1 ; ne. Chair013 < Sy#te!.Con#o e.VriteLine0 &)fter a Chair# ha*e $een created:^n& R &tota created 9 & R Chair.created R

Cha"ter 4* Initiali;ation = Cleanu"

1#'

&2 tota fina iMed 9 & R Chair.fina iMed13 // Optiona argu!ent# force gar$age // co ection @ fina iMation: if0arg#.Length Z 01 ; if0arg#J0K 99 &gc& SS arg#J0K 99 &a &1 ; Sy#te!.Con#o e.VriteLine0&gc01:&13 Sy#te!._C.Co ect013 < /= \todo: Hind e7ui*a entY if0arg#J0K.e7ua #0&fina iMe&1 SS arg#J0K.e7ua #0&a &11 ; Sy#te!.Contro .VriteLine0&runHina iMation01:&13 Sy#te!.runHina iMation013 < < =/ Sy#te!.Con#o e.VriteLine0&$ye!&13 < < <///:8 The a3*ve pr*gra+ create# +any Chair *34ect#, and at #*+e p*int a9ter the gar3age c*llect*r 3egin# running, the pr*gra+ #t*p# creating Chair#) Since the gar3age c*llect*r can run at any ti+e, y*u d*nt kn*! e;actly !hen it !ill #tart up, #* there# a 9lag called gcrun t* indicate !hether the gar3age c*llect*r ha# #tarted running yet) = #ec*nd 9lag f i# a !ay 9*r Chair t* tell the .ain( ) l**p that it #h*uld #t*p +aking *34ect#) B*th *9 the#e 9lag# are #et !ithin OChair( ), !hich i# called during gar3age c*llecti*n) T!* *ther static varia3le#, created and finaliTed, keep track *9 the nu+3er *9 Chair# created ver#u# the nu+3er that get 9inali7ed 3y the gar3age c*llect*r) 5inally, each Chair ha# it# *!n Gn*nEstaticH int i #* it can keep track *9 !hat nu+3er it i#) ,hen Chair nu+3er &% i# 9inali7ed, the 9lag i# #et t* true t* 3ring the pr*ce## *9 Chair creati*n t* a #t*p) =ll thi# happen# in .ain( ), in the l**p .hi e0!Chair.f1 ; ne. Chair013

1&(

Thinking in C

www.ThinkingIn.!et

< :*u +ight !*nder h*! thi# l**p c*uld ever 9ini#h, #ince there# n*thing in#ide the l**p that change# the value *9 Chair6f) H*!ever, the finaliTe( ) pr*ce## !ill, eventually, !hen it 9inali7e# nu+3er &%) ,hen y*u run the pr*gra+, y*u pr*vide a c*++andEline argu+ent *9 Igc,J I9inali7e,J *r Iall)J The IgcJ argu+ent !ill call the #ystem6gc( ) +eth*d Gt* 9*rce e;ecuti*n *9 the gar3age c*llect*rH) U#ing the I9inali7eJ argu+ent call# #ystem6run:inaliTation( ) !hichRin the*ryR!ill cau#e any un9inali7ed *34ect# t* 3e 9inali7ed) =nd IallJ cau#e# 3*th +eth*d# t* 3e called) The preceding pr*gra+ #h*!# that the pr*+i#e that 9inali7er# !ill al!ay# 3e run h*ld# true, 3ut *nly i9 y*u e;plicitly 9*rce it t* happen y*ur#el9) -9 y*u d*nt cau#e #ystem6gc( ) t* 3e called, y*ull get an *utput like thi#1 Created EF Beginning to fina iMe created Hina iMing Chair (EF2 creation )fter a Chair# ha*e tota created 9 TII"2 $ye!

after TEI? Chair# ha*e $een Setting f ag to #top Chair $een created: tota fina iMed 9 2?IE

Thu#, n*t all 9inali7er# get called 3y the ti+e the pr*gra+ c*+plete#) -9 #ystem6gc( ) i# called, it !ill 9inali7e and de#tr*y all the *34ect# that are n* l*nger in u#e up t* that p*int) Re+e+3er that neither gar3age c*llecti*n n*r 9inali7ati*n i# guaranteed) -9 the "ava Cirtual Aachine G"CAH i#nt cl*#e t* running *ut *9 +e+*ry, then it !ill G!i#elyH n*t !a#te ti+e rec*vering +e+*ry thr*ugh gar3age c*llecti*n)

Cha"ter 4* Initiali;ation = Cleanu"

1&1

-he death condition


There i# a very intere#ting u#e *9 the de#truct*r, even i9 it# n*t called every ti+e) That u#e i# the veri9icati*n *9 the death condition2 *9 an *34ect) =t the p*int that y*ure n* l*nger intere#ted in an *34ectR!hen it# ready t* 3e cleaned upRthat *34ect #h*uld 3e in a #tate !here3y it# +e+*ry can 3e #a9ely relea#ed) 5*r e;a+ple, i9 the *34ect repre#ent# an *pen 9ile, that 9ile #h*uld 3e cl*#ed 3y the pr*gra++er 3e9*re the *34ect i# gar3ageE c*llected) -9 any p*rti*n# *9 the *34ect are n*t pr*perly cleaned up, then y*u have a 3ug in y*ur pr*gra+ that c*uld 3e very di99icult t* 9ind) The value *9 the de#truct*r# i# that it can 3e u#ed t* di#c*ver thi# c*nditi*n, even i9 the de#truct*r i#nt al!ay# called) -9 *ne *9 the de#truct*r# happen# t* reveal the 3ug, then y*u di#c*ver the pr*3le+, !hich i# all y*u really care a3*ut) Here# a #i+ple e;a+ple *9 h*! y*u +ight u#e it1 //:c0E::eathCondition.c# // O#ing a de#tructor to detect an o$Dect that // ha#n't $een proper y c eaned up. c a## Boo% ; $oo chec%edOut 9 fa #e3 interna Boo%0$oo chec%Out1 ; chec%edOut 9 chec%Out3 < interna *oid Chec%5n01 ; chec%edOut 9 fa #e3 < 8Boo%01 ; if0chec%edOut1 Sy#te!.Con#o e.VriteLine0&+rror: chec%ed out&13 < < pu$ ic c a## :eathCondition ; pu$ ic #tatic *oid Gain01 ;
2 = ter+ c*ined 3y Bill Cenner# G!!!)arti+a)c*+H

1&)

Thinking in C

www.ThinkingIn.!et

Boo% no*e 9 ne. Boo%0true13 // -roper c eanup: no*e .Chec%5n013 // :rop the reference2 forget to c ean up: ne. Boo%0true13 // Horce gar$age co ection @ fina iMation: Sy#te!._C.Co ect013 < < ///:8 The death c*nditi*n i# that all Boo( *34ect# are #upp*#ed t* 3e checked in 3e9*re they are gar3ageEc*llected, 3ut in .ain( ) a pr*gra++er err*r d*e#nt check in *ne *9 the 3**k#) ,ith*ut the de#truct*r# validati*n *9 the death c*nditi*n, thi# c*uld 3e a di99icult 3ug t* 9ind) *te that #ystem6 C6Collect( ) i# u#ed t* 9*rce cleanup Gand y*u #h*uld d* thi# during pr*gra+ devel*p+ent t* #peed de3uggingH) But even i9 it i#nt, the gar3age c*llect*r i# al!ay# 9ired *n the end *9 an applicati*n pr*ce## Gunle## 3r*ken int* !ith an e;plicit IC*ntr*lECJ interruptH, #* the errant Boo( !ill Duickly 3e di#c*vered)

9ow a gar+age collector wor*s


-9 y*u c*+e 9r*+ a pr*gra++ing language !here all*cating *34ect# *n the heap i# e;pen#ive, y*u +ay naturally a##u+e that C## #che+e *9 all*cating all re9erence type# *n the heap i# e;pen#ive) H*!ever, it turn# *ut that the gar3age c*llect*r can have a #igni9icant i+pact *n increasing the #peed *9 *34ect creati*n) Thi# +ight #*und a 3it *dd at 9ir#tRthat #t*rage relea#e a99ect# #t*rage all*cati*nR3ut it +ean# that all*cating #t*rage 9*r heap *34ect# in C# can 3e nearly a# 9a#t a# creating #t*rage *n the #tack in *ther language#) 5*r e;a+ple, y*u can think *9 the C@@ heap a# a yard !here each *34ect #take# *ut it# *!n piece *9 tur9) Thi# real e#tate can 3ec*+e a3and*ned #*+eti+e later and +u#t 3e reu#ed) -n C#, the +anaged heap i# Duite di99erentQ it# +*re like a c*nvey*r 3elt that +*ve# 9*r!ard every ti+e y*u all*cate a ne! *34ect) Thi# +ean# that *34ect #t*rage all*cati*n i# re+arka3ly rapid) The Iheap p*interJ i# #i+ply +*ved 9*r!ard int* virgin territ*ry, #* it# e99ectively the #a+e a# C@@# #tack all*cati*n) GO9 c*ur#e, there# a little e;tra *verhead 9*r 3**kkeeping 3ut it# n*thing like

Cha"ter 4* Initiali;ation = Cleanu"

1&3

#earching 9*r #t*rage)H :e#, y*u heard right P all*cati*n *n the +anaged heap i# $aster than all*cati*n !ithin a C@@E#tyle un+anaged heap) *! y*u +ight *3#erve that the heap i#nt in 9act a c*nvey*r 3elt, and i9 y*u treat it that !ay y*ull eventually #tart paging +e+*ry a l*t G!hich i# a 3ig per9*r+ance hitH and later run *ut) The trick i# that the gar3age c*llect*r #tep# in and !hile it c*llect# the gar3age it c*+pact# all the *34ect# in the heap #* that y*uve e99ectively +*ved the Iheap p*interJ cl*#er t* the 3eginning *9 the c*nvey*r 3elt and 9urther a!ay 9r*+ a page 9ault) The gar3age c*llect*r rearrange# thing# and +ake# it p*##i3le 9*r the highE#peed, in9initeE9reeEheap +*del t* 3e u#ed !hile all*cating #t*rage) T* under#tand h*! thi# !*rk#, y*u need t* get a little 3etter idea *9 the !ay the C*++*n Language Runti+e gar3age c*llect*r G>CH !*rk#) >ar3age c*llecti*n in the CLR Gre+e+3er that +e+*ry +anage+ent e;i#t# in the CLR I3el*!J the level *9 the C*++*n Type Sy#te+, #* thi# di#cu##i*n eDually applie# t* pr*gra+# !ritten in Ci#ual Ba#ic ) ET, Ei99el ) ET, and Pyth*n ) ET a# t* C# pr*gra+#H i# 3a#ed *n the idea that any n*ndead *34ect +u#t ulti+ately 3e tracea3le 3ack t* a re9erence that live# either *n the #tack *r in #tatic #t*rage) The chain +ight g* thr*ugh #everal layer# *9 *34ect#) Thu#, i9 y*u #tart in the #tack and the #tatic #t*rage area and !alk thr*ugh all the re9erence# y*ull 9ind all the live *34ect#) 5*r each re9erence that y*u 9ind, y*u +u#t trace int* the *34ect that it p*int# t* and then 9*ll*! all the re9erence# in that *34ect, tracing int* the *34ect# they p*int t*, etc), until y*uve +*ved thr*ugh the entire !e3 that *riginated !ith the re9erence *n the #tack *r in #tatic #t*rage) Each *34ect that y*u +*ve thr*ugh +u#t #till 3e alive) *te that there i# n* pr*3le+ !ith detached #el9Ere9erential gr*up#Rthe#e are #i+ply n*t 9*und, and are there9*re aut*+atically gar3age) =l#*, i9 y*u trace t* an *34ect that ha# already 3een !alked t*, y*u d* n*t have t* reEtrace it) Having l*cated all the IliveJ *34ect#, the >C #tart# at the end *9 the +anaged heap and #hi9t# the 9ir#t live *34ect in +e+*ry t* 3e directly ad4acent t* the penulti+ate live *34ect) Thi# pair *9 live *34ect# i# then #hi9ted t* the ne;t live *34ect, the three are #hi9ted en +a##e t* the ne;t, and #* 9*rth, until the heap i# c*+pacted)

1&4

Thinking in C

www.ThinkingIn.!et

O3vi*u#ly, gar3age c*llecti*n i# a l*t *9 !*rk, even *n a +*dern, highE #peed +achine) -n *rder t* i+pr*ve per9*r+ance, the gar3age c*llect*r re9ine# the 3a#ic appr*ach de#cri3ed here !ith generations) The 3a#ic c*ncept *9 generati*nal gar3age c*llecti*n i# that an *34ect all*cated recently i# +*re likely t* 3e gar3age than an *34ect !hich ha# already #urvived +ultiple pa##e# *9 the gar3age c*llect*r) S* in#tead *9 !alking the heap all the !ay 9r*+ the #tack *r #tatic #t*rage, *nce the >C ha# run *nce, the c*llect*r +ay a##u+e that the previ*u#ly c*+pacted *34ect# Gthe *lder generati*nH are all valid and *nly !alk the +*#t recently all*cated part *9 the heap Gthe ne! generati*nH) >ar3age c*llecti*n i# a 9av*rite t*pic *9 re#earcher#, and there !ill und*u3tedly 3e inn*vati*n# in >C that !ill eventually 9ind their !ay int* the 9ield) H*!ever, gar3age c*llecti*n and c*+puter p*!er have already g*tten t* the #tage !here the +*#t re+arka3le thing a3*ut >C i# h*! tran#parent it i#)

@e#+er initiali:ation
C# g*e# *ut *9 it# !ay t* guarantee that varia3le# are pr*perly initiali7ed 3e9*re they are u#ed) -n the ca#e *9 varia3le# that are de9ined l*cally t* a +eth*d, thi# guarantee c*+e# in the 9*r+ *9 a c*+pileEti+e err*r) S* i9 y*u #ay1 *oid H01 ; int i3 iRR3 < y*ull get an err*r +e##age that #ay# that i i# an una##igned l*cal varia3le) O9 c*ur#e, the c*+piler c*uld have given i a de9ault value, 3ut it# +*re likely that thi# i# a pr*gra++er err*r and a de9ault value !*uld have c*vered that up) 5*rcing the pr*gra++er t* pr*vide an initiali7ati*n value i# +*re likely t* catch a 3ug) -9 a pri+itive i# a data +e+3er *9 a cla##, h*!ever, thing# are a 3it di99erent) Since any +eth*d can initiali7e *r u#e that data, it +ight n*t 3e practical t* 9*rce the u#er t* initiali7e it t* it# appr*priate value 3e9*re the data i# u#ed) H*!ever, it# un#a9e t* leave it !ith a gar3age value, #* each

Cha"ter 4* Initiali;ation = Cleanu"

1&5

pri+itive data +e+3er *9 a cla## i# guaranteed t* get an initial value) Th*#e value# can 3e #een here1 //:c0E:5nitia Na ue#.c# // Sho.# defau t initia *a ue#. c a## Gea#ure!ent ; $oo t3 char c3 $yte $3 #hort #3 int i3 ong 3 f oat f3 dou$ e d3 interna *oid -rint01 ; Sy#te!.Con#o e.VriteLine0 &:ata type 5nitia *a ue^n& R &$oo & R t R &^n& R &char J& R c R &K &R 0int1c R&^n&R &$yte & R $ R &^n& R &#hort & R # R &^n& R &int & R i R &^n& R & ong & R R &^n& R &f oat & R f R &^n& R &dou$ e & R d13 < < pu$ ic c a## 5nitia Na ue# ; pu$ ic #tatic *oid Gain01 ; Gea#ure!ent d 9 ne. Gea#ure!ent013 d.-rint013 /= 5n thi# ca#e you cou d a #o #ay: ne. Gea#ure!ent01.print013 =/ < < ///:8 The *utput *9 thi# pr*gra+ i#1 :ata type $oo ean 5nitia fa #e *a ue

1&6

Thinking in C

www.ThinkingIn.!et

char $yte #hort int ong f oat dou$ e

J K 0 0 0 0 0 0.0 0.0

The char value i# a 7er*, !hich print# a# a #pace) :*ull #ee later that !hen y*u de9ine an *34ect re9erence in#ide a cla## !ith*ut initiali7ing it t* a ne! *34ect, that re9erence i# given a #pecial value *9 null G!hich i# a C# key!*rdH) :*u can #ee that even th*ugh the value# are n*t #peci9ied, they aut*+atically get initiali7ed) S* at lea#t there# n* threat *9 !*rking !ith uninitiali7ed varia3le#)

'$eci05ing initiali:ation
,hat happen# i9 y*u !ant t* give a varia3le an initial valueF One direct !ay t* d* thi# i# #i+ply t* a##ign the value at the p*int y*u de9ine the varia3le in the cla##) Here the 9ield de9initi*n# in cla## .easurement are changed t* pr*vide initial value#1 c a## Gea#ure!ent ; $oo $ 9 true3 char c 9 'x'3 $yte B 9 EF3 #hort # 9 0xff3 int i 9 >>>3 ong 9 "3 f oat f 9 T."Ef3 dou$ e d 9 T."E"P>3 //. . . :*u can al#* initiali7e n*npri+itive *34ect# in thi# #a+e !ay) -9 $epth i# a cla##, y*u can in#ert a varia3le and initiali7e it like #*1 c a## Gea#ure!ent ; :epth o 9 ne. :epth013 $oo ean $ 9 true3

Cha"ter 4* Initiali;ation = Cleanu"

1&#

// . . . -9 y*u havent given o an initial value and y*u try t* u#e it any!ay, y*ull get a runEti+e err*r called an e%ce"tion Gc*vered in Chapter #e;cepti*n#H) :*u can even call a #tatic +eth*d t* pr*vide an initiali7ati*n value1 c a## C5nit ; int i 9 5nit5013 //... #tatic int 5nit501; //L < < Thi# +eth*d can have argu+ent#, 3ut th*#e argu+ent# cann*t 3e in#tance varia3le#) "ava pr*gra++er# !ill n*te that thi# i# +*re re#trictive than "ava# in#tance initiali7ati*n, !hich can call n*nE#tatic +eth*d# and u#e previ*u#ly in#tantiated in#tance varia3le#) Thi# appr*ach t* initiali7ati*n i# #i+ple and #traight9*r!ard) -t ha# the li+itati*n that e-er4 *34ect *9 type .easurement !ill get the#e #a+e initiali7ati*n value#) S*+eti+e# thi# i# e;actly !hat y*u need, 3ut at *ther ti+e# y*u need +*re 9le;i3ility)

Constructor initiali:ation
The c*n#truct*r can 3e u#ed t* per9*r+ initiali7ati*n, and thi# give# y*u greater 9le;i3ility in y*ur pr*gra++ing #ince y*u can call +eth*d# and per9*r+ acti*n# at runEti+e t* deter+ine the initial value#) There# *ne thing t* keep in +ind, h*!ever1 y*u arent precluding the aut*+atic initiali7ati*n, !hich happen# 3e9*re the c*n#truct*r i# entered) S*, 9*r e;a+ple, i9 y*u #ay1 c a## Counter ; int i3 Counter01 ; i 9 F3 < // . . . then i !ill 9ir#t 3e initiali7ed t* $, then t* %) Thi# i# true !ith all the pri+itive type# and !ith *34ect re9erence#, including th*#e that are given e;plicit initiali7ati*n at the p*int *9 de9initi*n) 5*r thi# rea#*n, the c*+piler d*e#nt try t* 9*rce y*u t* initiali7e ele+ent# in the c*n#truct*r

1&&

Thinking in C

www.ThinkingIn.!et

at any particular place, *r 3e9*re they are u#edRinitiali7ati*n i# already guaranteed/)

Order o0 initiali:ation
,ithin a cla##, the *rder *9 initiali7ati*n i# deter+ined 3y the *rder that the varia3le# are de9ined !ithin the cla##) The varia3le de9initi*n# +ay 3e #cattered thr*ugh*ut and in 3et!een +eth*d de9initi*n#, 3ut the varia3le# are initiali7ed 3e9*re any +eth*d# can 3e calledReven the c*n#truct*r) 5*r e;a+ple1 //:c0E:OrderOf5nitia iMation.c# // :e!on#trate# initia iMation order. // Vhen the con#tructor i# ca ed to create a // 'ag o$Dect2 you' #ee a !e##age: c a## 'ag ; interna 'ag0int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&'ag0& R !ar%er R &1&13 < < c a## Card ; 'ag t" 9 ne. 'ag0"13 // Before con#tructor interna Card01 ; // 5ndicate .e're in the con#tructor: Sy#te!.Con#o e.VriteLine0&Card01&13 tT 9 ne. 'ag0TT13 // Reinitia iMe tT < 'ag t2 9 ne. 'ag0213 // )fter con#tructor interna *oid H01 ; Sy#te!.Con#o e.VriteLine0&H01&13 < 'ag tT 9 ne. 'ag0T13 // )t end < pu$ ic c a## OrderOf5nitia iMation ; pu$ ic #tatic *oid Gain01 ;
/ -n c*ntra#t, C@@ ha# the constructor initiali;er list that cau#e# initiali7ati*n t* *ccur

3e9*re entering the c*n#truct*r 3*dy, and i# en9*rced 9*r *34ect#) See Thinking in C++6 )nd edition Gavaila3le *n thi# 3**k# C? ROA and at www.BruceEckel.comH)

Cha"ter 4* Initiali;ation = Cleanu"

1&'

Card t 9 ne. Card013 t.H013 // Sho.# that con#truction i# done < < ///:8 -n Card, the de9initi*n# *9 the +ag *34ect# are intenti*nally #cattered a3*ut t* pr*ve that theyll all get initiali7ed 3e9*re the c*n#truct*r i# entered *r anything el#e can happen) -n additi*n, t9 i# reinitiali7ed in#ide the c*n#truct*r) The *utput i#1 'ag0"1 'ag021 'ag0T1 Card01 'ag0TT1 f01 Thu#, the t9 re9erence get# initiali7ed t!ice, *nce 3e9*re and *nce during the c*n#truct*r call) GThe 9ir#t *34ect i# dr*pped, #* it can 3e gar3ageE c*llected later)H Thi# +ight n*t #ee+ e99icient at 9ir#t, 3ut it guarantee# pr*per initiali7ati*nR!hat !*uld happen i9 an *verl*aded c*n#truct*r !ere de9ined that did not initiali7e t9 and there !a#nt a Ide9aultJ initiali7ati*n 9*r t9 in it# de9initi*nF

'tatic data initiali:ation


,hen the data i# static the #a+e thing happen#Q i9 it# a pri+itive and y*u d*nt initiali7e it, it get# the #tandard pri+itive initial value#) -9 it# a re9erence t* an *34ect, it# null unle## y*u create a ne! *34ect and attach y*ur re9erence t* it) -9 y*u !ant t* place initiali7ati*n at the p*int *9 de9initi*n, it l**k# the #a+e a# 9*r n*nEstatic#) There# *nly a #ingle piece *9 #t*rage 9*r a static, regardle## *9 h*! +any *34ect# are created) But the Due#ti*n ari#e# *9 !hen the static #t*rage get# initiali7ed) =n e;a+ple +ake# thi# Due#ti*n clear1 //:c0E:Static5nitia iMation.c# // Specifying initia *a ue# in a // c a## definition. c a## Bo. ;

1'(

Thinking in C

www.ThinkingIn.!et

interna Bo. 0int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&Bo. 0& R !ar%er R &1&13 < interna *oid H0int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&H0& R !ar%er R &1&13 < < c a## 'a$ e ; #tatic Bo. $" 9 ne. Bo. 0"13 interna 'a$ e01 ; Sy#te!.Con#o e.VriteLine0&'a$ e01&13 $2.H0"13 < interna *oid H20int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&H20& R !ar%er R &1&13 < #tatic Bo. $2 9 ne. Bo. 0213 < c a## Cup$oard ; Bo. $T 9 ne. Bo. 0T13 #tatic Bo. $E 9 ne. Bo. 0E13 interna Cup$oard01 ; Sy#te!.Con#o e.VriteLine0&Cup$oard01&13 $E.H0213 < interna *oid HT0int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&HT0& R !ar%er R &1&13 < #tatic Bo. $P 9 ne. Bo. 0P13 < pu$ ic c a## Static5nitia iMation ; pu$ ic #tatic *oid Gain01 ; Sy#te!.Con#o e.VriteLine0 &Creating ne. Cup$oard01 in !ain&13 ne. Cup$oard013 Sy#te!.Con#o e.VriteLine0 &Creating ne. Cup$oard01 in !ain&13 ne. Cup$oard013

Cha"ter 4* Initiali;ation = Cleanu"

1'1

t2.H20"13 tT.HT0"13 < #tatic 'a$ e t2 9 ne. 'a$ e013 #tatic Cup$oard tT 9 ne. Cup$oard013 < ///:8 Bowl all*!# y*u t* vie! the creati*n *9 a cla##, and +able and Cupboard create static +e+3er# *9 Bowl #cattered thr*ugh their cla## de9initi*n#) *te that Cupboard create# a n*nEstatic Bowl b9 pri*r t* the static de9initi*n#) The *utput #h*!# !hat happen#1 Bo. 0"1 Bo. 021 'a$ e01 f0"1 Bo. 0E1 Bo. 0P1 Bo. 0T1 Cup$oard01 f021 Creating ne. Cup$oard01 in !ain Bo. 0T1 Cup$oard01 f021 Creating ne. Cup$oard01 in !ain Bo. 0T1 Cup$oard01 f021 f20"1 fT0"1 The static initiali7ati*n *ccur# *nly i9 it# nece##ary) -9 y*u d*nt create a +able *34ect and y*u never re9er t* +able6b7 *r +able6b8, the static Bowl b7 and b8 !ill never 3e created) H*!ever, they are initiali7ed *nly !hen the $irst +able *34ect i# created G*r the 9ir#t static acce## *ccur#H) =9ter that, the static *34ect# are n*t reinitiali7ed) The *rder *9 initiali7ati*n i# static# 9ir#t, i9 they havent already 3een initiali7ed 3y a previ*u# *34ect creati*n, and then the n*nEstatic *34ect#) :*u can #ee the evidence *9 thi# in the *utput)

1')

Thinking in C

www.ThinkingIn.!et

-t# help9ul t* #u++ari7e the pr*ce## *9 creating an *34ect) C*n#ider a cla## called $og1 C. The 9ir#t ti+e an *34ect *9 type $og i# created, or the 9ir#t ti+e a static +eth*d *r static 9ield *9 cla## $og i# acce##ed, the C# runti+e +u#t l*cate the a##e+3ly in !hich $og# cla## de9initi*n i# #t*red) =# the $og cla## i# l*aded Gcreating a +ype *34ect, !hich y*ull learn a3*ut laterH, all *9 it# static initiali7er# are run) Thu#, static initiali7ati*n take# place *nly *nce, a# the +ype *34ect i# l*aded 9*r the 9ir#t ti+e) ,hen y*u create a new $og( ), the c*n#tructi*n pr*ce## 9*r a $og *34ect 9ir#t all*cate# en*ugh #t*rage 9*r a $og *34ect *n the heap) Thi# #t*rage i# !iped t* 7er*, aut*+atically #etting all the pri+itive# in that $og *34ect t* their de9ault value# G7er* 9*r nu+3er# and the eDuivalent 9*r boolean and charH and the re9erence# t* null) =ny initiali7ati*n# that *ccur at the p*int *9 9ield de9initi*n are e;ecuted) C*n#truct*r# are e;ecuted) =# y*u #hall #ee in Chapter #inheritance#, thi# +ight actually inv*lve a 9air a+*unt *9 activity, e#pecially !hen inheritance i# inv*lved)

D.

E.

1F.

11. 12.

'tatic Constructor
C# all*!# y*u t* gr*up *ther static initiali7ati*n# in#ide a #pecial Istatic c*n#truct*r)J -t l**k# like thi#1 c a## Spoon ; #tatic int i3 #tatic Spoon01; i 9 EF3 < // . . .

Cha"ter 4* Initiali;ation = Cleanu"

1'3

Thi# c*de, like *ther static initiali7ati*n#, i# e;ecuted *nly *nce, the 9ir#t ti+e y*u +ake an *34ect *9 that cla## or the 9ir#t ti+e y*u acce## a static +e+3er *9 that cla## Geven i9 y*u never +ake an *34ect *9 that cla##H) 5*r e;a+ple1 //:c0E:StaticCon#tructor.c# // +xp icit #tatic initia iMation // .ith #tatic con#tructor c a## Cup ; interna Cup0int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&Cup0& R !ar%er R &1&13 < interna *oid H0int !ar%er1 ; Sy#te!.Con#o e.VriteLine0&f0& R !ar%er R &1&13 < < c a## Cup# ; interna #tatic Cup c"3 #tatic Cup c23 #tatic Cup#01; Sy#te!.Con#o e.VriteLine0&5n#ide #tatic Cup#01 con#tructor&13 c" 9 ne. Cup0"13 c2 9 ne. Cup0213 < Cup#01 ; Sy#te!.Con#o e.VriteLine0&Cup#01&13 < < pu$ ic c a## +xp icitStatic ; pu$ ic #tatic *oid Gain01 ; Sy#te!.Con#o e.VriteLine0&5n#ide Gain01&13 Cup#.c".H0>>13 // 0"1 < // #tatic Cup# x 9 ne. Cup#013 // 021 // #tatic Cup# y 9 ne. Cup#013 // 021 < ///:8

1'4

Thinking in C

www.ThinkingIn.!et

The static c*n#truct*r 9*r Cups run !hen either the acce## *9 the static *34ect c7 *ccur# *n the line +arked G0H, *r i9 line G0H i# c*++ented *ut and the line# +arked G2H are unc*++ented) -9 3*th G0H and G2H are c*++ented *ut, the static c*n#truct*r 9*r Cups never *ccur#) =l#*, it d*e#nt +atter i9 *ne *r 3*th *9 the line# +arked G2H are unc*++entedQ the #tatic initiali7ati*n *nly *ccur# *nce)

)rra5 initiali:ation
-nitiali7ing array# in C i# err*rEpr*ne and tedi*u#) C@@ u#e# aggregate initiali;ation t* +ake it +uch #a9er&) C# ha# n* Iaggregate#J like C@@, #ince everything i# an *34ect in "ava) -t d*e# have array#, and the#e are #upp*rted !ith array initiali7ati*n) =n array i# #i+ply a #eDuence *9 either *34ect# *r pri+itive#, all the #a+e type and packaged t*gether under *ne identi9ier na+e) =rray# are de9ined and u#ed !ith the #DuareE3racket# inde%ing o"erator < >) T* de9ine an array y*u #i+ply 9*ll*! y*ur type na+e !ith e+pty #Duare 3racket#1 intJK a"3 :*u can al#* put the #Duare 3racket# a9ter the identi9ier t* pr*duce e;actly the #a+e +eaning1 int a"JK3 Thi# c*n9*r+# t* e;pectati*n# 9r*+ C and C@@ pr*gra++er#) The 9*r+er #tyle, h*!ever, i# pr*3a3ly a +*re #en#i3le #ynta;, #ince it #ay# that the type i# Ian int array)J That #tyle !ill 3e u#ed in thi# 3**k) The c*+piler d*e#nt all*! y*u t* tell it h*! 3ig the array i#) Thi# 3ring# u# 3ack t* that i##ue *9 Ire9erence#)J =ll that y*u have at thi# p*int i# a re9erence t* an array, and there# 3een n* #pace all*cated 9*r the array) T* create #t*rage 9*r the array y*u +u#t !rite an initiali7ati*n e;pre##i*n) 5*r array#, initiali7ati*n can appear any!here in y*ur c*de, 3ut y*u can al#* u#e a #pecial kind *9 initiali7ati*n e;pre##i*n that +u#t *ccur at the p*int !here the array i# created) Thi# #pecial initiali7ati*n i# a #et *9 value# #urr*unded 3y curly 3race#) The #t*rage all*cati*n Gthe eDuivalent
& See Thinking in C++6 )nd edition 9*r a c*+plete de#cripti*n *9 C@@ aggregate

initiali7ati*n)

Cha"ter 4* Initiali;ation = Cleanu"

1'5

*9 u#ing newH i# taken care *9 3y the c*+piler in thi# ca#e) 5*r e;a+ple1 intJK a" 9 ; "2 22 T2 E2 P <3 S* !hy !*uld y*u ever de9ine an array re9erence !ith*ut an arrayF intJK a23 ,ell, it# p*##i3le t* a##ign *ne array t* an*ther in C#, #* y*u can #ay1 a2 9 a"3 ,hat y*ure really d*ing i# c*pying a re9erence, a# de+*n#trated here1 //:c0E:)rray#.c# // )rray# of pri!iti*e#. pu$ ic c a## )rray# ; pu$ ic #tatic *oid Gain01 ; intJK a" 9 ; "2 22 T2 E2 P <3 intJK a23 a2 9 a"3 for0int i 9 03 i W a2.Length3 iRR1 a2JiKRR3 for0int i 9 03 i W a".Length3 iRR1 Sy#te!.Con#o e.VriteLine0 &a"J& R i R &K 9 & R a"JiK13 < < ///:8
<

:*u can #ee that a7 i# given an initiali7ati*n value !hile a8 i# n*tQ a8 i# a##igned laterRin thi# ca#e, t* an*ther array) There# #*+ething ne! here1 all array# have a pr*perty G!hether theyre array# *9 *34ect# *r array# *9 pri+itive#H that y*u can DueryR3ut n*t changeRt* tell y*u h*! +any ele+ent# there are in the array) Thi# +e+3er i# Length) Since array# in C#, a# in "ava and C, #tart c*unting 9r*+ ele+ent 7er*, the large#t ele+ent y*u can inde; i# Length - 7) -9 y*u g* *ut *9 3*und#, C and C@@ Duietly accept thi# and all*! y*u t* #t*+p all *ver y*ur +e+*ry, !hich i# the #*urce *9 +any in9a+*u# 3ug#) H*!ever, C# pr*tect# y*u again#t #uch pr*3le+# 3y cau#ing a runEti+e err*r Gan e%ce"tion, the #u34ect *9 Chapter 0$H i9 y*u #tep *ut *9 3*und#) O9 c*ur#e,

1'6

Thinking in C

www.ThinkingIn.!et

checking every array acce## c*#t# ti+e and c*de, !hich +ean# that array acce##e# +ight 3e a #*urce *9 ine99iciency in y*ur pr*gra+ i9 they *ccur at a critical 4uncture) S*+eti+e# the "-T can IprecheckJ t* en#ure that all inde; value# in a l**p !ill never e;ceed the array 3*und#, 3ut in general, array acce## pay# a #+all per9*r+ance price) By e;plicitly +*ving t* Iun#a9eJ c*de Gdi#cu##ed in #un#a9e c*de#H, 3*und# checking can 3e turned *99) ,hat i9 y*u d*nt kn*! h*! +any ele+ent# y*ure g*ing t* need in y*ur array !hile y*ure !riting the pr*gra+F :*u #i+ply u#e new t* create the ele+ent# in the array) Here, new !*rk# even th*ugh it# creating an array *9 pri+itive# Gnew !*nt create a n*narray pri+itiveH1 //:c0E:)rrayCe..c# // Creating array# .ith ne.. u#ing Sy#te!3 pu$ ic c a## )rrayCe. ; #tatic Rando! rand 9 ne. Rando!013 pu$ ic #tatic *oid Gain01 ; intJK a3 a 9 ne. intJrand.Cext0201 R "K3 Sy#te!.Con#o e.VriteLine0 & ength of a 9 & R a.Length13 for0int i 9 03 i W a.Length3 iRR1 Sy#te!.Con#o e.VriteLine0 &aJ& R i R &K 9 & R aJiK13 < < ///:8 Since the #i7e *9 the array i# ch*#en at rand*+, it# clear that array creati*n i# actually happening at runEti+e) -n additi*n, y*ull #ee 9r*+ the *utput *9 thi# pr*gra+ that array ele+ent# *9 pri+itive type# are aut*+atically initiali7ed t* Ie+ptyJ value#) G5*r nu+eric# and char, thi# i# 7er*, and 9*r boolean, it# false)H -9 y*ure dealing !ith an array *9 n*npri+itive *34ect#, y*u +u#t al!ay# u#e new) Here, the re9erence i##ue c*+e# up again 3ecau#e !hat y*u

Cha"ter 4* Initiali;ation = Cleanu"

1'#

create i# an array *9 re9erence#) C*n#ider the !rapper type Bnt"older, !hich i# a cla## and n*t a pri+itive1 //:c0E:)rrayC a##O$D.c# // Creating an array of nonpri!iti*e o$Dect#. u#ing Sy#te!3 c a## 5ntUo der; int i3 interna 5ntUo der0int i1; thi#.i 9 i3 < pu$ ic o*erride #tring 'oString01; return i.'oString013 < < pu$ ic c a## )rrayC a##O$D ; #tatic Rando! rand 9 ne. Rando!013 pu$ ic #tatic *oid Gain01 ; 5ntUo derJK a 9 ne. 5ntUo derJrand.Cext0201 R "K3 Sy#te!.Con#o e.VriteLine0 & ength of a 9 & R a.Length13 for0int i 9 03 i W a.Length3 iRR1 ; aJiK 9 ne. 5ntUo der0rand.Cext0P00113 Sy#te!.Con#o e.VriteLine0 &aJ& R i R &K 9 & R aJiK13 < < < ///:8 Here, even a9ter new i# called t* create the array1 5ntUo derJK a 9 ne. 5ntUo derJrand.Cext0201 R "K3 it# *nly an array *9 re9erence#, and n*t until the re9erence it#el9 i# initiali7ed 3y creating a ne! Bnteger *34ect i# the initiali7ati*n c*+plete1 aJiK 9 ne. 5ntUo der0rand.Cext0P00113

1'&

Thinking in C

www.ThinkingIn.!et

-9 y*u 9*rget t* create the *34ect, h*!ever, y*ull get an e;cepti*n at runE ti+e !hen y*u try t* read the e+pty array l*cati*n) -t# al#* p*##i3le t* initiali7e array# *9 *34ect# u#ing the curlyE3raceE encl*#ed li#t) There are t!* 9*r+#1 //:c0E:)rray5nit.c# // )rray initia iMation. c a## 5ntUo der; int i3 interna 5ntUo der0int i1; thi#.i 9 i3 < pu$ ic o*erride #tring 'oString01; return i.'oString013 < < pu$ ic c a## )rray5nit ; pu$ ic #tatic *oid Gain01 ; 5ntUo derJK a 9 ; ne. 5ntUo der0"12 ne. 5ntUo der0212 ne. 5ntUo der0T12 <3 5ntUo ne. ne. ne. <3 < < ///:8 Thi# i# u#e9ul at ti+e#, 3ut it# +*re li+ited #ince the #i7e *9 the array i# deter+ined at c*+pileEti+e) The 9inal c*++a in the li#t *9 initiali7er# i# *pti*nal) GThi# 9eature +ake# 9*r ea#ier +aintenance *9 l*ng li#t#)H derJK 5ntUo 5ntUo 5ntUo $ 9 ne. 5ntUo derJK ; der0"12 der0212 der0T12

Cha"ter 4* Initiali;ation = Cleanu"

1''

@ultidi#ensional arra5s
C# all*!# y*u t* ea#ily create +ultidi+en#i*nal array#1 //:c0E:Gu ti:i!)rray.c# // Creating !u tidi!en#iona u#ing Sy#te!3 array#.

c a## 5ntUo der ; int i3 interna 5ntUo der0int i1 ; thi#.i 9 i3 < pu$ ic o*erride #tring 'oString01 ; return i.'oString013 < < pu$ ic c a## Gu ti:i!)rray ; #tatic Rando! rand 9 ne. Rando!013 #tatic *oid -rt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 < pu$ ic #tatic *oid Gain01 ; intJ2K a" 9 ; ; "2 22 T2<2 ; E2 P2 ?2<2 <3 -rt0&a".Length 9 & R a".Length13 -rt0& 99 & R a"._etLength001 R & = & R a"._etLength0"113 for 0int i 9 03 i W a"._etLength0013 iRR1 for 0int D 9 03 D W a"._etLength0"13 DRR1 -rt0&a"J& R i R &2& R D R &K 9 & R a"Ji2 DK13 // T6: rectangu ar array: intJ22K a2 9 ne. intJ22 22 EK3 for 0int i 9 03 i W a2._etLength0013 iRR1 for 0int D 9 03 D W a2._etLength0"13 DRR1

)((

Thinking in C

www.ThinkingIn.!et

for 0int % 9 03 % W a2._etLength0213 %RR1 -rt0&a2J& R i R &2& R D R &2& R % R &K 9 & R a2Ji2D2%K13 // `agged array .ith *aried6Length *ector#: intJKJKJK aT 9 ne. intJrand.Cext0F1 R "KJKJK3 for 0int i 9 03 i W aT.Length3 iRR1 ; aTJiK 9 ne. intJrand.Cext0P1 R "KJK3 for 0int D 9 03 D W aTJiK.Length3 DRR1 aTJiKJDK 9 ne. intJrand.Cext0P1 R "K3 < for 0int i 9 03 i W aT.Length3 iRR1 for 0int D 9 03 D W aTJiK.Length3 DRR1 for 0int % 9 03 % W aTJiKJDK.Length3 %RR1 -rt0&aTJ& R i R &KJ& R D R &KJ& R % R &K 9 & R aTJiKJDKJ%K13 // )rray of nonpri!iti*e o$Dect#: 5ntUo derJ2K aE 9 ; ; ne. 5ntUo der0"12 ne. 5ntUo der021<2 ; ne. 5ntUo der0T12 ne. 5ntUo der0E1<2 ; ne. 5ntUo der0P12 ne. 5ntUo der0?1<2 <3 for 0int i 9 03 i W aE._etLength0013 iRR1 for 0int D 9 03 D W aE._etLength0"13 DRR1 -rt0&aEJ& R i R &2& R D R &K 9 & R aEJi2DK13 5ntUo derJKJK aP3 aP 9 ne. 5ntUo derJTKJK3 for 0int i 9 03 i W aP.Length3 iRR1 ; aPJiK 9 ne. 5ntUo derJTK3 for 0int D 9 03 D W aPJiK.Length3 DRR1; aPJiKJDK 9 ne. 5ntUo der0i=D13 < < for 0int i 9 03 i W aP._etLength0013 iRR1; for 0int D 9 03 D W aPJiK.Length3 DRR1; -rt0&aPJ& R i R &KJ& R D R &K 9 & R aPJiKJDK13

Cha"ter 4* Initiali;ation = Cleanu"

)(1

< < < < ///:8 //\todo: Hix Gu ti:i!)rray to dea .ith rectangu ar and Dagged array#. :i#cu## perfor!ance ra!ification# The c*de u#ed 9*r printing u#e# Length #* that it d*e#nt depend *n 9i;ed array #i7e#) The 9ir#t e;a+ple #h*!# a +ultidi+en#i*nal array *9 pri+itive#) :*u deli+it each vect*r in the array !ith curly 3race#1 intJKJK a" 9 ; ; "2 22 T2 <2 ; E2 P2 ?2 <2 <3 Each #et *9 #Duare 3racket# +*ve# y*u int* the ne;t level *9 the array) The #ec*nd e;a+ple #h*!# a threeEdi+en#i*nal array all*cated !ith new) Here, the !h*le array i# all*cated at *nce1 intJKJKJK a2 9 ne. intJ2KJ2KJEK3 But the third e;a+ple #h*!# that each vect*r in the array# that +ake up the +atri; can 3e *9 any length1 intJKJKJK aT 9 ne. intJpRand0F1KJKJK3 for0int i 9 03 i W aT. ength3 iRR1 ; aTJiK 9 ne. intJpRand0P1KJK3 for0int D 9 03 D W aTJiK. ength3 DRR1 aTJiKJDK 9 ne. intJpRand0P1K3 < The 9ir#t new create# an array !ith a rand*+Elength 9ir#t ele+ent and the re#t undeter+ined) The #ec*nd new in#ide the for l**p 9ill# *ut the ele+ent# 3ut leave# the third inde; undeter+ined until y*u hit the third new) :*u !ill #ee 9r*+ the *utput that array value# are aut*+atically initiali7ed t* 7er* i9 y*u d*nt give the+ an e;plicit initiali7ati*n value)

)()

Thinking in C

www.ThinkingIn.!et

:*u can deal !ith array# *9 n*npri+itive *34ect# in a #i+ilar 9a#hi*n, !hich i# #h*!n in the 9*urth e;a+ple, de+*n#trating the a3ility t* c*llect +any new e;pre##i*n# !ith curly 3race#1 5ntegerJKJK aE 9 ; ; ne. 5nteger0"12 ne. 5nteger021<2 ; ne. 5nteger0T12 ne. 5nteger0E1<2 ; ne. 5nteger0P12 ne. 5nteger0?1<2 <3 The 9i9th e;a+ple #h*!# h*! an array *9 n*npri+itive *34ect# can 3e 3uilt up piece 3y piece1 5ntegerJKJK aP3 aP 9 ne. 5ntegerJTKJK3 for0int i 9 03 i W aP. ength3 iRR1 ; aPJiK 9 ne. 5ntegerJTK3 for0int D 9 03 D W aPJiK. ength3 DRR1 aPJiKJDK 9 ne. 5nteger0i=D13 < The i;) i# 4u#t t* put an intere#ting value int* the Bnteger)

'ide+ar?)$$endi&, What a di00erence a rectangle #a*es


The additi*n *9 IrectangularJ array# t* C# i# *ne *9 a 9e! di99erent language 9eature# that have the p*tential t* +ake C# a great language 9*r nu+erically inten#ive c*+puting) ,ith I4aggedJ array# Garray# *9 the 9*r+ O34ectZ\Z\H, it# i+p*##i3le 9*r an *pti+i7er t* +ake a##u+pti*n# a3*ut +e+*ry all*cati*n) = 4agged array +ay have +ultiple r*!# p*inting t* the #a+e 3a#e array, unall*cated r*!#, and cr*##Ere9erence#) dou$ eJPKJK !y)rray 9 ne. dou$ eJPKJK3 !y)rrayJ0K 9 ne. dou$ eJ2K3 !y)rrayJ"K 9 !y)rrayJ0K3 !y)rrayJ2K 9 ne. dou$ eJ"K3 !y)rrayJEK 9 ne. dou$ eJEK3

Cha"ter 4* Initiali;ation = Cleanu"

)(3

= rectangular array, *n the *ther hand, i# a c*ntigu*u# 3l*ck1 dou$ e !y)rrayJP2EK 9 ne. dou$ eJP2EK3

Several *pti+i7ing techniDue# are harder t* d* !ith 4agged array# than !ith rectangular) ,hen re#earcher# at -BA added rectangular array# t* "ava, they #peeded up #*+e nu+erical 3ench+ark# 3y 9act*r# cl*#e t* '$K GIThe in4a Pr*4ect,J A*reira et al), C=CA, Oct 2$$0H S* 9ar, the C# *pti+i7er d*e#nt #ee+ t* 3e taking advantage *9 #uch p*##i3ilitie#, alth*ugh it d*e# run #*+e!hat 9a#ter than "ava *n Ch*le#ky +ultiplicati*n, *ne *9 the 3ench+ark# u#ed 3y the re#earcher#, p*rted here t* C#1 //:c0E:Cho e#%y.c# /= :e!on#tration progra! #ho.ing u#e of the )rray pac%age =/ /= =/ /= CUOL+Sa/: 'hi# progra! co!pute# the Cho e#%y factor O of a =/ /= #y!!etric po#iti*e definite !atrix ) #uch that ) 9 O'O .here =/

)(4

Thinking in C

www.ThinkingIn.!et

/= O' i# the tran#po#e of O. O i# an upper triangu ar !atrix. =/ u#ing Sy#te!3 pu$ ic c a## Cho e#%y ; pu$ ic #tatic *oid Gain01 ; int n 9 "0003 // pro$ e! #iMe dou$ eJ2K ) 9 ne. dou$ eJn2nK3 // n x n 26 di!en#iona array dou$ e op#3 dou$ e !f op#3 /= = Co!pute Cho e#%y factor u#ing an opti!iMed code. =/ initia iMe0)2n13 //)ccurate ./i "0!# on C'/2a/,-2 ./i PP!# on Vin>P/>I :ate'i!e t" 9 :ate'i!e.Co.3 unro 0)2n13 :ate'i!e t2 9 :ate'i!e.Co.3 'i!eSpan ti!e 9 0t2 6 t"13 op# 9 0000".0 = n1 = n1 = n1 / T.013 !f op# 9 00".0e6? = op#1 / ti!e.'ota Second#13 Sy#te!.Con#o e.Vrite0&Opti!iMed code2 'i!e: &Rti!eR& Gf op#:&R!f op#R& &13 *a idate0)2n13 /= = Co!pute Cho e#%y factor u#ing a #traightfor.ard code. =/ initia iMe0)2n13 t" 9 :ate'i!e.Co.3 p ain0)2n13 t2 9 :ate'i!e.Co.3 ti!e 9 0t2 6 t"13 op# 9 0000".0 = n1 = n1 = n1 / T.013 !f op# 9 00".0e6? = op#1 / ti!e.'ota Second#13

Cha"ter 4* Initiali;ation = Cleanu"

)(5

Sy#te!.Con#o e.Vrite0&Si!p e code2 'i!e: &Rti!eR& Gf op#:&R!f op#R& &13 *a idate0)2n13 < pu$ ic #tatic *oid initia iMe0dou$ eJ2K )2int n1 ; int i3 int D3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; for0 i 9 03 i W9 0n 6 "13 iRR1 ; )JD2 iK 9 03 <3 <3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; for0 i 9 D3 i W9 0n 6 "13 iRR1 ; )Ji2 DK 9 D R "3 <3 <3 < pu$ ic #tatic *oid *a idate0dou$ eJ2K )2int n1 ; int i3 int D3 int re#u t3 dou$ e ep#3 re#u t 9 "3 ep# 9 ".0e6"03 for0 i 9 03 i W9 0n 6 "13 iRR1 ; for0 D 9 i3 D W9 0n 6 "13 DRR1 ; if 000Gath.)$#00)JD2 iK 6 ".0111 Z ep#11 ; Sy#te!.Con#o e.VriteLine0Gath.)$#00)JD2 iK 6 ".01113 re#u t 9 03 <3 <3 <3 if 0re#u t 99 "1 ; Sy#te!.Con#o e.VriteLine0&Re#u t i# correct!&13 < e #e ; Sy#te!.Con#o e.VriteLine0&Re#u t i# incorrect!&13

)(6

Thinking in C

www.ThinkingIn.!et

< < pu$ ic #tatic *oid p ain0dou$ eJ2K )2int n1 ; int i3 int D3 int %3 dou$ e #3 dou$ e d3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; d 9 0.03 for0 % 9 03 % W9 0D 6 "13 %RR1 ; # 9 0.03 for0 i 9 03 i W9 0% 6 "13 iRR1 ; # 9 0# R 0)J%2iK = )JD2iK113 <3 # 9 00)JD2%K 6 #1 / )J%2%K13 )JD2%K 9 #3 d 9 0d R 0# = #113 <3 d 9 0)JD2DK 6 d13 )JD2DK 9 Gath.S7rt0d13 <3 < pu$ ic #tatic *oid unro 0dou$ eJ2K )2int n1 ; int i3 int D3 int %3 dou$ e #3 dou$ e d3 dou$ e #03 dou$ e #"3 dou$ e #23 dou$ e #T3 dou$ e aiD3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; d 9 0.03 for0 % 9 03 % W9 0D 6 E13 % R9 E1 ; #0 9 0.03 #" 9 0.03

Cha"ter 4* Initiali;ation = Cleanu"

)(#

#2 9 0.03 #T 9 0.03 for0 i 9 03 i W9 0% 6 "13 iRR1 ; aiD 9 )JD2iK3 #0 9 0#0 R 0)J0% R 012iK = aiD113 #" 9 0#" R 0)J0% R "12iK = aiD113 #2 9 0#2 R 0)J0% R 212iK = aiD113 #T 9 0#T R 0)J0% R T12iK = aiD113 <3 #0 9 00)JD20% R 01K 6 #01 / )J0% R 0120% R 01K13 )JD20% R 01K 9 #03 #" 9 0#" R 0)J0% R "12%K = )JD2%K113 #" 9 00)JD20% R "1K 6 #"1 / )J0% R "120% R "1K13 )JD2 % R "K 9 #"3 #2 9 00#2 R 0)J0% R 212%K = )JD2%K11 R 0)J0% R 2120% R "1K = )JD20% R "1K113 #2 9 00)JD20% R 21K 6 #21 / )J0% R 2120% R 21K13 )JD20% R 21K 9 #23 #T 9 000#T R 0)J0% R T12%K = )JD2%K11 R 0)J0% R T120% R "1K = )JD20% R "1K11 R 0)J0% R T120% R 21K = )JD20% R 21K113 #T 9 00)JD20% R T1K 6 #T1 / )J0% R T120% R T1K13 )JD20% R T1K 9 #T3 d 9 0000d R 0#0 = #011 R 0#" = #"11 R 0#2 = #211 R 0#T = #T113 <3 for0 % 9 00D / E1 = E13 % W9 0D 6 "13 %RR1 ; # 9 0.03 for0 i 9 03 i W9 0% 6 "13 iRR1 ; # 9 0# R 0)J%2iK = )JD2iK113 <3 # 9 00)JD2%K 6 #1 / )J%2%K13 )JD2%K 9 #3 d 9 0d R 0# = #113 <3 d 9 0)JD2DK 6 d13 )JD2DK 9 0Gath.S7rt0d113

)(&

Thinking in C

www.ThinkingIn.!et

<3 < < ///:8 5*r c*+pari#*n, here# an eDuivalent pr*gra+ in "ava, u#ing 4agged array#1 //:c0E:Cho e#%y.Da*a /= :e!on#tration progra! #ho.ing u#e of the )rray pac%age =/ /= =/ /= CUOL+Sa/: 'hi# progra! co!pute# the Cho e#%y factor O of a =/ /= #y!!etric po#iti*e definite !atrix ) #uch that ) 9 O'O .here =/ /= O' i# the tran#po#e of O. O i# an upper triangu ar !atrix. =/ i!port Da*a.!ath.=3 pu$ ic c a## Cho e#%yXnati*eXarray ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; int n 9 "0003 // pro$ e! #iMe dou$ eJKJK ) 9 ne. dou$ eJnKJnK3 // n x n 26 di!en#iona array dou$ e op#3 dou$ e !f op#3 /= = Co!pute Cho e#%y factor u#ing an opti!iMed code. =/ initia iMe0)2n13 //)ccurate ./i "0!# on C'/2a/,-2 ./i PP!# on Vin>P/>I dou$ e t" 9 0"e6T=Sy#te!.current'i!eGi i#0113 unro 0)2n13 dou$ e t2 9 0"e6T=Sy#te!.current'i!eGi i#0113 dou$ e ti!e 9 0t2 6 t"13

Cha"ter 4* Initiali;ation = Cleanu"

)('

op# 9 0000".0 = n1 = n1 = n1 / T.013 !f op# 9 00".0e6? = op#1 / ti!e13 Sy#te!.out.print0&Opti!iMed code2 'i!e: &Rti!eR& Gf op#:&R!f op#R& &13 *a idate0)2n13 /= = Co!pute Cho e#%y factor u#ing a #traightfor.ard code. =/ initia iMe0)2n13 t" 9 0"e6T=Sy#te!.current'i!eGi i#0113 p ain0)2n13 t2 9 0"e6T=Sy#te!.current'i!eGi i#0113 ti!e 9 0t2 6 t"13 op# 9 0000".0 = n1 = n1 = n1 / T.013 !f op# 9 00".0e6? = op#1 / ti!e13 Sy#te!.out.print0&Si!p e code2 'i!e: &Rti!eR& Gf op#:&R!f op#R& &13 *a idate0)2n13 < pu$ ic #tatic *oid initia iMe0dou$ eJKJK )2int n1 ; int i3 int D3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; for0 i 9 03 i W9 0n 6 "13 iRR1 ; )JDKJiK 9 03 <3 <3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; for0 i 9 D3 i W9 0n 6 "13 iRR1 ; )JiKJDK 9 D R "3 <3 <3 < pu$ ic #tatic *oid *a idate0dou$ eJKJK )2int n1 ; int i3 int D3 int re#u t3

)1(

Thinking in C

www.ThinkingIn.!et

dou$ e ep#3 re#u t 9 "3 ep# 9 ".0e6"03 for0 i 9 03 i W9 0n 6 "13 iRR1 ; for0 D 9 i3 D W9 0n 6 "13 DRR1 ; if 000Gath.a$#00)JDKJiK 6 ".0111 Z ep#11 ; re#u t 9 03 <3 <3 <3 if 0re#u t 99 "1 ; Sy#te!.out.print n0&Re#u t i# correct!&13 < e #e ; Sy#te!.out.print n0&Re#u t i# incorrect!&13 < < pu$ ic #tatic *oid p ain0dou$ eJKJK )2int n1 ; int i3 int D3 int %3 dou$ e #3 dou$ e d3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; d 9 0.03 for0 % 9 03 % W9 0D 6 "13 %RR1 ; # 9 0.03 for0 i 9 03 i W9 0% 6 "13 iRR1 ; # 9 0# R 0)J%KJiK = )JDKJiK113 <3 # 9 00)JDKJ%K 6 #1 / )J%KJ%K13 )JDKJ%K 9 #3 d 9 0d R 0# = #113 <3 d 9 0)JDKJDK 6 d13 )JDKJDK 9 Gath.#7rt0d13 <3 < pu$ ic #tatic *oid unro int i3 0dou$ eJKJK )2int n1 ;

Cha"ter 4* Initiali;ation = Cleanu"

)11

int D3 int %3 dou$ e #3 dou$ e d3 dou$ e #03 dou$ e #"3 dou$ e #23 dou$ e #T3 dou$ e aiD3 for0 D 9 03 D W9 0n 6 "13 DRR1 ; d 9 0.03 for0 % 9 03 % W9 0D 6 E13 % R9 E1 ; #0 9 0.03 #" 9 0.03 #2 9 0.03 #T 9 0.03 for0 i 9 03 i W9 0% 6 "13 iRR1 ; aiD 9 )JDKJiK3 #0 9 0#0 R 0)J0% R 01KJiK = aiD113 #" 9 0#" R 0)J0% R "1KJiK = aiD113 #2 9 0#2 R 0)J0% R 21KJiK = aiD113 #T 9 0#T R 0)J0% R T1KJiK = aiD113 <3 #0 9 00)JDKJ0% R 01K 6 #01 / )J0% R 01KJ0% R 01K13 )JDKJ0% R 01K 9 #03 #" 9 0#" R 0)J0% R "1KJ%K = )JDKJ%K113 #" 9 00)JDKJ0% R "1K 6 #"1 / )J0% R "1KJ0% R "1K13 )JDKJ% R "K 9 #"3 #2 9 00#2 R 0)J0% R 21KJ%K = )JDKJ%K11 R 0)J0% R 21KJ0% R "1K = )JDKJ0% R "1K113 #2 9 00)JDKJ0% R 21K 6 #21 / )J0% R 21KJ0% R 21K13 )JDKJ0% R 21K 9 #23 #T 9 000#T R 0)J0% R T1KJ%K = )JDKJ%K11 R 0)J0% R T1KJ0% R "1K = )JDKJ0% R "1K11 R 0)J0% R T1K J0% R 21K = )JDKJ0% R 21K113 #T 9 00)JDKJ0% R T1K 6 #T1 / )J0% R T1KJ0% R T1K13 )JDKJ0% R T1K 9 #T3

)1)

Thinking in C

www.ThinkingIn.!et

d 9 0000d R 0#0 = #011 R 0#" = #"11 R 0#2 = #211 R 0#T = #T113 <3 for0 % 9 00D / E1 = E13 % W9 0D 6 "13 %RR1 ; # 9 0.03 for0 i 9 03 i W9 0% 6 "13 iRR1 ; # 9 0# R 0)J%KJiK = )JDKJiK113 <3 # 9 00)JDKJ%K 6 #1 / )J%KJ%K13 )JDKJ%K 9 #3 d 9 0d R 0# = #113 <3 d 9 0)JDKJDK 6 d13 )JDKJDK 9 0Gath.#7rt0d113 <3 < <///:8 ,hen the t!* pr*gra+# are run *n +y P/E'$$, the#e are the re#ult#1 Ch*le#ky)e;e1 4ava Ch*le#ky`native`array1

'u##ar5
Thi# #ee+ingly ela3*rate +echani#+ 9*r initiali7ati*n, the c*n#truct*r, #h*uld give y*u a #tr*ng hint a3*ut the critical i+p*rtance placed *n initiali7ati*n in the language) =# Str*u#trup !a# de#igning C@@, *ne *9 the 9ir#t *3#ervati*n# he +ade a3*ut pr*ductivity in C !a# that i+pr*per initiali7ati*n *9 varia3le# cau#e# a #igni9icant p*rti*n *9 pr*gra++ing pr*3le+#) The#e kind# *9 3ug# are hard t* 9ind, and #i+ilar i##ue# apply t* i+pr*per cleanup) Becau#e c*n#truct*r# all*! y*u t* guarantee pr*per initiali7ati*n and cleanup Gthe c*+piler !ill n*t all*! an *34ect t* 3e created !ith*ut the pr*per c*n#truct*r call#H, y*u get c*+plete c*ntr*l and #a9ety) -n C@@, de#tructi*n i# Duite i+p*rtant 3ecau#e *34ect# created !ith new +u#t 3e e;plicitly de#tr*yed) -n C#, the gar3age c*llect*r aut*+atically relea#e# the +e+*ry 9*r all *34ect#, #* the eDuivalent cleanup +eth*d in

Cha"ter 4* Initiali;ation = Cleanu"

)13

C# i#nt nece##ary +uch *9 the ti+e) -n ca#e# !here y*u d*nt need de#truct*rElike 3ehavi*r, C## gar3age c*llect*r greatly #i+pli9ie# pr*gra++ing, and add# +uchEneeded #a9ety in +anaging +e+*ry) H*!ever, the gar3age c*llect*r d*e# add a runEti+e c*#t, the e;pen#e *9 !hich i# di99icult t* put int* per#pective 3ecau#e *9 the *ther per9*r+ance ra+i9icati*n# *9 the -L and CRL appr*ach t* 3inary 9ile#) Becau#e *9 the guarantee that all *34ect# !ill 3e c*n#tructed, there# actually +*re t* the c*n#truct*r than !hat i# #h*!n here) -n particular, !hen y*u create ne! cla##e# u#ing either com"osition *r inheritance the guarantee *9 c*n#tructi*n al#* h*ld#, and #*+e additi*nal #ynta; i# nece##ary t* #upp*rt thi#) :*ull learn a3*ut c*+p*#iti*n, inheritance, and h*! they a99ect c*n#truct*r# in 9uture chapter#)

%&ercises

)14

Thinking in C

www.ThinkingIn.!et

", Cou$ling and Cohesion


,hy d* pe*ple !*rry a3*ut #*9t!are IarchitectureJF ,hat +ake# #*9t!are hard t* under#tandF H*! d*e# c*ntr*lling #c*pe and creating a3#tract inter9ace# +ake even the +*#t c*+ple; pr*3le+ tracta3leF ,hat are the type# *9 c*upling and their relative c*#t#F ,hat are the type# *9 c*he#i*n and their relative 3ene9it#F H*! d* *34ect# addre## the#e i##ue#F H*! d*e# g**d de#ign e+erge 9r*+ 9*ur #i+ple rule# a3*ut c*de #tructureF H*! C# *rgani7e# 9ile# and type#) ,hy na+e#pace# are a g**d appr*ach t* #c*pe 3ey*nd the *34ectElevel) Creating y*ur *!n na+e#pace#) The c*ncept *9 vi#i3ility) The 9i9th rule *9 c*de #tructure) Pu3lic, internal, and private acce## +*di9ier# Gpr*tected and pr*tected internal are de9erred t* the ne;t chapterH)

Cha"ter 4* Initiali;ation = Cleanu"

)15

?ata encap#ulati*n, inheritance, and p*ly+*rphi#+ are the c*rner#t*ne capa3ilitie# *9 *34ect *rientati*n, 3ut their u#e d*e# n*t aut*+atically create g**d *r even pa##a3le de#ign) >**d #*9t!are de#ign ari#e# 9r*+ dividing a pr*3le+ int* c*herent part# and tackling th*#e part# independently, in a +anner that# ea#y t* te#t and change) O34ect *rientati*n 9acilitate# 4u#t #uch partiti*ning *9 c*ncern#, 3ut reDuire# y*u t* under#tand the 9*rce# that +ake #*+e #*9t!are de#ign# 3etter than *ther#) The#e 9*rce#, c*upling and c*he#i*n, are univer#al t* all #*9t!are #y#te+# and pr*vide a 3a#i# 9*r c*+paring #*9t!are architecture# and de#ign#)
,hen !e #peak *9 IarchitectureJ and Ide#ignJ in #*9t!are #y#te+#, !e can 3e #peaking *9 +any di99erent thing# P the phy#ical #tructure *9 the net!*rk, the #et *9 *perating #y#te+ and #erver pr*vider# ch*#en, the graphic de#ign *9 the entire clientE 9acing ,e3#ite, the u#erEinter9ace de#ign *9 applicati*n# !e !rite, *r the internal #tructure *9 the pr*gra+# 3eing !ritten) =ll *9 the#e 9act*r# are i+p*rtant and it# a #ha+e that !e have n*t yet devel*ped a c*++*n v*ca3ulary 9*r giving each *9 the+ their 4u#t attenti*n) 5*r the purp*#e# *9 thi# chapter, !e are #*lely c*ncerned !ith the internal #tructure *9 pr*gra+# P deci#i*n# that !ill 3e +ade and e+3*died in the C# #*urce c*de y*u !rite)

'o0tware )s )rchitecture vs. 'o0tware )rchitecture


Ot*d*1 A*ve thi# #*+e!here el#e =# *9ten a# n*t, the lead pr*gra++er in a tea+ ha# the title *9 S*9t!are =rchitect) The p*pularity *9 thi# title c*+e# 9r*+ the p*pular vie! that the challenge# *9 3uilding a #*9t!are #y#te+ are #i+ilar t* the challenge# *9 3uilding a #ky#craper *r 3ridge) The vie! *9 #*9t!are as architecture #te+# 9r*+ the undenia3le truth that #*9t!are *9ten 9ail#) A*#t *9 th*#e !h* have #tudied larger #*9t!are pr*4ect# Gpr*4ect# in e;ce## *9 ',$$$ 9uncti*n p*int#, !hich tran#late# t* pr*3a3ly 0%',$$$ line# *9 C#H have c*ncluded that a#pect# *ther than c*de c*n#tructi*n are the +*#t i+p*rtant driver# *9 #ucce## *r 9ailure) ,hat the#e pe*ple #ee in large pr*4ect#, ti+e and again, are 9ailure# relating t* reDuire+ent# and 9ailure# relating t* integrati*n1 tea+# 3uild the !r*ng thing and then they cant get the piece# they 3uild t* 9it t*gether) Ba#ed *n the#e *3#ervati*n#, the challenge# *9 #*9t!are #ee+ed t* parallel the challenge# *9 architecture P the cra9t#+an#hip *9 the individual !*rker i# all !ell and g**d, 3ut #ucce## c*+e# 9r*+ care9ul planning and c**rdinati*n) Every 9e! year#, the pendulu+ *9 p*pular *pini*n #!ing# 9r*+ thi# vie! t*!ard# a vie! that e+pha#i7e# the individual c*ntri3uti*n# *9 talented pr*gra++er#) = 9e!

Cha"ter 5* >iding the Im"lementation

)1#

year# later, the pendulu+ predicta3ly #!ing# the *ther !ay) Thi# vie! *9 #*9t!are h*ld# that, like it *r n*t, c*de de9ine# the #*9t!are# 3ehavi*r and that diagra+# and #peci9icati*n# d* n*t generally capture the real i##ue# at hand !hen de#igning pr*gra+#) Pr*p*nent# *9 thi# vie! argue that the #*9t!are as architecture vie! i# pri+arily pu#hed 3y c*n#ultant# and vend*r# #elling e;pen#ive t**l# that generate a l*t *9 paper 3ut little pr*duct) Until recently, the e#calati*n *9 de9ect c*#t# *ver ti+e !a# the tru+p card 9*r the #*9t!are as architecture adv*cate#) -n 06(%, Barry B*eh+ pu3li#hed a paper in !hich he e#ta3li#hed that a de9ect c*rrected 9*r U0 in the reDuire+ent# pha#e c*uld c*#t U0$$ t* 9i; *nce depl*yed0) ,ith th*#e ec*n*+ic#, 3ig upE9r*nt e99*rt# !ere *3vi*u#ly !*rth!hile) -t# d*u3t9ul that #uch nu+3er# have +uch +eaning t*dayQ B*eh+ hi+#el9 c*ncluded in 2$$0 that 9*r I#+aller, n*ncritical #*9t!are #y#te+#J the c*#t e#calati*n !a# I+*re like '10 than 0$$10)J The e;pl*#ively p*pular #et *9 practice# called E;tre+e Pr*gra++ing i# 3a#ed *n Ithe technical pre+i#e Zthat\ the c*#t *9 change Zcan ri#e\ +uch +*re #l*!ly, eventually reaching an a#y+pt*te)J 2 S* #h*uld y*u vie! #*9t!are devel*p+ent a# an undertaking akin t* 3uilding a 3ridge *r a# *ne akin t* gr*!ing a gardenF ,ell, there are a 9e! thing# !e can #ay 9*r #ure a3*ut #*9t!are devel*p+ent1 Pr*gra++er# al!ay# *vere#ti+ate their l*ngEter+ pr*ductivity) A*#t large #*9t!are pr*4ect# #till c*#t +*re than e;pected) A*#t pr*4ect# #till take l*nger t* 9ini#h than e;pected) Aany are cancelled pri*r t* c*+pleti*n and +any, *nce depl*yed, 9ail t* achieve the 3u#ine## g*al# they !ere intended t* #erve) Bey*nd the#e generally pe##i+i#tic #tate+ent#, the variance# 3et!een individual#, tea+#, c*+panie#, and indu#try #ect*r# #!a+p the #tati#tic#) U#e9ul #*9t!are #y#te+# range 9r*+ pr*gra+# that are a 9e! hundred line# l*ng Gthe #*urce c*de t* ping i# #h*rter than #*+e *9 the #a+ple# in thi# 3**kKH t* pr*gra+# in e;ce## *9 a +illi*n line# *9 c*de) Tea+# can range 9r*+ individual# t* hundred#) = #ucce##9ul pr*gra+ +ay 3e a 9uncti*nE*pti+i7er that, *n a #ingle run *ut *9 a th*u#and, pr*duce# a +eaning9ul re#ult *r a li9e #upp*rt #y#te+ that, literally, never 9ail# Gye#, pr*va3ly c*rrect #*9t!are i# p*##i3leH) S* !hen pe*ple #tart #p*uting #tati#tic# *r pr*n*unce+ent# a3*ut I3e#t practice#,J at 3e#t theyre *verEgenerali7ing and at !*r#t theyre trying t* #care y*u int* 3uying !hatever it i# theyre #elling /) ,e d* kn*! that there# at lea#t *ne +a4*r 9la! in the #*9t!are a# architecture +etaph*r, and that i# that unlike a 3uilding that re+ain# under c*n#tructi*n until a de#ignated Igrand *pening,J #*9t!are #h*uld 3e 3uilt and depl*yed incre+entally P i9 n*t *ne Ir**+ at a ti+eJ then at lea#t I*ne 9l**r at a ti+e)J Thi# i#, *9 c*ur#e, ea#ier in #*+e #ituati*n# than in *ther#, 3ut *ne *9 the great trui#+# *9 #*9t!are

0 B) B*eh+ and C) Ba#ili, YS*9t!are ?e9ect Reducti*n T*p 0$ Li#t,Y -EEE C*+puter, -EEE C*+puter

S*ciety, C*l) /&,

*) 0, "anuary 2$$0, pp) 0/'E0/%)

2 E;tre+e Pr*gra++ing E;plained, pg) 2/ / Be e#pecially du3i*u# i9 y*u hear I%$^ 9ailure rate)J Thi#, like the U/$$B that :2N 9ailure# !ere g*ing

t* c*#t, i# a nu+3er that *riginated in a #ingle pr*9itE+*tivated #tudy 3ut !hich ha# 3een repeated #* +any ti+e# that it# taken *n a li9e *9 it# *!n)

)1&

Thinking in C

www.ThinkingIn.!et

devel*p+ent +anage+ent i# that 9r*+ the 9ir#t !eek# *9 the pr*4ect, y*u #h*uld 3e a3le t* at lea#t p*tentially #hip y*ur late#t 3uild)

What Is 'o0tware )rchitecture


Every n*nEtrivial pr*gra+ #h*uld have an *verall *rdering principle) ,hile that# vague en*ugh t* all*! 9*r a l*t *9 di99erent interpretati*n# *9 !hat d*e# and d*e# n*t c*n#titute an architecture, y*u d*nt gain +uch 3y vie!ing ) ET a# y*ur #y#te+# architecture) Rather, y*u #h*uld c*n#ider the !ay that data 9l*!# in and *ut *9 y*ur #y#te+ and the !ay# in !hich it i# tran#9*r+ed) =t #uch a level *9 a3#tracti*n, there are 9e!er variati*n# in #tructure than y*u +ight gue##) A*#t pr*gra+# are g*ing t* have at lea#t a 9e! #u3#y#te+#, and each +ay have it# *!n architecture) 5*r in#tance, al+*#t all #y#te+# reDuire #*+e kind *9 u#er inter9ace, even i9 it# 4u#t 9*r ad+ini#trati*n, and U- #u3#y#te+# are typically architected t* 9*ll*! either the A*delECie!EC*ntr*ller pattern *r the Pre#entati*nE =3#tracti*nEC*ntr*l pattern G3*th *9 !hich are th*r*ughly e;plained in Chapter #,ind*!# 9*r+##H) H*!ever, neither *9 the#e architecture# #peak# t* h*! the pr*gra+ #h*uld #tructure the creati*n *9 3u#ine## value G!hat g*e# *n in the IA*delJ *r I=3#tracti*nJ part# *9 ACC and P=C re#pectivelyH)

'i#ulation )rchitectures, )lwa5s -aught. 6arel5 >sed


Aany pe*ple are taught that *34ect *riented #y#te+# #h*uld 3e #tructured t* c*n9*r+ t* *34ect# in the pr*3le+ d*+ain, an architectural pattern !e c*uld call Si+ulati*n) There i# certainly hi#t*rical precedent 9*r thi#1 *34ect *riented pr*gra++ing !a# in 9act invented in re#p*n#e t* the need# *9 #i+ulati*n pr*gra++ing) Un9*rtunately, *ut#ide *9 vide* ga+e# and certain type# *9 +*deling, Si+ulati*n i# n*t generally a u#e9ul architecture) ,hyF ,ell, 3ecau#e the 3u#ine## intere#t# *9 +*#t c*+panie# are u#ually 9*cu#ed *n tran#acti*n# driven 3y n*nEdeter+ini#tic 9*rce# Gi)e), pe*pleH and it 4u#t d*e#nt d* +uch 9*r the 3*tt*+ line t* try t* recreate th*#e 9*rce# in#ide the c*+puter #y#te+) =+a7*n# *rdering #y#te+ pr*3a3ly ha# a Boo( cla##, and +ay3e an 'uthor cla##, 3ut -ll !ager it d*e#nt have an 1prah cla##, n* +atter h*! +uch the talkE#h*! h*#t# rec*++endati*n# in9luence purcha#er#) Si+ulati*n architecture# tend t* e;e+pli9y the c*ncept *9 c*he#i*n, th*ugh) C*he#i*n i# the a+*unt *9 c*n#i#tency and c*+pleti*n in a cla## *r na+e#pace, the a+*unt 3y !hich a cla## *r na+e#pace Ihang# t*gether)J -n their pr*per d*+ain, #i+ulati*n# tend t* have great c*he#i*n1 !hen y*uve g*t a !lant *34ect and an 'nimal *34ect, it# pretty ea#y t* 9igure *ut !here t* put y*ur photosynthesis() +eth*d) Si+ilarly, !ith cla##e# derived 9r*+ real !*rld n*un#, *ne d*e#nt *9ten have Ic*incidental c*he#i*nJ !here a cla## c*ntain# +ultiple, c*+pletely unrelated inter9ace#)

Cha"ter 5* >iding the Im"lementation

)1'

Client?'erver and n;-ier )rchitectures


,hen c*rp*rate net!*rk# 9ir#t 3eca+e u3iDuit*u# in the early 066$#, there !a# a great deal *9 e;cite+ent a3*ut the p*##i3ility *9 e;pl*iting the de#kt*p c*+puter# CPU p*!er and di#play characteri#tic#, !hile +aintaining data integrity and #ecurity *n +*re c*ntr*lla3le #erver#) Thi# client<#erver architecture Duickly 9ell *ut *9 9av*r a# client #*9t!are turned *ut t* 3e c*#tly t* devel*p and di99icult t* keep in #ync !ith changing 3u#ine## rule#) Client<Server !a# replaced !ith /ETier and nETier =rchitecture#, !hich divide the !*rld int* / c*ncern#1 a pre#entati*n layer at the client, *ne *r +*re 3u#ine## rule# layer# that Irun any!hereJ G3ut u#ually *n a #erverH, and a per#i#tence *r data3a#e layer that de9initely run# *n a #erver, 3ut perhap# n*t the #a+e +achine# that run the 3u#ine## rule# layer#) Originally p*pular 9*r c*rp*rate devel*p+ent, the d*tEc*+ e;pl*#i*n entrenched the nETier =rchitecture a# the +*#t c*++*n #y#te+ architecture in devel*p+ent t*day) ,e3 Service#, !hich !ell di#cu## in +*re detail in Chapter #,e3 Service##, are nE Tier =rchitecture# !here the c*++unicati*n 3et!een layer# i# d*ne !ith BAL *ver ,e3 pr*t*c*l# #uch a# SO=P, HTTP, and SATP) -n thi# architecture, all the intere#ting #tu99 happen# in the 3u#ine##Erule tier#, !hich are typically architected in a u#eEca#eEcentric +anner) IC*ntr*lJ cla##e# repre#ent the creati*n *9 3u#ine## value, !hich i# u#ually de9ined in ter+# *9 a u#eEca#e, an at*+ic u#e *9 the #y#te+ that deliver# value t* the cu#t*+er) The#e C*ntr*l *34ect# interact !ith *34ect# that repre#ent enduring 3u#ine## the+e# G#uch a# Sale#, Service, and L*yaltyH, 9inancial tran#acti*n# G#uch a# -nv*ice#, =cc*unt# Receiva3le and Paya3le, and Ta;e#H, regulat*ry c*n#traint#, and 3u#ine## #trategie#) Cla##e# that +ap int* n*un# in the real !*rld are 9e! and 9ar 3et!een) The the+e *9 #uch 3u#ine##Etier architecture# i# Ii#*lating the vect*r# *9 change)J The g*al i# t* create cla##e# 3a#ed n*t *n a +apping t* realE!*rld n*un# 3ut t* pattern# *9 3ehavi*r *r #trategy that are likely t* change *ver ti+e) 5*r in#tance, a retail 3u#ine## i# likely t* have #*+e c*ncept *9 a St*ck Neeping Unit P a pr*duct in a particular c*n9igurati*n !ith a certain +anu9acturer, de#cripti*n, and #* 9*rth P 3ut +ay have +any di99erent #trategie# 9*r pricing) -n a typical 3u#ine##Etier architecture, thi# +ight lead t* the creati*n *9 cla##e# #uch a# #toc(EeepingVnit, .anufacturer , and an inter9ace 9*r !ricing#trategy i+ple+ented 3y &veryday!rice, #ale!rice, *r Clearance!rice) The Ivect*r *9 changeJ in thi# ca#e i# the !ricing#trategy, !hich i# +anipulated 3y a c*ntr*l *34ectQ 9*r in#tance, an *34ect !hich l*!er# price# !hen a #toc(EeepingVnit i# di#c*ntinued1

))(

Thinking in C

www.ThinkingIn.!et

Thi# de#ign 9rag+ent i# typical *9 the type# *9 #tructure# *ne #ee# in 3u#ine##Etier architecture#1 u#eEca#e# are rei9ied Ga 9ancy !*rd 9*r Iin#tantiated a# *34ect#JH, there i# e;ten#ive u#e *9 the Strategy pattern, and there are l*t# *9 cla##e# !hich d* n*t +ap t* tangi3le *34ect# in the real !*rld) The 3u#ine## rule I,hen a pr*duct i# di#c*ntinued 3y it# +anu9acturer, place it *n #ale until !e have le## than a d*7en in invent*ry, then price it 9*r clearance,J +ight l**k like thi# in c*de1 c a## C ear:i#continued5te!#; #tatic readon y int G5CXB+HOR+XCL+)R)CC+ 9 "23 :i#continued0Stoc%aeepingOnitJK ine1; foreach0Stoc%aeepingOnit #%u in ine1; int count 9 #tore5n*entory.Count0 ine13 if0count W G5CXB+HOR+XCL+)R)CC+1; #%u.-ricingStrategy 9 ne. C earance-rice013 <e #e; #%u.-ricingStrategy 9 ne. Sa e-rice013 < < < < -n a Si+ulati*n architecture, a #toc(EeepingVnit !*uld price it#el9 !hen di#c*ntinued1 c a## Stoc%aeepingOnit; //... #tatic int nu!$er5nStoc%3 #tatic readon y int G5CXB+HOR+XCL+)R)CC+ 9 "23

Cha"ter 5* >iding the Im"lementation

))1

:i#continue01; if0nu!$er5nStoc% W G5CXB+HOR+XCL+)R)CC+1; thi#.-ricingStrategy 9 ne. C earance-rice013 <e #e; thi#.-ricingStrategy 9 ne. Sa e-rice013 < < < =# can 3e #een in thi# de#ign 9rag+ent, 3u#ine##Etier architecture# tend t* l**k le## c*he#ive than #i+ulati*n architecture# 9*r #+all pr*3le+#) -n realE!*rld applicati*n#, th*ugh, there are typically d*7en# *r hundred# *9 u#eEca#e#, each *9 !hich +ay have #everal 3u#ine## rule# a##*ciated !ith it) Bu#ine## rule# tend t* inv*lve a l*t *9 di99erent 9act*r# and yet are the natural unit *9 th*ught 9*r the d*+ain e;pert#, #* 3u#ine##Etier architecture# tend t* re#ult in clearer line# *9 c*++unicati*n 3et!een devel*p+ent tea+# and d*+ain e;pert#) I,e need t* a#k a Due#ti*n a3*ut the Tprice di#c*ntinued ite+# 3u#ine## rule#J i# +uch clearer t* d*+ain e;pert# than I,e need t* a#k a Due#ti*n a3*ut h*! an SNU price# it#el9 !hen it# di#c*ntinued)J

La5ered )rchitectures
Once up*n a ti+e, c*+puter# !ere pri+arily u#ed t* aut*+ate repetitive calculati*n#1 tide chart#, gunnery ta3le#, cen#u# #tati#tic#) *!aday#, CPUEinten#ive +ath i# *ne *9 the lea#t 9reDuent ta#k# a#ked *9 a c*+puter) - i+agine there are +any y*unger pe*ple !h* d*nt kn*! that, e##entially, c*+puter# are n*thing 3ut 3inary calculat*r#) Thi# i# 3ecau#e layer a9ter layer *9 increa#ing a3#tracti*n ha# 3een placed 3et!een the endEu#er and the underlying hard!are) -+ n*t #ure thi# i# entirely 3ene9icial !hen it c*+e# t* pr*gra++ing, 3ut - certainly d*nt !ant t* g* 3ack t* the day# !hen the 3ig trick in graphic# pr*gra++ing !a# d*ing y*ur !*rk !hen the #creen !a# d*ing a vertical retrace) Layer# *9 a3#tracti*n are a+*ng the +*#t p*!er9ul architecture# *ver the l*ng ter+, re+*ving entire area# 9r*+ the c*ncern# *9 later pr*gra++er#) Layered architecture# are c*++*nly u#ed !hen i+ple+enting pr*t*c*l#, #ince pr*t*c*l# the+#elve# have a tendency t* 3e layered *n t*p *9 *ther pr*t*c*l#) Layer# are al#* u3iDuit*u# !hen !*rking !ith device driver# *r e+3edded #y#te+# Gn*t likely #cenari*# 9*r C# t*day, 3ut !h* kn*!# !hat t*+*rr*! h*ld#FH) The three place# !here - can anticipate a C# tea+ l**king t*!ard# layered architecture# are in the area# *9 *34ectErelati*nal +apping, c*ncurrent li3rarie#, and net!*rk c*++unicati*n#) The 9ir#t t!* are area# !here the ) ET 9ra+e!*rk d*e# n*t pr*vide #u99icient a3#tracti*n and the la#t i# a 9a#tE+*ving area !here C# ha# the p*tential t* really #hine) Layered architecture# al!ay# #ee+ t* 3e di99icult t* get right) -n a layered architecture, all cla##e# in a layer #h*uld #hare the #a+e a3#tracti*n layer, and each layer #h*uld 3e a3le t* per9*r+ all it# 9uncti*n# 3y *nly relying *n it# *!n cla##e# and

)))

Thinking in C

www.ThinkingIn.!et

th*#e *9 the layer i++ediately I3el*!J it) Pulling thi# *99 reDuire# a +*re c*+plete under#tanding *9 the pr*3le+ d*+ain than i# typically availa3le in the early #tage# *9 #y#te+ devel*p+ent, !hen architecture i# decided) S* u#ually !ith a layered architecture, y*u 9ace t!* p*##i3ilitie#1 a l*t *9 up9r*nt e99*rt *r 3eing very c*n#cienti*u# a3*ut +*ving *34ect# and re9act*ring 3a#ed *n a3#tracti*n level) The great 3ene9it# *9 a layered architecture c*+e d*!n the line !hen an under#tanding *9 the !*rking *9 the l*!er level# i# rarely *r never needed) Thi# i# the #ituati*n t*day !ith, #ay, graphic#, !here n* *ne 3ut ga+e pr*gra++er# need c*ncern the+#elve# !ith the c*+ple; detail# *9 #creen +*de#, pi;el a#pect#, and di#play page# Gand !ith +*dern ga+e engine# 3uilt *n ?irectB and the prevalence *9 graphic# accelerat*r card#, apparently even ga+e pr*gra++er# are +*ving a!ay 9r*+ thi# level *9 detailH)

Pro+le#;'olving )rchitectures
-t# increa#ingly rare t* devel*p a #y#te+ that #*lve# a pr*3le+ that i# *ther!i#e intracta3le) Thi# i# t** 3ad, 3ecau#e there are 9e! thrill# greater than devel*ping a t**l and !atching that t**l acc*+pli#h #*+ething 3ey*nd y*ur capa3ilitie#) Such #y#te+# *9ten reDuire the devel*p+ent *9 #peciali7ed pr*3le+E#*lving architecture# EE 3lack3*ard #y#te+#, 9uncti*n *pti+i7er#, 9u77y l*gic engine#, #upp*rtEvect*r +achine#, and #* 9*rth) The#e pr*3le+ #*lver# +ay the+#elve# 3e architected in any nu+3er *9 !ay#, #* in a #en#e y*u c*uld #ay that thi# i# a variati*n *9 the layered architecture, !here the pr*3le+E#*lver i# a 9*undati*n *n !hich the input# and +etaE3ehavi*r rely) But t* #*lve a pr*3le+ u#ing, #ay, a genetic *pti+i7er *r e;pert #y#te+ reDuire# an under#tanding *9 the characteri#tic# *9 the pr*3le+E#*lver, n*t #* +uch an under#tanding *9 the !ay that the pr*3le+E#*lver i# i+ple+ented) S* i9 y*ure 9*rtunate en*ugh t* 3e !*rking in #uch a d*+ain, y*u #h*uld c*ncentrate *n under#tanding the c*re alg*rith+# and #eeing i9 there# a di#c*nnect 3et!een the acade+ic !*rk *n the pr*3le+E#*lver and the ta#k at handQ +any #uch pr*4ect# 9ail 3ecau#e the pr*3le+E#*lver reDuire# that the input *r +etaEdata have a certain +athe+atical characteri#tic) =# an *34ect le##*n, re#earch *n arti9icial neural net!*rk# langui#hed 9*r +*re than a decade 3ecau#e the *riginal !*rk u#ed a di#c*ntinu*u# Iactivati*n 9uncti*n)J Once #*+e*ne reali7ed the +athe+atical pr*3le+ !ith that, a 9a+*u# Ipr**9J *9 their li+itati*n# 9ell 3y the !ay#ide and neural net# 3eca+e *ne *9 the h*tte#t re#earch t*pic# in +achine learningK

4is$atching )rchitectures
=n a+a7ingly large a+*unt *9 value can 3e derived 9r*+ #y#te+# that +anage the 9l*! *9 in9*r+ati*n !ith*ut a great deal *9 interacti*n !ith the underlying data) The#e #y#te+# typically deal !ith the general pr*3le+ *9 e99iciently +anaging the 9l*! 9r*+ +ultiple, unkn*!nEatEc*+pilati*nEti+e #*urce# *9 data !ith +ultiple, unkn$!nEatEc*+pilati*nEti+e #ink# 9*r data) IE99icientlyJ i# #*+eti+e# +ea#ured in ter+# *9 #peed, #*+eti+e# in ter+# *9 re#*urce#, and #*+eti+e# in ter+# *9

Cha"ter 5* >iding the Im"lementation

))3

relia3ility) S*+eti+e# the c*nnecti*n# are tran#ient, in !hich ca#e the architecture# are u#ually called Ievent drivenJ and #*+eti+e# the c*nnecti*n# are l*ngerEla#ting, in !hich ca#e +ultiple;ing and de+ultiple;ing architecture# are c*++*nly u#ed) ?i#patching #*luti*n# tend t* 3e relatively #+all and can #*+eti+e# 3e #een a# de#ign ele+ent#, n*t the architectural *rgani7ing principle 9*r an entire #y#te+ *r #u3#y#te+) But they *9ten play #uch a crucial r*le in delivering value that they de#erve the greate#t e+pha#i# in a #y#te+# devel*p+ent)

G(ot 6eall5 O+/ect;OrientedH


One *9 the +*#t c*++*n critici#+# that y*ull hear a3*ut a piece *9 #*9t!are i# that, alth*ugh it# !ritten !ith an *34ectE*riented language, Iit# n*t really *34ect *riented)J There are t!* r**t cau#e# 9*r thi# critici#+, *ne *9 !hich i# #eri*u# and !*rth critici7ing, and *ne *9 !hich 3etray# a lack *9 under#tanding *n the part *9 the critici7er) The 9riv*l*u# critici#+ c*+e# 9r*+ th*#e !h* +i#takenly 3elieve that Si+ulati*n architecture# are the *nly valid *rdering principle 9*r *34ectE*riented #y#te+#) Each architecture ha# it# #trength# and !eakne##e# and !hile Si+ulati*n architecture# have hi#t*rical tie# !ith *34ect *rientati*n, they arent the 3e#t ch*ice in +any, +ay3e +*#t, realE!*rld devel*p+ent e99*rt#) There are +any +*re architecture# than have 3een di#cu##ed hereQ !eve 4u#t t*uched *n #*+e *9 the +*re p*pular *ne#) The #eri*u# critici#+, the thing that +ake# t** +any #y#te+# In*t really *34ect *rientedJ i# l*!Elevel de#ign that d*e#nt u#e *34ectE*riented 9eature# t* i+pr*ve the Duality *9 the #*9t!are #y#te+) There are +any di99erent type# *9 Duality1 #peed *9 e;ecuti*n, +e+*ry *r re#*urce e99iciency, ea#e *9 integrati*n !ith *ther c*de, reu#a3ility, r*3u#tne##, and e;ten#i3ility Gt* na+e 4u#t a 9e!H) The +*#t i+p*rtant +ea#ure *9 #*9t!are Duality, th*ugh, i# the e;tent t* !hich y*ur #*9t!are can 9ul9ill 3u#ine## g*al#, !hich u#ually +ean# the e;tent t* !hich the #*9t!are 9ul9ill# u#er need# *r the #peed !ith !hich y*u can react t* ne!ly di#c*vered u#er need#) Since there# n*thing y*u can d* a3*ut the 9*r+er, the c*nclu#i*n i# Ithe +*#t i+p*rtant thing y*u can d* i# u#e *34ectE*riented 9eature# t* i+pr*ve the #peed !ith !hich y*u can react t* ne!ly di#c*vered u#er need#)J

4esign Is )s 4esign 4oes


The endEu#er ha# n* intere#t in y*ur #*9t!are# de#ign) They care that y*ur #*9t!are help# the+ d* their 4*3 ea#ier) They care that y*ur #*9t!are d*e#nt irritate the+) They care that !hen they talk t* y*u a3*ut !hat they need 9r*+ the #*9t!are, y*u li#ten and re#p*nd #y+pathetically Gand in Engli#h, n*t >eekH) They care that y*ur #*9t!are i# cheap and relia3le and r*3u#t) Other than that, they d*nt care i9 it# !ritten in a##e+3ly language, L-SP, C#, *r 5ORTR= , and they #ure a# #h**ting d*nt care a3*ut y*ur cla## and #eDuence diagra+#)

))4

Thinking in C

www.ThinkingIn.!et

S* there# really nothing that +atter# a3*ut de#ign e;cept h*! ea#y it i# t* change *r e;tend P the thing# that y*u have t* d* !hen y*u di#c*ver that y*ur e;i#ting c*de 9all# #h*rt in #*+e +anner) S* h*! d* y*u de#ign 9*r changeF

7irst. 4o (o 9ar#
-t# accepta3le 9*r y*u t* decide n*t t* +ake a change) -t# accepta3le 9*r y*ur change t* turn *ut t* 3e le## help9ul t* the u#er than the *riginal) -t# accepta3le 9*r y*ur change t* 3e dead !r*ng, either 3ecau#e *9 +i#c*++unicati*n *r 3ecau#e y*ur 9inger# #lipped *n the key# and typed a plu# in#tead *9 a +inu#) ,hat i# unaccepta3le i# 9*r y*u t* c*++it a change that 3reak# #*+ething el#e in y*ur c*de) =nd it i# unaccepta3le 9*r y*u t* n*t kn*! i9 y*ur change 3reak# #*+ething el#e in the c*de) :et #uch a path*l*gical #tate, !here the *nly thing that devel*per# can #ay a3*ut their c*de i# a pathetic I,ell, it shouldn:t cau#e anything el#e t* change,J i# very c*++*n) =l+*#t a# c*++*n are #ituati*n# !here change# d*, in 9act, #ee+ t* rand*+ly a99ect the 3ehavi*r *9 the #y#te+ a# a !h*le) -t i# c*unterintuitive, 3ut the nu+3er *ne thing y*u can d* t* #peed up y*ur devel*p+ent #chedule i# t* !rite a l*t *9 te#t#) -t d*e#nt pay *99 in the 9ir#t day#, 3ut it pay# *99 in 4u#t a 9e! !eek#) By the ti+e y*u get #everal +*nth# int* a pr*4ect, y*u !ill 3e +adly in l*ve !ith y*ur te#ting #uite) Once y*u devel*p a #y#te+ !ith a pr*per #uite *9 te#t#, y*u !ill c*n#ider it inc*+petent 9**li#hne## t* devel*p !ith*ut *ne) ,ith +*dern language# that #upp*rt re9lecti*n, it ha# 3ec*+e p*##i3le t* !rite te#t in9ra#tructure #y#te+# that di#c*ver at runti+e !hat +eth*d# are te#t# G3y c*nventi*n, +eth*d# that 3egin !ith the #tring Ite#tJH and running the+ and rep*rting the re#ult#) The pred*+inant #uch #y#te+ i# "Unit, created 3y Nent Beck and Erich >a++a) Several p*rt# and re9act*ring# *9 "Unit 9*r ) ET language# are availa3le, the +*#t p*pular *9 !hich i# Philip Craig# Unit) :*u can d*!nl*ad Unit 9r*+ http1<<nunit)#*urce9*rge)net) Unit i# a #traight9*r!ard p*rt *9 "Unit and d*e# n*t e;pl*it C# *r ) ET 9eature# #uch a# attri3ute#, !hich +ight 3e u#ed t* create ne! 9eature# G#uch a# 9iner c*ntr*l *9 !hich te#t# are applied t* a +eth*d *r cla##H)

S*9t!are #y#te+# are a+*ng the +*#t c*+ple; #tructure# 3uilt 3y hu+an#, and unintended c*n#eDuence# are an inevita3le part *9 +anipulating th*#e #y#te+#) The #peed !ith !hich y*u can change a #*9t!are #y#te+ i# dependent *n +any thing#, 3ut *n n*thing #* +uch a# y*ur a3ility t* i#*late a change in 3*th )

Cha"ter 5* >iding the Im"lementation

))5

4esign 6ule #1, Write 3oring Code


5*r in#tance, let# #ay that y*u !ant t* prepare y*ur h*u#e 9*r vacati*n 3y canceling the +ail and turning *n the aut*+atic #prinkler in the garden) -t #ee+# l*gical that y*ud d* thi# in a +eth*d "ouse6Hacation!rep()1 //W+xa!p eZ //WC a##ZNacation".c#W/C a##Z na!e#pace Nacation"; c a## Uou#e ; Gai !yGai 9 ne. Gai 013 _arden !y_arden 9 ne. _arden013 pu$ ic *oid Nacation-rep01 ; Sy#te!.Con#o e.VriteLine0&-reparing the hou#e for *acation&13 Sy#te!.Con#o e.VriteLine0&Stopping the !ai &13 !yGai .)cti*e 9 fa #e3 Sy#te!.Con#o e.VriteLine0&Setting the auto!atic #prin%er&13 !y_arden.Sprin% erSet 9 true3 Sy#te!.Con#o e.VriteLine0&Uou#e i# prepared&13 < pu$ ic #tatic *oid Gain01 ; Uou#e !yUou#e 9 ne. Uou#e013 !yUou#e.Nacation-rep013 < < c a## Gai ; $oo acti*e3 pu$ ic $oo )cti*e; get ; return acti*e3< #et ; acti*e 9 *a ue3< < < c a## _arden ; $oo #prin% erOn3 pu$ ic $oo Sprin% erSet; get ; return #prin% erOn3< #et ; #prin% erOn 9 *a ue3< < < <

))6

Thinking in C

www.ThinkingIn.!et

//W/+xa!p eZ There# n*thing !r*ng !ith thi# c*de a# it #tand#, "ouse6Hacation!rep() i# c*he#ive and n*t c*+ple;) But y*ur u#er c*+e# t* y*u and #ay# IOh, gee, !e *nly !ant t* deactivate the +ail i9 the vacati*n i# g*ing t* 3e l*nger than / day#)J ,hat d* y*u d*F The Duicke#t thing t* d* i# change H*u#e)Cacati*nPrepGH t*1 pu$ ic *oid Nacation-rep0int ength1 ; Sy#te!.Con#o e.VriteLine0&-reparing the hou#e for *acation&13 if0 ength Z T1; Sy#te!.Con#o e.VriteLine0&Stopping the !ai &13 !yGai .)cti*e 9 fa #e3 < Sy#te!.Con#o e.VriteLine0&Setting the auto!atic #prin%er&13 !y_arden.Sprin% erSet 9 true3 Sy#te!.Con#o e.VriteLine0&Uou#e i# prepared&13 < But a# #**n a# y*u type that, y*u !*rry a3*ut the I+agic nu+3erJ / in the c*de) Aagic nu+3er# are anathe+a t* +any pr*gra++er#, #* +uch #* that I?=:S`- ` ,EENJ i# +*re c*++*n than I%JK 5anatici#+ a#ide, +agic nu+3er# are a c*de #+ell that indicate# #*+e re9act*ring +ight 3e called 9*r) S* in#tead *9 I/J y*u +ight !ant !rite the c*de a# if0 ength Z !in:ay#HorGai Stoppage1 3ut that in#tantly rai#e# the Due#ti*n *9 !here t* de9ine that varia3le) :*u +ight de9ine it at the t*p *9 the Hacation!rep() +eth*d, 3ut that hardly acc*+pli#he# anything) = p**r pr*gra++er +ight +ake it a read*nly varia3le in#ide H*u#e, 3ut +*#t !*uld place it in#ide .ail, thu#1 pu$ ic *oid Nacation-rep0int ength1 ; if0 ength Z Gai .!in:ay#HorGai Stoppage ; Sy#te!.Con#o e.VriteLine0&Stopping the !ai &13 !yGai .)cti*e 9 fa #e3 < LetcL and c a## Gai ; #tatic readon y int G5CX:)/SXHORXS'O- 9 T3 pu$ ic int !in:ay#HorStoppage; get ; return G5CX:)/SXHORXS'O-3 < < LetcL "ouse6Hacation!rep() i# #till accepta3ly c*he#ive, alth*ugh it# increa#ed in c*+ple;ity) S* n*! y*ur u#er c*+e# t* y*u and #ay# I,ell, !e *nly !ant t* turn *n the #prinkler i9 the vacati*n i# during the gr*!ing #ea#*n) =nd i9 it# during the !inter, !e need t*

Cha"ter 5* >iding the Im"lementation

))#

3ring the plant# in#ide, in ca#e there# a 9r*#t)J -9 pr*gra++ing !ere a linear pr*ce##, y*ud 9*ll*! the #a+e pattern y*u did 9*r the +ail #t*ppage rule and y*u +ight end up !ith1 //W+xa!p eZ //WC a##ZNacationT.c#W/C a##Z u#ing Sy#te!3 na!e#pace Nacation"; c a## Uou#e ; Gai !yGai 9 ne. Gai 013 _arden !y_arden 9 ne. _arden013 pu$ ic *oid Nacation-rep0:ate'i!e #tart:ate2 int ength1 ; Sy#te!.Con#o e.VriteLine0&-reparing the hou#e for *acation&13 if0 ength Z Gai .!in:ay#BeforeStoppage1; Sy#te!.Con#o e.VriteLine0&Stopping the !ai &13 !yGai .)cti*e 9 fa #e3 < int !onth 9 #tart:ate.Gonth3 Sea#on #ea#on 9 _arden.Sea#onHor0!onth13 #.itch0#ea#on1; ca#e Sea#on._ro.ingSea#on : Sy#te!.Con#o e.VriteLine0&Setting the auto!atic #prin%er&13 !y_arden.Sprin% erSet 9 true3 $rea%3 ca#e Sea#on.Vinter : Sy#te!.Con#o e.VriteLine0&Bringing the p ant# in#ide&13 foreach0- ant p in !y_arden.- ant#1; if0p.Out#ide1; p.Bring5n#ide013 < < $rea%3 defau t: Sy#te!.Con#o e.VriteLine0&Lea*ing the garden a one&13 $rea%3 < Sy#te!.Con#o e.VriteLine0&Uou#e i# prepared&13 < pu$ ic #tatic *oid Gain01 ; Uou#e !yUou#e 9 ne. Uou#e013 !yUou#e.Nacation-rep0:ate'i!e.Co.2 E13

))&

Thinking in C

www.ThinkingIn.!et

< < c a## Gai ; #tatic readon y int G5CX:)/SXB+HOR+XS'O--)_+ 9 T3 pu$ ic #tatic int !in:ay#BeforeStoppage; get ; return G5CX:)/SXB+HOR+XS'O--)_+3 < < $oo acti*e3 pu$ ic $oo )cti*e; get ; return acti*e3< #et ; acti*e 9 *a ue3< < < c a## _arden ; $oo #prin% erOn3 pu$ ic $oo Sprin% erSet; get ; return #prin% erOn3< #et ; #prin% erOn 9 *a ue3< < - antJK p ant# 9 ne. - antJK; ne. _eraniu!012 ne. Hicu#01 <3 pu$ ic - antJK - ant#; get ; return p ant#3 < < pu$ ic #tatic Sea#on Sea#onHor0int !onth1; if0!onth Z9 T @@ !onth W9 "01 return Sea#on._ro.ingSea#on3 if0!onth 99 "01 return Sea#on.:or!ant3 return Sea#on.Vinter3 < < enu! Sea#on; _ro.ingSea#on2 :or!ant2 Vinter < c a## - ant; protected $oo i#Out#ide 9 true3

pu$ ic $oo Out#ide; get ; return i#Out#ide3 < #et ; i#Out#ide 9 *a ue3 < <

Cha"ter 5* >iding the Im"lementation

))'

pu$ ic *oid Bring5n#ide01; Sy#te!.Con#o e.VriteLine0&Bringing a p ant in#ide&13 thi#.Out#ide 9 fa #e3 < < c a## _eraniu! : - ant; < c a## Hicu# : - ant; pu$ ic Hicu#01; thi#.Out#ide 9 fa #e3 < < < *!, "ouse6Hacation!rep() i# pa##ed 3*th a length and a #tarting date) -t deter+ine# the +*nth *9 the vacati*n, u#e# arden6#eason:or(int month) t* deter+ine in !hat Sea#*n the vacati*n !ill happen, and take# the nece##ary #tep# depending *n that) =# a pr*cedural +eth*d, Hacation!rep() !*uld #till 3e c*n#idered 9airly c*he#ive) Everything it d*e# ha# #*+ething t* d* !ith preparing the h*u#e 9*r vacati*n, it# 4u#t turning *ut t* 3e a +*re c*+ple; ta#k than it !a# *n *ur 9ir#t iterati*n) But 9r*+ an *34ect #tandp*int, #*+ething# g*ne a!ry) The +*#t egregi*u# pr*3le+ i# clearly the call in#ide the c*nditi*nal in#ide the l**p in#ide the #!itch) Oh, - need t* e;plain !here that i#F That# part *9 the pr*3le+ P deeply ne#ted c*ntr*l #tructure# are inherently c*+ple;) -+ re9erring t* the#e line#1 if0p.Out#ide1; p.Bring5n#ide013 < The e;ecuti*n *9 thi# 3l*ck i# 3a#ed *n the #tate *9 a re9erenced *34ect Gthe !lant pH, 3ut the 3l*ck *nly c*ntain# call# t* that #a+e *34ect) -n *ther !*rd#, 3*th the Iguard c*nditi*nJ and the c*n#eDuence are !*rking *n e;ternal *34ect#) =lth*ugh *ne c*uld argue that "ouse6Hacation!rep() i# #till 9airly c*he#ive, thi# 3l*ck indicate# that !lant6BringBnside() i# n*t c*he#ive, 3ecau#e it d*e# n*t c*ntain the l*gically nece##ary check t* +ake #ure that *nly plant# that are currently *ut#ide are 3r*ught in#ide) Thu#, !ell change !lant6BringBnside() t*1 pu$ ic *oid Bring5n#ide5fCece##ary01; if0thi#.Out#ide1; Sy#te!.Con#o e.VriteLine0&Bringing a p ant in#ide&13 thi#.Out#ide 9 fa #e3 < < S*+ething# !r*ng !ith thi#) = #ingle +eth*d !hich d*e# +*re than *ne thing i# *ne type *9 c*he#i*n +i#take, t!* +eth*d# that d* e##entially the #a+e thing i# an*ther) The pu3lic 1utside pr*perty *9 !lant ha# a set +eth*d) Our ne!ly !ritten BringBnsideBf,ecessary() d*e# n*thing that i#nt l*gically d*ne in#ide that set )3( Thinking in C www.ThinkingIn.!et

+eth*d, !ith the e;cepti*n *9 printing #*+ething t* the C*n#*le) -9 the di#tincti*n 3et!een printing t* the c*n#*le *r n*t i# i+p*rtant, then +ay3e !e c*uld u#e a para+eter The #a+e pe*ple !h* +i#takenly 3elieve that Si+ulati*n architecture# are the *nly ItrueJ *34ectE*riented architecture# !ill #ay that thi# c*de i# already !r*ng) They !ill, very predicta3ly, dra! thi# diagra+1

and !rite thi# c*de1 //W+xa!p eZ //WC a##ZNacation2.c#W/C a##Z na!e#pace Nacation2; interface 5-repara$ e; *oid Nacation-rep013 < c a## Uou#e : 5-repara$ e; 5-repara$ eJK !y-repara$ e# 9 ; ne. Gai 012 ne. _arden01 <3 pu$ ic *oid Nacation-rep01 ; Sy#te!.Con#o e.VriteLine0&-reparing the hou#e for *acation&13 foreach05-repara$ e p in !y-repara$ e#1; p.Nacation-rep013 < Sy#te!.Con#o e.VriteLine0&Uou#e i# prepared&13 < pu$ ic #tatic *oid Gain01 ; Uou#e !yUou#e 9 ne. Uou#e013 !yUou#e.Nacation-rep013 Cha"ter 5* >iding the Im"lementation )31

< < c a## Gai : 5-repara$ e; $oo acti*e3 pu$ ic $oo )cti*e; get ; return acti*e3< #et ; acti*e 9 *a ue3< < pu$ ic *oid Nacation-rep01; Sy#te!.Con#o e.VriteLine0&Gai it#e f&13 thi#.acti*e 9 fa #e3 < < c a## _arden : 5-repara$ e ; $oo #prin% erOn3 pu$ ic $oo Sprin% erSet; get ; return #prin% erOn3< #et ; #prin% erOn 9 *a ue3< < pu$ ic *oid Nacation-rep01; Sy#te!.Con#o e.VriteLine0&_arden turning on the #prin% er&13 #prin% erOn 9 true3 < < < //W/+xa!p eZ There# n*thing !r*ng !ith the c*de in "ouse6Hacation!rep() P it# c*he#ive and it# n*t c*+ple;) There# n* rea#*n, at thi# p*int, t* deacti*ating

S*+eti+e in y*ur career, y*ure g*ing t* !*rk *n a pr*4ect !here every ti+e y*u +ake a change, it cau#e# #*+ething el#e t* 3reak) -t !ill 3e a +i#era3le, #*ulE deadening and inter+ina3le peri*d) -t !ill eventually end, 3ut *nly 3ecau#e the c*+pany cancel# the pr*4ect *r g*e# 3ankrupt) The#e terri3le e;perience# *ccur 3ecau#e it i# i+p*##i3le t* i#*late a change) There i# *nly *ne p*##i3le cau#e 9*r thi#1 the area y*u are atte+pting t* change i# cou"led !ith an*ther area *9 the pr*gra+) Okay, there# a #+allE3utE9inite p*##i3ility that the pr*3le+ i# cau#ed 3y an underlying *perating #y#te+ *r hard!are 9la! that# triggered 3y #*+e n*nEpr*gra++atic a#pect *9 the !*rk y*ure d*ing G#uch 9la!# are

)3)

Thinking in C

www.ThinkingIn.!et

pr*perly called I3ug#J and +*#t pr*gra++er# enc*unter the+ a c*uple *9 ti+e# per decade) Pr*gra++atic +i#take# are called Ide9ect#J and happen, *h, a3*ut t!enty ti+e# per dayH) C*upling, *r dependence, i# the degree t* !hich a +eth*d *r cla## relie# *n *ther +eth*d# *r cla##e# t* acc*+pli#h it# ta#k) C*upling l*!er# +eth*d c*+ple;ity G3y relying *n #*+ething el#e t* d* a calculati*nH, 3ut increa#e# de#ign c*+ple;ity) C*upling ha# a c*+ple; relati*n#hip !ith c*he#i*n) = c*he#ive +eth*d d*e# *ne and *nly *ne pr*ce##, a c*he#ive cla## encap#ulate# l*gically related 3ehavi*r and data) 5*r all 3ut the rare#t cla##e#, the Iand *nly *neJ and Il*gically relatedJ c*n#traint# reDuire the u#e *9 *ther cla##e#) S* #plitting a #ingle ta#k int* t!* +ay increa#e 3*th c*herence and c*upling and 3e *9 unargua3le 3ene9it) H*!ever, #plitting and reE #plitting Gand reEreE#plittingH a ta#k !ill *9ten 3ack9ire due t* c*nte;t de+and#)

he #eri*u# pr*3le+ !ith +uch #*9t!are i# the prevalence *9 large +eth*d# that rely *n deeply ne#ted l**p# and c*nditi*nal# 9*r 9l*! c*ntr*l) >**d +eth*d# #h*uld 3e #* #traight9*r!ard that they reDuire n* internal c*++ent#) 5*r in#tance1 Co#t tota -rice0-roductJK product#1; Co#t #u! 9 ne. Co#t013 foreach0-roduct p in product#1; #u! R9 p.Co#t3 < return #u!3 < Thi# +eth*d #till need# +eth*d d*cu+entati*n P that it d*e#nt apply ta;e#, that it +ay return a C*#t !h*#e value i# $ Ga##u+ing that# h*! the C*#tGH c*n#truct*r initiali7e#H i9 the pr*duct# para+eter i# e+pty, perhap# even that it reDuire# pr*duct# t* 3e n*nEnull Galth*ugh it# 3etter t* a##u+e that all +eth*d# thr*! a ullRe9erenceE;cepti*n !hen pa##ed any null para+eter# and d*cu+ent !hen that isn:t the ca#eH) But it d*e#nt need internal c*++ent# GI-nitiali7e a C*#t *34ect called T#u+ that !ill h*ld the re#ult#JF Plea#eKH) -nternal c*++ent# are *nly needed !hen y*ur c*de i# c*+ple;) ?*nt !rite c*+ple; c*de) ,rite 3*ring c*de that #*lve# intere#ting pr*3le+#) Cycl*+atic c*+ple;ity, the +ea#ure *9 c*de c*+ple;ity, !a# intr*duced in chapter #/F#) One *9 the characteri#tic# *9 g**d *34ectE*riented pr*gra+# i# that their +eth*d# have le## cycl*+atic c*+ple;ity than pr*cedural pr*gra+#) H*! can thi# 3e #*, i9 the t!* pr*gra+# #*lve the #a+e pr*3le+F S*+e #a+ple c*de +ight e;plain the di99erence)

Cha"ter 5* >iding the Im"lementation

)33

4esign Is )s 4esign 4oes

"a, 9iding the I#$le#entation


= pri+ary c*n#iderati*n in *34ectE*riented de#ign i# I#eparating the thing# that change 9r*+ the thing# that #tay the #a+e)J
Thi# i# particularly i+p*rtant 9*r li3rarie#) The u#er Gclient "rogrammerH *9 that li3rary +u#t 3e a3le t* rely *n the part they u#e, and kn*! that they !*nt need t* re!rite c*de i9 a ne! ver#i*n *9 the li3rary c*+e# *ut) On the 9lip #ide, the li3rary creat*r +u#t have the 9reed*+ t* +ake +*di9icati*n# and i+pr*ve+ent# !ith the certainty that the client pr*gra++er# c*de !*nt 3e a99ected 3y th*#e change#) Thi# can 3e achieved thr*ugh c*nventi*n) 5*r e;a+ple, the li3rary pr*gra++er +u#t agree t* n*t re+*ve e;i#ting +eth*d# !hen +*di9ying a cla## in the li3rary, #ince that !*uld 3reak the client pr*gra++er# c*de) The rever#e #ituati*n i# th*rnier, h*!ever) -n the ca#e *9 a data +e+3er, h*! can the li3rary creat*r kn*! !hich data +e+3er# have 3een acce##ed 3y client pr*gra++er#F Thi# i# al#* true !ith +eth*d# that are *nly part *9 the i+ple+entati*n *9 a cla##, and n*t +eant t* 3e u#ed directly 3y the client pr*gra++er) But !hat i9 the li3rary creat*r !ant# t* rip *ut an *ld i+ple+entati*n and put in a ne! *neF Changing any *9 th*#e +e+3er# +ight 3reak a client pr*gra++er# c*de) Thu# the li3rary creat*r i# in a #trait 4acket and cant change anything) T* #*lve thi# pr*3le+, C# pr*vide# access s"eci$iers t* all*! the li3rary creat*r t* #ay !hat i# availa3le t* the client pr*gra++er and !hat i# n*t) The level# *9 acce## c*ntr*l 9r*+ I+*#t acce##J t* Ilea#t acce##J are public, protected, I9riendlyJ G!hich ha# n* key!*rdH, and private) 5r*+ the previ*u# paragraph y*u +ight think that, a# a li3rary de#igner, y*ull !ant t* keep everything a# IprivateJ a# p*##i3le, and e;p*#e *nly the +eth*d# that y*u !ant the client pr*gra++er t* u#e) Thi# i# e;actly right, even th*ugh it# *9ten c*unterintuitive 9*r pe*ple !h* pr*gra+ in *ther language# Ge#pecially CH and are u#ed t* acce##ing everything !ith*ut re#tricti*n) By the end *9 thi# chapter y*u #h*uld 3e c*nvinced *9 the value *9 acce## c*ntr*l in C#) The c*ncept *9 a li3rary *9 c*+p*nent# and the c*ntr*l *ver !h* can acce## the c*+p*nent# *9 that li3rary i# n*t c*+plete, h*!ever) There# #till the Due#ti*n *9 h*! the c*+p*nent# are 3undled t*gether int* a c*he#ive li3rary unit) Thi# i# c*ntr*lled !ith the namespace key!*rd in C#, and the acce## #peci9ier# are a99ected 3y !hether a cla## i# in the #a+e package *r in a #eparate package) S* t* 3egin thi#

)34

Thinking in C

www.ThinkingIn.!et

chapter, y*ull learn h*! li3rary c*+p*nent# are placed int* package#) Then y*ull 3e a3le t* under#tand the c*+plete +eaning *9 the acce## #peci9ier#)

-he na#es$ace unit


= package i# !hat y*u get !hen y*u u#e the using key!*rd t* 3ring in an entire li3rary, #uch a# u#ing Sy#te!.Co ection#3 Thi# 3ring# in the entire utility li3rary that# part *9 the #tandard ) ET 5ra+e!*rk S?N di#tri3uti*n) Since, 9*r e;a+ple, the cla## 'rrayList i# in )ava6util, y*u can n*! either #peci9y the 9ull na+e )ava6util6'rrayList G!hich y*u can d* !ith*ut the import #tate+entH, *r y*u can #i+ply #ay 'rrayList G3ecau#e *9 the importH) -9 y*u !ant t* 3ring in a #ingle cla##, y*u can na+e that cla## in the import #tate+ent i!port Da*a.uti .)rrayLi#t3 *! y*u can u#e 'rrayList !ith n* Duali9icati*n) H*!ever, n*ne *9 the *ther cla##e# in )ava6util are availa3le) The rea#*n 9*r all thi# i+p*rting i# t* pr*vide a +echani#+ t* +anage Ina+e #pace#)J The na+e# *9 all y*ur cla## +e+3er# are in#ulated 9r*+ each *ther) = +eth*d f( ) in#ide a cla## ' !ill n*t cla#h !ith an f( ) that ha# the #a+e #ignature Gargu+ent li#tH in cla## B) But !hat a3*ut the cla## na+e#F Supp*#e y*u create a stac( cla## that i# in#talled *n a +achine that already ha# a stac( cla## that# !ritten 3y #*+e*ne el#eF ,ith "ava *n the -nternet, thi# can happen !ith*ut the u#er kn*!ing it, #ince cla##e# can get d*!nl*aded aut*+atically in the pr*ce## *9 running a "ava pr*gra+) Thi# p*tential cla#hing *9 na+e# i# !hy it# i+p*rtant t* have c*+plete c*ntr*l *ver the na+e #pace# in C#, and t* 3e a3le t* create a c*+pletely uniDue na+e regardle## *9 the c*n#traint# *9 the -nternet) S* 9ar, +*#t *9 the e;a+ple# in thi# 3**k have e;i#ted in a #ingle 9ile and have 3een de#igned 9*r l*cal u#e, and havent 3*thered !ith package na+e#) G-n thi# ca#e the cla## na+e i# placed in the Ide9ault package)JH Thi# i# certainly an *pti*n, and 9*r #i+plicity# #ake thi# appr*ach !ill 3e u#ed !henever p*##i3le thr*ugh*ut the re#t *9 thi# 3**k) H*!ever, i9 y*ure planning t* create li3rarie# *r pr*gra+# that are 9riendly t* *ther C# pr*gra+# *n the #a+e +achine, y*u +u#t think a3*ut preventing cla## na+e cla#he#) ,hen y*u create a #*urceEc*de 9ile 9*r C#, it# c*++*nly called a com"ilation unit G#*+eti+e# a translation unitH) Each c*+pilati*n unit +u#t have a na+e ending in 6cs, and in#ide the c*+pilati*n unit there can 3e *ne *r +*re public cla##e#) Tk

Cha"ter 5* >iding the Im"lementation

)35

Creating unique $ac*age na#es


tkL) *! thi# package na+e can 3e u#ed a# an u+3rella na+e #pace 9*r the 9*ll*!ing t!* 9ile#1 //co!pi ed .ith c#c /target: i$rary na!e#pace thin%inginc#harp; pu$ ic c a## )rrayLi#t; pu$ ic )rrayLi#t01; Sy#te!.Con#o e.VriteLine0&thin%inginc#harp.)rrayLi#t&13 < <
]

LtkL u#ing thin%inginc#harp3 na!e#pace u#e#another; c a## O#e#Specia iMed; pu$ ic #tatic *oid Gain01; )rrayLi#t a 9 ne. )rrayLi#t013 //Can #ti exp icit y reference other Sy#te!.Co ection#.)rrayLi#t rea Li#t 9 ne. Sy#te!.Co ection#.)rrayLi#t013 rea Li#t.)dd0&Oh! 5t'# a rea co ection c a##!&13 < <
]

LtkL

Collisions
,hat happen# i9 t!* li3rarie# are i+p*rted via b and they include the #a+e na+e#F 5*r e;a+ple, #upp*#e a pr*gra+ d*e# thi#1 u#ing Cet.'hin%ing5n.Oti 3 u#ing Sy#te!.Co ection#3 tk d:^tic^chapP^thin%ingZc#c /t:!odu e V.c# Gicro#oft 0R1 Ni#ua C( Co!pi er Ner#ion F.00.>2PE JCLR *er#ion *".0.2>"EK Copyright 0C1 Gicro#oft Corp 20006200". ) right# re#er*ed. ::^tic^chapP^thin%ingZdir No u!e in dri*e : i# GON5+S

)36

Thinking in C

www.ThinkingIn.!et

No u!e Seria

Cu!$er i# 2BTF6">0F

:irectory of ::^tic^chapP^thin%ing "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" 0I:TF )G W:5RZ . 0I:TF )G W:5RZ .. 0I:TP )G 2IP V.c# 0I:TI )G 220EI V.net!odu e 2 Hi e0#1 22TTT $yte# 2 :ir0#1 "02?"T2P?T2T>2 $yte# free

::^tic^chapP^thin%ingZ#n 6% %ey.#n% Gicro#oft 0R1 .C+' Hra!e.or% Strong Ca!e Oti ity Ner#ion ".0.2>"E."? Copyright 0C1 Gicro#oft Corp. ">>I6200". ) right# re#er*ed. aey pair .ritten to %ey.#n% ::^tic^chapP^thin%ingZdir No u!e in dri*e : i# GON5+S No u!e Seria Cu!$er i# 2BTF6">0F :irectory of ::^tic^chapP^thin%ing "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" 0I:TF )G W:5RZ . 0I:TF )G W:5RZ .. 0I:TP )G 2IP V.c# 0I:TI )G 220EI V.net!odu e 0I:T> )G P>? %ey.#n% E Hi e0#1 ?200" $yte# 2 :ir0#1 "02?"T2PEF200I $yte# free

::^tic^chapP^thin%ingZa /out:thin%ing.d /%eyfi e:%ey.#n% V.net!odu e Gicro#oft 0R1 )##e!$ y Lin%er Ner#ion F.00.>2PE JCLR *er#ion *".0.2>"EK Copyright 0C1 Gicro#oft Corp 20006200". ) right# re#er*ed.

Cha"ter 5* >iding the Im"lementation

)3#

::^tic^chapP^thin%ingZdir No u!e in dri*e : i# GON5+S No u!e Seria Cu!$er i# 2BTF6">0F :irectory of ::^tic^chapP^thin%ing "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" "0/2T/200" 0I:TF )G W:5RZ . 0I:TF )G W:5RZ .. 0I:TP )G 2IP V.c# 0I:TI )G 220EI V.net!odu e 0I:T> )G T20F2 V.d 0I:T> )G P>? %ey.#n% 0I:E2 )G T2PIE thin%ing.d P Hi e0#1 >2PIP $yte# 2 :ir0#1 "02?"T22F?2?F2 $yte# free /i thin%ing.d

::^tic^chapP^thin%ingZgacuti

Gicro#oft 0R1 .C+' _ o$a )##e!$ y Cache Oti ity. Ner#ion ".0.2>"E."? Copyright 0C1 Gicro#oft Corp. ">>I6200". ) right# re#er*ed. )##e!$ y #ucce##fu y added to the cache

::^tic^chapP^thin%ingZ#tart c:^.indo.#^a##e!$ y

Ot*d*1 5igure *ut h*! t* re9erence it in *ther# G- kn*! - can d* it 9r*+ the c*++and line c*+pile, 3ut - cant 9igure *ut h*! t* d* it tran#parentlyH :*u can u#e thi# #h*rthand t* print a string either !ith a ne!line G!6rintln( )H *r !ith*ut a ne!line G!6rint( )H)

)3&

Thinking in C

www.ThinkingIn.!et

>sing i#$orts to change +ehavior


LtkL The pr*gra+ !ill n* l*nger print a##erti*n#) Here# an e;a+ple1 //Wexa!p eZ ///WchapterZ0PW/chapterZ ///Wprogra!Z'e#t)##ert.c#W/progra!Z // :e!on#trating the a##ertion too . // Co!!ent or unco!!ent the fo o.ing to change a##ertion $eha*ior: //(define )SS+R' u#ing Sy#te!.:iagno#tic#3 pu$ ic c a## )##ert; pri*ate #tatic *oid -+rr0#tring #1; Sy#te!.Con#o e.VriteLine0#13 < JConditiona 0&)SS+R'&1K pu$ ic #tatic *oid if0!exp1 -+rr0&)##ertion fai ed&13 < JConditiona 0&)SS+R'&1K pu$ ic #tatic *oid ; if0exp1 -+rr0&)##ertion fai ed&13 < JConditiona 0&)SS+R'&1K pu$ ic #tatic *oid #tring !#g1; if0!exp1 -+rr0!#g13 < JConditiona 0&)SS+R'&1K pu$ ic #tatic *oid #tring !#g1; if0exp1 -+rr0!#g13 < < pu$ ic c a## 'e#t)##ert ; pu$ ic #tatic *oid Gain01 ; )##ert.'rue002 R 21 99 P13 )##ert.Ha #e00" R "1 99 213 )##ert.'rue002 R 21 99 P2 &2 R 2 99 P&13 )##ert.Ha #e00" R "1 99 22 &" R" !9 2&13 < < //W/exa!p eZ By changing the package that# i+p*rted, y*u change y*ur c*de 9r*+ the de3ug ver#i*n t* the pr*ducti*n ver#i*n) Thi# techniDue can 3e u#ed 9*r any kind *9 c*nditi*nal c*de)

'rue0$oo Ha #e0$oo

exp1; exp1

'rue0$oo

exp2

Ha #e0$oo

exp2

Cha"ter 5* >iding the Im"lementation

)3'

C#s access s$eci0iers


,hen u#ed, the "ava acce## #peci9ier# public, protected, and private are placed in 9r*nt *9 each de9initi*n 9*r each +e+3er in y*ur cla##, !hether it# a 9ield *r a +eth*d) Each acce## #peci9ier c*ntr*l# the acce## 9*r *nly that particular de9initi*n) Thi# i# a di#tinct c*ntra#t t* C@@, in !hich the acce## #peci9ier c*ntr*l# all the de9initi*n# 9*ll*!ing it until an*ther acce## #peci9ier c*+e# al*ng) One !ay *r an*ther, everything ha# #*+e kind *9 acce## #peci9ied 9*r it) -n the 9*ll*!ing #ecti*n#, y*ull learn all a3*ut the vari*u# type# *9 acce##, #tarting !ith the de9ault acce##)

G7riendl5H
,hat i9 y*u give n* acce## #peci9ier at all, a# in all the e;a+ple# 3e9*re thi# chapterF The de9ault acce## ha# n* key!*rd, 3ut it i# c*++*nly re9erred t* a# I9riendly)J -t +ean# that all the *ther cla##e# in the current package have acce## t* the 9riendly +e+3er, 3ut t* all the cla##e# *ut#ide *9 thi# package the +e+3er appear# t* 3e private) Since a c*+pilati*n unitRa 9ileRcan 3el*ng *nly t* a #ingle package, all the cla##e# !ithin a #ingle c*+pilati*n unit are aut*+atically 9riendly !ith each *ther) Thu#, 9riendly ele+ent# are al#* #aid t* have "ackage access) 5riendly acce## all*!# y*u t* gr*up related cla##e# t*gether in a package #* that they can ea#ily interact !ith each *ther) ,hen y*u put cla##e# t*gether in a package Gthu# granting +utual acce## t* their 9riendly +e+3er#Q i)e), +aking the+ I9riend#JH y*u I*!nJ the c*de in that package) -t +ake# #en#e that *nly c*de y*u *!n #h*uld have 9riendly acce## t* *ther c*de y*u *!n) :*u c*uld #ay that 9riendly acce## give# a +eaning *r a rea#*n 9*r gr*uping cla##e# t*gether in a package) -n +any language# the !ay y*u *rgani7e y*ur de9initi*n# in 9ile# can 3e !illyEnilly, 3ut in "ava y*ure c*+pelled t* *rgani7e the+ in a #en#i3le 9a#hi*n) -n additi*n, y*ull pr*3a3ly !ant t* e;clude cla##e# that #h*uldnt have acce## t* the cla##e# 3eing de9ined in the current package) The cla## c*ntr*l# !hich c*de ha# acce## t* it# +e+3er#) There# n* +agic !ay t* I3reak in)J C*de 9r*+ an*ther package cant #h*! up and #ay, IHi, -+ a 9riend *9 Bob#KJ and e;pect t* #ee the protected, 9riendly, and private +e+3er# *9 Bob) The *nly !ay t* grant acce## t* a +e+3er i# t*1 1. 2. Aake the +e+3er public) Then every3*dy, every!here, can acce## it) Aake the +e+3er 9riendly 3y leaving *99 any acce## #peci9ier, and put the *ther cla##e# in the #a+e package) Then the *ther cla##e# can acce## the +e+3er) =# y*ull #ee in Chapter ., !hen inheritance i# intr*duced, an inherited cla## can acce## a protected +e+3er a# !ell a# a public +e+3er G3ut n*t private +e+3er#H) -t can acce## 9riendly +e+3er# *nly i9 the t!* cla##e# are in the #a+e package) But d*nt !*rry a3*ut that n*!) Thinking in C www.ThinkingIn.!et

3.

)4(

Pr*vide Iacce##*r<+utat*rJ +eth*d# Gal#* kn*!n a# Iget<#etJ +eth*d#H that read and change the value) Thi# i# the +*#t civili7ed appr*ach in ter+# *9 OOP, and it i# 9unda+ental t* "avaBean#, a# y*ull #ee in Chapter 0/)

public, inter0ace access


,hen y*u u#e the public key!*rd, it +ean# that the +e+3er declarati*n that i++ediately 9*ll*!# public i# availa3le t* every*ne, in particular t* the client pr*gra++er !h* u#e# the li3rary) Supp*#e y*u de9ine a package dessert c*ntaining the 9*ll*!ing c*+pilati*n unit1 //: c0P:de##ert:Coo%ie.Da*a // Create# a i$rary. pac%age c0P.de##ert3 pu$ ic c a## Coo%ie ; pu$ ic Coo%ie01 ; Sy#te!.out.print n0&Coo%ie con#tructor&13 < *oid $ite01 ; Sy#te!.out.print n0&$ite&13 < < ///:8 Re+e+3er, Coo(ie6)ava +u#t re#ide in a #u3direct*ry called dessert, in a direct*ry under c4Y Gindicating Chapter ' *9 thi# 3**kH that +u#t 3e under *ne *9 the CL=SSP=TH direct*rie#) ?*nt +ake the +i#take *9 thinking that "ava !ill al!ay# l**k at the current direct*ry a# *ne *9 the #tarting p*int# 9*r #earching) -9 y*u d*nt have a T6 a# *ne *9 the path# in y*ur CL=SSP=TH, "ava !*nt l**k there) *! i9 y*u create a pr*gra+ that u#e# Coo(ie1 //: c0P::inner.Da*a // O#e# the i$rary. i!port c0P.de##ert.=3 pu$ ic c a## :inner ; pu$ ic :inner01 ; Sy#te!.out.print n0&:inner con#tructor&13 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; Coo%ie x 9 ne. Coo%ie013 //! x.$ite013 // Can't acce## < < ///:8 y*u can create a Coo(ie *34ect, #ince it# c*n#truct*r i# public and the cla## i# public) G,ell l**k +*re at the c*ncept *9 a public cla## later)H H*!ever, the bite( ) +e+3er i# inacce##i3le in#ide $inner6)ava #ince bite( ) i# 9riendly *nly !ithin package dessert)

Cha"ter 5* >iding the Im"lementation

)41

-he de0ault $ac*age


:*u +ight 3e #urpri#ed t* di#c*ver that the 9*ll*!ing c*de c*+pile#, even th*ugh it !*uld appear that it 3reak# the rule#1 //: c0P:Ca%e.Da*a // )cce##e# a c a## in a // #eparate co!pi ation unit. c a## Ca%e ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; -ie x 9 ne. -ie013 x.f013 < < ///:8 -n a #ec*nd 9ile, in the #a+e direct*ry1 //: c0P:-ie.Da*a // 'he other c a##. c a## -ie ; *oid f01 ; Sy#te!.out.print n0&-ie.f01&13 < < ///:8 :*u +ight initially vie! the#e a# c*+pletely 9*reign 9ile#, and yet Ca(e i# a3le t* create a !ie *34ect and call it# f( ) +eth*dK G *te that y*u +u#t have T) in y*ur CL=SSP=TH in *rder 9*r the 9ile# t* c*+pile)H :*ud typically think that !ie and f( ) are 9riendly and there9*re n*t availa3le t* Ca(e) They are 9riendlyRthat part i# c*rrect) The rea#*n that they are availa3le in Ca(e6)ava i# 3ecau#e they are in the #a+e direct*ry and have n* e;plicit package na+e) "ava treat# 9ile# like thi# a# i+plicitly part *9 the Ide9ault packageJ 9*r that direct*ry, and there9*re 9riendly t* all the *ther 9ile# in that direct*ry)

private, 5ou cant touch thatJ


The private key!*rd +ean# that n* *ne can acce## that +e+3er e;cept that particular cla##, in#ide +eth*d# *9 that cla##) Other cla##e# in the #a+e package cann*t acce## private +e+3er#, #* it# a# i9 y*ure even in#ulating the cla## again#t y*ur#el9) On the *ther hand, it# n*t unlikely that a package +ight 3e created 3y #everal pe*ple c*lla3*rating t*gether, #* private all*!# y*u t* 9reely change that +e+3er !ith*ut c*ncern that it !ill a99ect an*ther cla## in the #a+e package) The de9ault I9riendlyJ package acce## *9ten pr*vide# an adeDuate a+*unt *9 hidingQ re+e+3er, a I9riendlyJ +e+3er i# inacce##i3le t* the u#er *9 the package) Thi# i# nice, #ince the de9ault acce## i# the *ne that y*u n*r+ally u#e Gand the *ne that y*ull get i9 y*u 9*rget t* add any acce## c*ntr*lH) Thu#, y*ull typically think a3*ut acce## 9*r the +e+3er# that y*u e;plicitly !ant t* +ake public 9*r the client pr*gra++er, and a# a re#ult, y*u +ight n*t initially think y*ull u#e the private key!*rd *9ten #ince it# t*lera3le t* get a!ay !ith*ut it) GThi# i# a di#tinct c*ntra#t !ith C@@)H )4) Thinking in C www.ThinkingIn.!et

H*!ever, it turn# *ut that the c*n#i#tent u#e *9 private i# very i+p*rtant, e#pecially !here +ultithreading i# c*ncerned) G=# y*ull #ee in Chapter 0&)H Here# an e;a+ple *9 the u#e *9 private1 //: c0P:5ceCrea!.Da*a // :e!on#trate# &pri*ate& %ey.ord. c a## Sundae ; pri*ate Sundae01 ;< #tatic Sundae !a%e)Sundae01 ; return ne. Sundae013 < < pu$ ic c a## 5ceCrea! ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; //! Sundae x 9 ne. Sundae013 Sundae x 9 Sundae.!a%e)Sundae013 < < ///:8 Thi# #h*!# an e;a+ple in !hich private c*+e# in handy1 y*u +ight !ant t* c*ntr*l h*! an *34ect i# created and prevent #*+e*ne 9r*+ directly acce##ing a particular c*n#truct*r G*r all *9 the+H) -n the e;a+ple a3*ve, y*u cann*t create a #undae *34ect via it# c*n#truct*rQ in#tead y*u +u#t call the ma(e'#undae( ) +eth*d t* d* it 9*r y*u0) =ny +eth*d that y*ure certain i# *nly a IhelperJ +eth*d 9*r that cla## can 3e +ade private, t* en#ure that y*u d*nt accidentally u#e it el#e!here in the package and thu# pr*hi3it y*ur#el9 9r*+ changing *r re+*ving the +eth*d) Aaking a +eth*d private guarantee# that y*u retain thi# *pti*n) The #a+e i# true 9*r a private 9ield in#ide a cla##) Unle## y*u +u#t e;p*#e the underlying i+ple+entati*n G!hich i# a +uch rarer #ituati*n than y*u +ight thinkH, y*u #h*uld +ake all 9ield# private) H*!ever, 4u#t 3ecau#e a re9erence t* an *34ect i# private in#ide a cla## d*e#nSt +ean that #*+e *ther *34ect canSt have a public re9erence t* the #a+e *34ect) GSee =ppendi; = 9*r i##ue# a3*ut alia#ing)H

protected, Gsort o0 0riendl5H


The protected acce## #peci9ier reDuire# a 4u+p ahead t* under#tand) 5ir#t, y*u #h*uld 3e a!are that y*u d*nt need t* under#tand thi# #ecti*n t* c*ntinue thr*ugh thi# 3**k up thr*ugh inheritance GChapter .H) But 9*r c*+pletene##, here i# a 3rie9 de#cripti*n and e;a+ple u#ing protected)

0 There# an*ther e99ect in thi# ca#e1 Since the de9ault c*n#truct*r i# the *nly *ne de9ined, and it#

private, it !ill prevent inheritance *9 thi# cla##) G= #u34ect that !ill 3e intr*duced in Chapter .)H

Cha"ter 5* >iding the Im"lementation

)43

The protected key!*rd deal# !ith a c*ncept called inheritance, !hich take# an e;i#ting cla## and add# ne! +e+3er# t* that cla## !ith*ut t*uching the e;i#ting cla##, !hich !e re9er t* a# the 2ase class) :*u can al#* change the 3ehavi*r *9 e;i#ting +e+3er# *9 the cla##) T* inherit 9r*+ an e;i#ting cla##, y*u #ay that y*ur ne! cla## extends an e;i#ting cla##, like thi#1 c a## Hoo extend# Bar ; The re#t *9 the cla## de9initi*n l**k# the #a+e) -9 y*u create a ne! package and y*u inherit 9r*+ a cla## in an*ther package, the *nly +e+3er# y*u have acce## t* are the public +e+3er# *9 the *riginal package) GO9 c*ur#e, i9 y*u per9*r+ the inheritance in the same package, y*u have the n*r+al package acce## t* all the I9riendlyJ +e+3er#)H S*+eti+e# the creat*r *9 the 3a#e cla## !*uld like t* take a particular +e+3er and grant acce## t* derived cla##e# 3ut n*t the !*rld in general) That# !hat protected d*e#) -9 y*u re9er 3ack t* the 9ile Coo(ie6)ava, the 9*ll*!ing cla## cannot acce## the I9riendlyJ +e+3er1 //: c0P:Choco ateChip.Da*a // Can't acce## friend y !e!$er // in another c a##. i!port c0P.de##ert.=3 pu$ ic c a## Choco ateChip extend# Coo%ie ; pu$ ic Choco ateChip01 ; Sy#te!.out.print n0 &Choco ateChip con#tructor&13 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; Choco ateChip x 9 ne. Choco ateChip013 //! x.$ite013 // Can't acce## $ite < < ///:8 One *9 the intere#ting thing# a3*ut inheritance i# that i9 a +eth*d bite( ) e;i#t# in cla## Coo(ie, then it al#* e;i#t# in any cla## inherited 9r*+ Coo(ie) But #ince bite( ) i# I9riendlyJ in a 9*reign package, it# unavaila3le t* u# in thi# *ne) O9 c*ur#e, y*u c*uld +ake it public, 3ut then every*ne !*uld have acce## and +ay3e that# n*t !hat y*u !ant) -9 !e change the cla## Coo(ie a# 9*ll*!#1 pu$ ic c a## Coo%ie ; pu$ ic Coo%ie01 ; Sy#te!.out.print n0&Coo%ie con#tructor&13 < protected *oid $ite01 ; Sy#te!.out.print n0&$ite&13 < <

)44

Thinking in C

www.ThinkingIn.!et

then bite( ) #till ha# I9riendlyJ acce## !ithin package dessert, 3ut it i# al#* acce##i3le t* any*ne inheriting 9r*+ Coo(ie) H*!ever, it i# not public) protected al#* give# package acce## P that i#, *ther cla##e# in the #a+e package +ay acce## protected ele+ent#)

Inter0ace and i#$le#entation


=cce## c*ntr*l i# *9ten re9erred t* a# im"lementation hiding) ,rapping data and +eth*d# !ithin cla##e# in c*+3inati*n !ith i+ple+entati*n hiding i# *9ten called enca"sulation2) The re#ult i# a data type !ith characteri#tic# and 3ehavi*r#) =cce## c*ntr*l put# 3*undarie# !ithin a data type 9*r t!* i+p*rtant rea#*n#) The 9ir#t i# t* e#ta3li#h !hat the client pr*gra++er# can and cant u#e) :*u can 3uild y*ur internal +echani#+# int* the #tructure !ith*ut !*rrying that the client pr*gra++er# !ill accidentally treat the internal# a# part *9 the inter9ace that they #h*uld 3e u#ing) Thi# 9eed# directly int* the #ec*nd rea#*n, !hich i# t* #eparate the inter9ace 9r*+ the i+ple+entati*n) -9 the #tructure i# u#ed in a #et *9 pr*gra+#, 3ut client pr*gra++er# cant d* anything 3ut #end +e##age# t* the public inter9ace, then y*u can change anything that# not public Ge)g), I9riendly,J protected, *r privateH !ith*ut reDuiring +*di9icati*n# t* client c*de) ,ere n*! in the !*rld *9 *34ectE*riented pr*gra++ing, !here a class i# actually de#cri3ing Ia cla## *9 *34ect#,J a# y*u !*uld de#cri3e a cla## *9 9i#he# *r a cla## *9 3ird#) =ny *34ect 3el*nging t* thi# cla## !ill #hare the#e characteri#tic# and 3ehavi*r#) The cla## i# a de#cripti*n *9 the !ay all *34ect# *9 thi# type !ill l**k and act) -n the *riginal OOP language, Si+ulaE.%, the key!*rd class !a# u#ed t* de#cri3e a ne! data type) The #a+e key!*rd ha# 3een u#ed 9*r +*#t *34ectE*riented language#) Thi# i# the 9*cal p*int *9 the !h*le language1 the creati*n *9 ne! data type# that are +*re than 4u#t 3*;e# c*ntaining data and +eth*d#) The cla## i# the 9unda+ental OOP c*ncept in C#) -t i# *ne *9 the key!*rd# that !ill not 3e #et in 3*ld in thi# 3**kRit 3ec*+e# ann*ying !ith a !*rd repeated a# *9ten a# Icla##)J 5*r clarity, y*u +ight pre9er a #tyle *9 creating cla##e# that put# the public +e+3er# at the 3eginning, 9*ll*!ed 3y the protected, 9riendly, and private +e+3er#) The advantage i# that the u#er *9 the cla## can then read d*!n 9r*+ the t*p and #ee 9ir#t !hat# i+p*rtant t* the+ Gthe public +e+3er#, 3ecau#e they can 3e acce##ed *ut#ide the 9ileH, and #t*p reading !hen they enc*unter the n*nEpublic +e+3er#, !hich are part *9 the internal i+ple+entati*n1 pu$ ic c a## , ;
2 H*!ever, pe*ple *9ten re9er t* i+ple+entati*n hiding al*ne a# encap#ulati*n)

Cha"ter 5* >iding the Im"lementation

)45

pu$ ic *oid -u$"0 1 pu$ ic *oid -u$20 1 pu$ ic *oid -u$T0 1 pri*ate *oid pri*"0 pri*ate *oid pri*20 pri*ate *oid pri*T0 pri*ate int i3 // . . . <

; ; ; 1 1 1

/= . /= . /= . ; /= ; /= ; /=

. . . . . .

. . . . . .

=/ < =/ < =/ < . =/ < . =/ < . =/ <

Thi# !ill +ake it *nly partially ea#ier t* read 3ecau#e the inter9ace and i+ple+entati*n are #till +i;ed t*gether) That i#, y*u #till #ee the #*urce c*deRthe i+ple+entati*nR3ecau#e it# right there in the cla##) -n additi*n, the c*++ent d*cu+entati*n #*+e!hat le##en# the i+p*rtance *9 c*de reada3ility 3y the client pr*gra++er) ?i#playing the inter9ace t* the c*n#u+er *9 a cla## i# really the 4*3 *9 the class 2rowser, a t**l !h*#e 4*3 i# t* l**k at all the availa3le cla##e# and #h*! y*u !hat y*u can d* !ith the+ Gi)e), !hat +e+3er# are availa3leH in a u#e9ul 9a#hi*n) Aicr*#*9t# Ci#ual Studi* ) ET i# the 9ir#t, 3ut n*t the *nly, t**l t* pr*vide a cla## 3r*!#er 9*r C#)

Class access
-n C#, the acce## #peci9ier# can al#* 3e u#ed t* deter+ine !hich cla##e# within a li3rary !ill 3e availa3le t* the u#er# *9 that li3rary) -9 y*u !ant a cla## t* 3e availa3le t* a client pr*gra++er, y*u place the public key!*rd #*+e!here 3e9*re the *pening 3race *9 the cla## 3*dy) Thi# c*ntr*l# !hether the client pr*gra++er can even create an *34ect *9 the cla##) T* c*ntr*l the acce## *9 a cla##, the #peci9ier +u#t appear 3e9*re the key!*rd class) Thu# y*u can #ay1 pu$ ic c a## Vidget ; *! i9 the na+e *9 y*ur li3rary i# .ylib any client pr*gra++er can acce## =idget 3y #aying u#ing Gy i$3 Vidget .3 ,hat i9 y*uve g*t a cla## in#ide .ylib that y*ure 4u#t u#ing t* acc*+pli#h the ta#k# per9*r+ed 3y =idget *r #*+e *ther public cla## in .ylibF :*u d*nt !ant t* g* t* the 3*ther *9 creating d*cu+entati*n 9*r the client pr*gra++er, and y*u think that #*+eti+e later y*u +ight !ant t* c*+pletely change thing# and rip *ut y*ur cla## alt*gether, #u3#tituting a di99erent *ne) T* give y*u thi# 9le;i3ility, y*u need t* en#ure that n* client pr*gra++er# 3ec*+e dependent *n y*ur particular i+ple+entati*n detail# hidden in#ide .ylib) T* acc*+pli#h thi#, y*u 4u#t leave the public key!*rd *99 the cla##, in !hich ca#e it 3ec*+e# 9riendly) GThat cla## can 3e u#ed *nly !ithin that package)H

)46

Thinking in C

www.ThinkingIn.!et

*te that a cla## cann*t 3e private Gthat !*uld +ake it acce##i3le t* n* *ne 3ut the cla##H, *r protected) S* y*u have *nly t!* ch*ice# 9*r cla## acce##1 I9riendlyJ *r public) -9 y*u d*nt !ant any*ne el#e t* have acce## t* that cla##, y*u can +ake all the c*n#truct*r# private, there3y preventing any*ne 3ut y*u, in#ide a static +e+3er *9 the cla##, 9r*+ creating an *34ect *9 that cla## /) Here# an e;a+ple1 //Wexa!p eZ ///WchapterZc0PW/chapterZ ///Wprogra!ZLunch.c#W/progra!Z // :e!on#trate# c a## acce## #pecifier#. // Ga%e a c a## effecti*e y pri*ate // .ith pri*ate con#tructor#: c a## Soup ; pri*ate Soup01 ;< // 0"1 ) o. creation *ia #tatic !ethod: pu$ ic #tatic Soup Ga%eSoup01 ; return ne. Soup013 < // 021 Create a #tatic o$Dect and // return a reference upon re7ue#t. // 0'he &Sing eton& pattern1: pri*ate #tatic Soup p#" 9 ne. Soup013 pu$ ic #tatic Soup )cce##01 ; return p#"3 < pu$ ic *oid H01 ;< < c a## Sand.ich ; // O#e# Lunch *oid H01 ; ne. Lunch013 < < // On y one pu$ ic c a## a o.ed per fi e: pu$ ic c a## Lunch ; *oid 'e#t01 ; // Can't do thi#! -ri*ate con#tructor: Soup pri*" 9 ne. Soup013 //! Soup pri*2 9 Soup.Ga%eSoup013 Sand.ich f" 9 ne. Sand.ich013 Soup.)cce##01.H013 < < //W/exa!p eZ Up t* n*!, +*#t *9 the +eth*d# have 3een returning either void *r a pri+itive type, #* the de9initi*n1 pu$ ic #tatic Soup )cce##01 ; return p#"3
/ :*u can al#* d* it 3y inheriting GChapter .H 9r*+ that cla##)

Cha"ter 5* >iding the Im"lementation

)4#

< +ight l**k a little c*n9u#ing at 9ir#t) The !*rd 3e9*re the +eth*d na+e G 'ccessH tell# !hat the +eth*d return#) S* 9ar thi# ha# +*#t *9ten 3een void, !hich +ean# it return# n*thing) But y*u can al#* return a re9erence t* an *34ect, !hich i# !hat happen# here) Thi# +eth*d return# a re9erence t* an *34ect *9 cla## #oup) The class #oup #h*!# h*! t* prevent direct creati*n *9 a cla## 3y +aking all the c*n#truct*r# private) Re+e+3er that i9 y*u d*nt e;plicitly create at lea#t *ne c*n#truct*r, the de9ault c*n#truct*r Ga c*n#truct*r !ith n* argu+ent#H !ill 3e created 9*r y*u) By !riting the de9ault c*n#truct*r, it !*nt 3e created aut*+atically) By +aking it private, n* *ne can create an *34ect *9 that cla##) But n*! h*! d*e# any*ne u#e thi# cla##F The a3*ve e;a+ple #h*!# t!* *pti*n#) 5ir#t, a static +eth*d i# created that create# a ne! #oup and return# a re9erence t* it) Thi# c*uld 3e u#e9ul i9 y*u !ant t* d* #*+e e;tra *perati*n# *n the #oup 3e9*re returning it, *r i9 y*u !ant t* keep c*unt *9 h*! +any #oup *34ect# t* create Gperhap# t* re#trict their p*pulati*nH) The #ec*nd *pti*n u#e# !hat# called a design "attern, !hich i# c*vered in Thinking in /atterns with ,a-a, d*!nl*ada3le at www.BruceEckel.com) Thi# particular pattern i# called a I#inglet*nJ 3ecau#e it all*!# *nly a #ingle *34ect t* ever 3e created) The *34ect *9 cla## #oup i# created a# a static private +e+3er *9 #oup, #* there# *ne and *nly *ne, and y*u cant get at it e;cept thr*ugh the public +eth*d access( )) =# previ*u#ly +enti*ned, i9 y*u d*nt put an acce## #peci9ier 9*r cla## acce## it de9ault# t* I9riendly)J Thi# +ean# that an *34ect *9 that cla## can 3e created 3y any *ther cla## in the package, 3ut n*t *ut#ide the package) GRe+e+3er, all the 9ile# !ithin the #a+e direct*ry that d*nt have e;plicit pac(age declarati*n# are i+plicitly part *9 the de9ault package 9*r that direct*ry)H H*!ever, i9 a static +e+3er *9 that cla## i# public, the client pr*gra++er can #till acce## that static +e+3er even th*ugh they cann*t create an *34ect *9 that cla##)

'u##ar5
-n any relati*n#hip it# i+p*rtant t* have 3*undarie# that are re#pected 3y all partie# inv*lved) ,hen y*u create a li3rary, y*u e#ta3li#h a relati*n#hip !ith the u#er *9 that li3raryRthe client pr*gra++erR!h* i# an*ther pr*gra++er, 3ut *ne putting t*gether an applicati*n *r u#ing y*ur li3rary t* 3uild a 3igger li3rary) ,ith*ut rule#, client pr*gra++er# can d* anything they !ant !ith all the +e+3er# *9 a cla##, even i9 y*u +ight pre9er they d*nt directly +anipulate #*+e *9 the +e+3er#) Everything# naked t* the !*rld) Thi# chapter l**ked at h*! cla##e# are 3uilt t* 9*r+ li3rarie#Q 9ir#t, the !ay a gr*up *9 cla##e# i# packaged !ithin a li3rary, and #ec*nd, the !ay the cla## c*ntr*l# acce## t* it# +e+3er#)

)4&

Thinking in C

www.ThinkingIn.!et

-t i# e#ti+ated that a C pr*gra++ing pr*4ect 3egin# t* 3reak d*!n #*+e!here 3et!een '$N and 0$$N line# *9 c*de 3ecau#e C ha# a #ingle Ina+e #paceJ #* na+e# 3egin t* c*llide, cau#ing an e;tra +anage+ent *verhead) -n "ava, the pac(age key!*rd, the package na+ing #che+e, and the import key!*rd give y*u c*+plete c*ntr*l *ver na+e#, #* the i##ue *9 na+e c*lli#i*n i# ea#ily av*ided) There are t!* rea#*n# 9*r c*ntr*lling acce## t* +e+3er#) The 9ir#t i# t* keep u#er# hand# *99 t**l# that they #h*uldnt t*uchQ t**l# that are nece##ary 9*r the internal +achinati*n# *9 the data type, 3ut n*t part *9 the inter9ace that u#er# need t* #*lve their particular pr*3le+#) S* +aking +eth*d# and 9ield# private i# a #ervice t* u#er# 3ecau#e they can ea#ily #ee !hat# i+p*rtant t* the+ and !hat they can ign*re) -t #i+pli9ie# their under#tanding *9 the cla##) The #ec*nd and +*#t i+p*rtant rea#*n 9*r acce## c*ntr*l i# t* all*! the li3rary de#igner t* change the internal !*rking# *9 the cla## !ith*ut !*rrying a3*ut h*! it !ill a99ect the client pr*gra++er) :*u +ight 3uild a cla## *ne !ay at 9ir#t, and then di#c*ver that re#tructuring y*ur c*de !ill pr*vide +uch greater #peed) -9 the inter9ace and i+ple+entati*n are clearly #eparated and pr*tected, y*u can acc*+pli#h thi# !ith*ut 9*rcing the u#er t* re!rite their c*de) =cce## #peci9ier# in "ava give valua3le c*ntr*l t* the creat*r *9 a cla##) The u#er# *9 the cla## can clearly #ee e;actly !hat they can u#e and !hat t* ign*re) A*re i+p*rtant, th*ugh, i# the a3ility t* en#ure that n* u#er 3ec*+e# dependent *n any part *9 the underlying i+ple+entati*n *9 a cla##) -9 y*u kn*! thi# a# the creat*r *9 the cla##, y*u can change the underlying i+ple+entati*n !ith the kn*!ledge that n* client pr*gra++er !ill 3e a99ected 3y the change# 3ecau#e they cant acce## that part *9 the cla##) ,hen y*u have the a3ility t* change the underlying i+ple+entati*n, y*u can n*t *nly i+pr*ve y*ur de#ign later, 3ut y*u al#* have the 9reed*+ t* +ake +i#take#) * +atter h*! care9ully y*u plan and de#ign y*ull +ake +i#take#) Nn*!ing that it# relatively #a9e t* +ake the#e +i#take# +ean# y*ull 3e +*re e;peri+ental, y*ull learn 9a#ter, and y*ull 9ini#h y*ur pr*4ect #**ner) The pu3lic inter9ace t* a cla## i# !hat the u#er does #ee, #* that i# the +*#t i+p*rtant part *9 the cla## t* get IrightJ during analy#i# and de#ign) Even that all*!# y*u #*+e lee!ay 9*r change) -9 y*u d*nt get the inter9ace right the 9ir#t ti+e, y*u can add +*re +eth*d#, a# l*ng a# y*u d*nt re+*ve any that client pr*gra++er# have already u#ed in their c*de)

Cha"ter 5* >iding the Im"lementation

)4'

%&ercises

C, 6eusing classes
,hat i# inheritanceF ,hy d*e# it helpF -nheritance in C#1 declaring derived cla##e#, pr*tected and pr*tected internal c*+p*nent#, virtual and *verride +eth*d#, a3#tract cla##e#, #ealed cla##e#, hiding inherited c*+p*nent#, ver#i*ning, lack *9 inheritance in #truct#) ,hat are alternative# t* inheritance 9*r c*+p*#ing c*+ple; #tructure#F H*! #h*uld !e decide 3et!een c*+p*#iti*n and aggregati*nF ,hat are the di99erent type# *9 de#ign pattern#F

)5(

Thinking in C

www.ThinkingIn.!et

One *9 the +*#t c*+pelling 9eature# a3*ut *34ect *rientati*n i# c*de reu#e) But t* 3e rev*luti*nary, y*uve g*t t* 3e a3le t* d* a l*t +*re than c*py c*de and change it)
That# the appr*ach u#ed in pr*cedural language# like C, and it ha#nt !*rked very !ell) Like everything in C#, the #*luti*n rev*lve# ar*und the cla##) :*u reu#e c*de 3y creating ne! cla##e#, 3ut in#tead *9 creating the+ 9r*+ #cratch, y*u u#e e;i#ting cla##e# that #*+e*ne ha# already 3uilt and de3ugged) The trick i# t* u#e the cla##e# !ith*ut #*iling the e;i#ting c*de) -n thi# chapter y*ull #ee t!* !ay# t* acc*+pli#h thi#) The 9ir#t i# Duite #traight9*r!ard1 :*u #i+ply create *34ect# *9 y*ur e;i#ting cla## in#ide the ne! cla##) Thi# i# called com"osition6 3ecau#e the ne! cla## i# c*+p*#ed *9 *34ect# *9 e;i#ting cla##e#) :*ure #i+ply reu#ing the 9uncti*nality *9 the c*de, n*t it# 9*r+) The #ec*nd appr*ach i# +*re #u3tle) -t create# a ne! cla## a# a t4"e o$ an e;i#ting cla##) :*u literally take the 9*r+ *9 the e;i#ting cla## and add c*de t* it !ith*ut +*di9ying the e;i#ting cla##) Thi# +agical act i# called inheritance, and the c*+piler d*e# +*#t *9 the !*rk) -nheritance i# *ne *9 the c*rner#t*ne# *9 *34ectE*riented pr*gra++ing, and ha# additi*nal i+plicati*n# that !ill 3e e;pl*red in Chapter #inheritance#) -t turn# *ut that +uch *9 the #ynta; and 3ehavi*r are #i+ilar 9*r 3*th c*+p*#iti*n and inheritance G!hich +ake# #en#e 3ecau#e they are 3*th

)51

!ay# *9 +aking ne! type# 9r*+ e;i#ting type#H) -n thi# chapter, y*ull learn a3*ut the#e c*de reu#e +echani#+#)

Co#$osition s5nta&
Until n*!, c*+p*#iti*n ha# 3een u#ed Duite 9reDuently) :*u #i+ply place *34ect re9erence# in#ide ne! cla##e#) 5*r e;a+ple, #upp*#e y*ud like an *34ect that h*ld# #everal string *34ect#, a c*uple *9 pri+itive#, and an *34ect *9 an*ther cla##) 5*r the n*npri+itive *34ect#, y*u put re9erence# in#ide y*ur ne! cla##, 3ut y*u de9ine the pri+itive# directly1 //:c0?:Sprin% erSy#te!.c# // Co!po#ition for code reu#e. c a## VaterSource ; pri*ate #tring #3 VaterSource01 ; Sy#te!.Con#o e.VriteLine0&VaterSource01&13 # 9 &Con#tructed&3 < pu$ ic o*erride #tring 'oString01 ; return #3 < < pu$ ic c a## Sprin% erSy#te! ; pri*ate #tring *a *e"2 *a *e22 *a *eT2 *a *eE3 VaterSource #ource3 int i3

)5)

f oat f3 *oid -rint01 ; Sy#te!.Con#o e.VriteLine0&*a *e" 9 & R *a *e"13 Sy#te!.Con#o e.VriteLine0&*a *e2 9 & R *a *e213 Sy#te!.Con#o e.VriteLine0&*a *eT 9 & R *a *eT13 Sy#te!.Con#o e.VriteLine0&*a *eE 9 & R *a *eE13 Sy#te!.Con#o e.VriteLine0&i 9 & R i13 Sy#te!.Con#o e.VriteLine0&f 9 & R f13 Sy#te!.Con#o e.VriteLine0&#ource 9 & R #ource13 < pu$ ic #tatic *oid Gain01 ; Sprin% erSy#te! x 9 ne. Sprin% erSy#te!013 x.-rint013 < < ///:8 One *9 the +eth*d# de9ined in =ater#ource i# #pecial1 +o#tring( )) :*u !ill learn later that every *34ect ha# a +o#tring( ) +eth*d, and it# called in #pecial #ituati*n# !hen the c*+piler !ant# a string 3ut it# g*t *ne *9 the#e *34ect#) S* in the e;pre##i*n1 Sy#te!.Con#o e.VriteLine0&#ource 9 & R #ource13 the c*+piler #ee# y*u trying t* add a string *34ect GYsource I YH t* a =ater#ource) Thi# d*e#nt +ake #en#e t* it, 3ecau#e y*u can *nly IaddJ a string t* an*ther #tring, #* it #ay# I-ll turn source int* a string 3y calling +o#tring( )KJ =9ter d*ing thi# it can c*+3ine the t!* string# and pa## the re#ulting #tring t* #ystem6Console6=riteLine( )) =ny ti+e y*u !ant t* all*! thi# 3ehavi*r !ith a cla## y*u create y*u need *nly !rite a +o#tring( ) +eth*d) =t 9ir#t glance, y*u +ight a##u+eRC# 3eing a# #a9e and care9ul a# it i#R that the c*+piler !*uld aut*+atically c*n#truct *34ect# 9*r each *9 the re9erence# in the a3*ve c*deQ 9*r e;a+ple, calling the de9ault c*n#truct*r 9*r =ater#ource t* initiali7e source) The *utput *9 the print #tate+ent i# in 9act1 *a *e" 9 nu *a *e2 9 nu *a *eT 9 nu

Cha"ter 6* ?eusing Classes

)53

*a *eE 9 nu i 9 0 f 9 0.0 #ource 9 nu Pri+itive# that are 9ield# in a cla## are aut*+atically initiali7ed t* 7er*, a# n*ted in Chapter #initiali7ati*n#) But the *34ect re9erence# are initiali7ed t* null, and i9 y*u try t* call +eth*d# 9*r any *9 the+ y*ull get an e;cepti*n) -t# actually pretty g**d Gand u#e9ulH that y*u can #till print the+ *ut !ith*ut thr*!ing an e;cepti*n) -t +ake# #en#e that the c*+piler d*e#nt 4u#t create a de9ault *34ect 9*r every re9erence 3ecau#e that !*uld incur unnece##ary *verhead in +any ca#e#) -9 y*u !ant the re9erence# initiali7ed, y*u can d* it1 0) =t the p*int the *34ect# are de9ined) Thi# +ean# that theyll al!ay# 3e initiali7ed 3e9*re the c*n#truct*r i# called) 2) -n the c*n#truct*r 9*r that cla##) /) Right 3e9*re y*u actually need t* u#e the *34ect) Thi# i# *9ten called la;4 initiali;ation) -t can reduce *verhead in #ituati*n# !here the *34ect d*e#nt need t* 3e created every ti+e) =ll three appr*ache# are #h*!n here1 //:c0?:Bath.c# // Con#tructor initia iMation .ith co!po#ition. c a## Soap ; pri*ate #tring #3 interna Soap01 ; Sy#te!.Con#o e.VriteLine0&Soap01&13 # 9 &Con#tructed&3 < pu$ ic o*erride #tring 'oString01 ; return #3 < < pu$ ic c a## Bath ; pri*ate #tring // 5nitia iMing at point of definition: //\todo: Change to #ho. arg con#tructor

)54

Thinking in C

www.ThinkingIn.!et

#" 9 &Uappy&2 #2 9 &Uappy&2 #T2 #E3 Soap ca#ti e3 int i3 f oat toy3 Bath01 ; Sy#te!.Con#o e.VriteLine0&5n#ide Bath01&13 #T 9 &`oy&3 i 9 EF3 toy 9 T."Ef3 ca#ti e 9 ne. Soap013 < *oid -rint01 ; // :e ayed initia iMation: if0#E 99 nu 1 #E 9 &`oy&3 Sy#te!.Con#o e.VriteLine0&#" 9 & R #"13 Sy#te!.Con#o e.VriteLine0&#2 9 & R #213 Sy#te!.Con#o e.VriteLine0&#T 9 & R #T13 Sy#te!.Con#o e.VriteLine0&#E 9 & R #E13 Sy#te!.Con#o e.VriteLine0&i 9 & R i13 Sy#te!.Con#o e.VriteLine0&toy 9 & R toy13 Sy#te!.Con#o e.VriteLine0&ca#ti e 9 & R ca#ti e13 < pu$ ic #tatic *oid Gain01 ; Bath $ 9 ne. Bath013 $.-rint013 < < ///:8 *te that in the Bath c*n#truct*r a #tate+ent i# e;ecuted 3e9*re any *9 the initiali7ati*n# take place) ,hen y*u d*nt initiali7e at the p*int *9 de9initi*n, there# #till n* guarantee that y*ull per9*r+ any initiali7ati*n 3e9*re y*u #end a +e##age t* an *34ect re9erenceRe;cept 9*r the inevita3le runEti+e e;cepti*n) Here# the *utput 9*r the pr*gra+1 5n#ide Bath01 Soap01

Cha"ter 6* ?eusing Classes

)55

#" 9 Uappy #2 9 Uappy #T 9 `oy #E 9 `oy i 9 EF toy 9 T."E ca#ti e 9 Con#tructed ,hen !rint( ) i# called it 9ill# in sJ #* that all the 9ield# are pr*perly initiali7ed 3y the ti+e they are u#ed)

Inheritance s5nta&
-nheritance i# an integral part *9 C# Gand OOP language# in generalH) -t turn# *ut that y*ure al!ay# d*ing inheritance !hen y*u create a cla##, 3ecau#e unle## y*u e;plicitly inherit 9r*+ #*+e *ther cla##, y*u i+plicitly inherit 9r*+ C## #tandard r**t cla## ob)ect) The #ynta; 9*r c*+p*#iti*n i# *3vi*u#, 3ut t* per9*r+ inheritance there# a di#tinctly di99erent 9*r+) ,hen y*u inherit, y*u #ay IThi# ne! cla## i# like that *ld cla##)J :*u #tate thi# in c*de 3y giving the na+e *9 the cla## a# u#ual, 3ut 3e9*re the *pening 3race *9 the cla## 3*dy, put a c*l*n 9*ll*!ed 3y the na+e *9 the 2ase class) ,hen y*u d* thi#, y*u aut*+atically get all the data +e+3er# and +eth*d# in the 3a#e cla##) Here# an e;a+ple1 //:c0?::etergent.c# ///Co!pi e .ith: &/!ain::etergent& // 5nheritance #yntax @ propertie#. interna c a## C ean#er ; pri*ate #tring # 9 &C ean#er&3 pu$ ic *oid )ppend0#tring a1 ; # R9 a3 < pu$ ic *oid :i ute01 ; )ppend0& di ute01&13 < pu$ ic *oid )pp y01 ; )ppend0& app y01&13 < *irtua pu$ ic *oid Scru$01 ; )ppend0& #cru$01&13 < pu$ ic *oid -rint01 ; Sy#te!.Con#o e.VriteLine0#13 < pu$ ic #tatic *oid Gain0#tringJK arg#1 ; C ean#er x 9 ne. C ean#er013 x.:i ute013 x.)pp y013 x.Scru$013

)56

Thinking in C

www.ThinkingIn.!et

x.-rint013 < < interna c a## :etergent : C ean#er ; // Change a !ethod: o*erride pu$ ic *oid Scru$01 ; )ppend0& :etergent.#cru$01&13 $a#e.Scru$013 // Ca $a#e6c a## *er#ion < // )dd !ethod# to the interface: pu$ ic *oid Hoa!01 ; )ppend0& Hoa!01&13 < // 'e#t the ne. c a##: ne. pu$ ic #tatic *oid Gain0#tringJK arg#1 ; :etergent x 9 ne. :etergent0arg#13 x.:i ute013 x.)pp y013 x.Scru$013 x.Hoa!013 x.-rint013 Sy#te!.Con#o e.VriteLine0&'e#ting $a#e c a##:&13 C ean#er.Gain013 < < ///:8 Thi# de+*n#trate# a nu+3er *9 9eature#) 5ir#t, 3*th Cleanser and $etergent c*ntain a .ain( ) +eth*d) :*u can create a .ain( ) 9*r each *ne *9 y*ur cla##e#, 3ut i9 y*u d* #*, the c*+piler !ill generate an err*r, #aying that y*u are de9ining +ultiple entry p*int#) :*u can ch**#e !hich .ain() y*u !ant t* have a##*ciated !ith the a##e+3ly 3y u#ing the <Aain1Cla##na+e #!itch) Thu#, i9 y*u c*+pile the a3*ve !ith csc $etergent6cs /.ainDCleanser, the *utput !ill 3e1 C ean#er di ute01 app y01 #cru$01 ,hile i9 c*+piled !ith csc $etergent6cs /.ainD$etergent, the re#ult i#1 C ean#er di ute01 app y01 :etergent.#cru$01 #cru$01 Hoa!01 'e#ting $a#e c a##: C ean#er di ute01 app y01 #cru$01

Cha"ter 6* ?eusing Classes

)5#

Thi# techniDue *9 putting a .ain( ) in each cla## can #*+eti+e# help !ith te#ting, !hen y*u 4u#t !ant t* !rite a Duick little pr*gra+ t* +ake #ure y*ur +eth*d# are !*rking the !ay y*u intend the+ t*) But 9*r general te#ting purp*#e#, y*u #h*uld u#e a unitEte#ting 9ra+e!*rk G#ee Chapter #te#ting#H) :*u d*nt need t* re+*ve the .ain( ) !hen y*ure 9ini#hed te#tingQ y*u can leave it in 9*r later te#ting) Here, y*u can #ee that $etergent6.ain( ) call# Cleanser6.ain( ) e;plicitly, pa##ing it the #a+e argu+ent# 9r*+ the c*++and line Gh*!ever, y*u c*uld pa## it any string arrayH) -t# i+p*rtant that all *9 the +eth*d# in Cleanser are public) Re+e+3er that i9 y*u leave *99 any acce## #peci9ier the +e+3er de9ault# t* private, !hich all*!# acce## *nly t* the very cla## in !hich the 9ield *r +eth*d i# de9ined) S* t* plan 9*r inheritance, a# a general rule leave 9ield# private, 3ut +ake all +eth*d# public) Gprotected +e+3er# al#* all*! acce## 3y derived cla##e#Q y*ull learn a3*ut thi# later)H O9 c*ur#e, in particular ca#e# y*u +u#t +ake ad4u#t+ent#, 3ut thi# i# a u#e9ul guideline) *te that Cleanser ha# a #et *9 +eth*d# in it# inter9ace1 'ppend( ), $ilute( ), 'pply( ), #crub( ), and !rint( )) Becau#e $etergent i# deri-ed $rom Cleanser it aut*+atically get# all the#e +eth*d# in it# inter9ace, even th*ugh y*u d*nt #ee the+ all e;plicitly de9ined in $etergent) :*u can think *9 inheritance, then, a# reusing the inter$ace. GThe i+ple+entati*n al#* c*+e# !ith it, 3ut that part i#nt the pri+ary p*int)H =# #een in #crub( ), it# p*##i3le t* take a +eth*d that# 3een de9ined in the 3a#e cla## and +*di9y it) -n thi# ca#e, y*u +ight !ant t* call the +eth*d 9r*+ the 3a#e cla## in#ide the ne! ver#i*n) But in#ide #crub( ) y*u cann*t #i+ply call #crub( ), #ince that !*uld pr*duce a recur#ive call, !hich i#nt !hat y*u !ant) T* #*lve thi# pr*3le+ C# ha# the key!*rd base that re9er# t* the I3a#e cla##J Gal#* called the I#upercla##JH 9r*+ !hich the current cla## ha# 3een inherited) Thu# the e;pre##i*n base6#crub( ) call# the 3a#eEcla## ver#i*n *9 the +eth*d #crub( )) ,hen inheriting y*ure n*t re#tricted t* u#ing the +eth*d# *9 the 3a#e cla##) :*u can al#* add ne! +eth*d# t* the derived cla## e;actly the !ay

)5&

Thinking in C

www.ThinkingIn.!et

y*u put any +eth*d in a cla##1 4u#t de9ine it) The +eth*d :oam( ) i# an e;a+ple *9 thi#) -n $etergent6.ain( ) y*u can #ee that 9*r a $etergent *34ect y*u can call all the +eth*d# that are availa3le in Cleanser a# !ell a# in $etergent Gi)e), :oam( )H)

Initiali:ing the +ase class


Since there are n*! t!* cla##e# inv*lvedRthe 3a#e cla## and the derived cla##Rin#tead *9 4u#t *ne, it can 3e a 3it c*n9u#ing t* try t* i+agine the re#ulting *34ect pr*duced 3y a derived cla##) 5r*+ the *ut#ide, it l**k# like the ne! cla## ha# the #a+e inter9ace a# the 3a#e cla## and +ay3e #*+e additi*nal +eth*d# and 9ield#) But inheritance d*e#nt 4u#t c*py the inter9ace *9 the 3a#e cla##) ,hen y*u create an *34ect *9 the derived cla##, it c*ntain# !ithin it a su2o23ect *9 the 3a#e cla##) Thi# #u3*34ect i# the #a+e a# i9 y*u had created an *34ect *9 the 3a#e cla## 3y it#el9) -t# 4u#t that, 9r*+ the *ut#ide, the #u3*34ect *9 the 3a#e cla## i# !rapped !ithin the derivedEcla## *34ect) O9 c*ur#e, it# e##ential that the 3a#eEcla## #u3*34ect 3e initiali7ed c*rrectly and there# *nly *ne !ay t* guarantee that1 per9*r+ the initiali7ati*n in the c*n#truct*r, 3y calling the 3a#eEcla## c*n#truct*r, !hich ha# all the appr*priate kn*!ledge and privilege# t* per9*r+ the 3a#eEcla## initiali7ati*n) C# aut*+atically in#ert# call# t* the 3a#eEcla## c*n#truct*r in the derivedEcla## c*n#truct*r) The 9*ll*!ing e;a+ple #h*!# thi# !*rking !ith three level# *9 inheritance1 //:c0?:Cartoon.c# // Con#tructor ca # during inheritance. //\todo: chec% if acce## !odifier# can $e !ade !ore pri*ate pu$ ic c a## )rt ; interna )rt01 ; Sy#te!.Con#o e.VriteLine0&)rt con#tructor&13 < < pu$ ic c a## :ra.ing : )rt ; interna :ra.ing01 ;

Cha"ter 6* ?eusing Classes

)5'

Sy#te!.Con#o e.VriteLine0&:ra.ing con#tructor&13 < < pu$ ic c a## Cartoon : :ra.ing ; interna Cartoon01 ; Sy#te!.Con#o e.VriteLine0&Cartoon con#tructor&13 < pu$ ic #tatic *oid Gain01 ; Cartoon x 9 ne. Cartoon013 < < ///:8 The *utput 9*r thi# pr*gra+ #h*!# the aut*+atic call#1 )rt con#tructor :ra.ing con#tructor Cartoon con#tructor :*u can #ee that the c*n#tructi*n happen# 9r*+ the 3a#e I*ut!ard,J #* the 3a#e cla## i# initiali7ed 3e9*re the derivedEcla## c*n#truct*r# can acce## it) Even i9 y*u d*nt create a c*n#truct*r 9*r Cartoon( ), the c*+piler !ill #ynthe#i7e a de9ault c*n#truct*r 9*r y*u that call# the 3a#e cla## c*n#truct*r)

Constructors with argu#ents


The a3*ve e;a+ple ha# de9ault c*n#truct*r#Q that i#, they d*nt have any argu+ent#) -t# ea#y 9*r the c*+piler t* call the#e 3ecau#e there# n* Due#ti*n a3*ut !hat argu+ent# t* pa##) -9 y*ur cla## d*e#nt have de9ault argu+ent#, *r i9 y*u !ant t* call a 3a#eEcla## c*n#truct*r that ha# an argu+ent, y*u +u#t e;plicitly !rite the call# t* the 3a#eEcla## c*n#truct*r u#ing the base key!*rd and the appr*priate argu+ent li#t1 //:c0?:Che##.c# // 5nheritance2 con#tructor# and argu!ent#. pu$ ic c a## _a!e ; interna _a!e0int i1 ; Sy#te!.Con#o e.VriteLine0&_a!e con#tructor&13

)6(

Thinking in C

www.ThinkingIn.!et

< < pu$ ic c a## Board_a!e : _a!e ; interna Board_a!e0int i1 : $a#e0i1 ; Sy#te!.Con#o e.VriteLine0&Board_a!e con#tructor&13 < < pu$ ic c a## Che## : Board_a!e ; interna Che##01 : $a#e0""1; Sy#te!.Con#o e.VriteLine0&Che## con#tructor&13 < pu$ ic #tatic *oid Gain01 ; Che## x 9 ne. Che##013 < <///:8 -9 y*u d*nt call the 3a#eEcla## c*n#truct*r in Board ame( ), the c*+piler !ill c*+plain that it cant 9ind a c*n#truct*r *9 the 9*r+ ame( ))

Catching +ase constructor e&ce$tions


=# 4u#t n*ted, the c*+piler 9*rce# y*u t* place the 3a#eEcla## c*n#truct*r call 3e9*re even the 3*dy *9 the derivedEcla## c*n#truct*r) =# y*ull #ee in Chapter #E;cepti*n##, thi# al#* prevent# a derivedEcla## c*n#truct*r 9r*+ catching any e;cepti*n# that c*+e 9r*+ a 3a#e cla##) Thi# can 3e inc*nvenient at ti+e#) //:c0?::o!e.c# u#ing Sy#te!3 c a## :o!e; pu$ ic :o!e01; thro. ne. 5n*a idOperation+xception013 < < c a## Brune e#chi : :o!e; pu$ ic Brune e#chi01;

Cha"ter 6* ?eusing Classes

)61

Sy#te!.Con#o e.VriteLine0&5ngeniou# Nau ting&13 < pu$ ic #tatic *oid Gain01; try; ne. Brune e#chi013 <catch0+xception ex1; Sy#te!.Con#o e.VriteLine0ex13 < < <///:8 print#1 Sy#te!.5n*a idOperation+xception: Operation i# not *a id due to the current #tate of the o$Dect. at :o!e..ctor01 at Brune e#chi.Gain01

Co#+ining co#$osition and inheritance


-t i# very c*++*n t* u#e c*+p*#iti*n and inheritance t*gether) The 9*ll*!ing e;a+ple #h*!# the creati*n *9 a +*re c*+ple; cla##, u#ing 3*th inheritance and c*+p*#iti*n, al*ng !ith the nece##ary c*n#truct*r initiali7ati*n1 //:c0?:- aceSetting.c# // Co!$ining co!po#ition @ inheritance. c a## - ate ; interna - ate0int i1 ; Sy#te!.Con#o e.VriteLine0&- ate con#tructor&13 < < c a## :inner- ate : - ate ; interna :inner- ate0int i1 : $a#e0i1 ; Sy#te!.Con#o e.VriteLine0

)6)

Thinking in C

www.ThinkingIn.!et

&:inner- ate con#tructor&13 < < c a## Oten#i ; interna Oten#i 0int i1 ; Sy#te!.Con#o e.VriteLine0&Oten#i < <

con#tructor&13

c a## Spoon : Oten#i ; interna Spoon0int i1 : $a#e0i1 ; Sy#te!.Con#o e.VriteLine0&Spoon con#tructor&13 < < c a## Hor% : Oten#i ; interna Hor%0int i1 : $a#e0i1 ; Sy#te!.Con#o e.VriteLine0&Hor% con#tructor&13 < < c a## anife : Oten#i ; interna anife0int i1 : $a#e0i1 ; Sy#te!.Con#o e.VriteLine0&anife con#tructor&13 < < // ) cu tura .ay of doing #o!ething: c a## Cu#to! ; interna Cu#to!0int i1 ; Sy#te!.Con#o e.VriteLine0&Cu#to! con#tructor&13 < < c a## - aceSetting : Cu#to! ; Spoon #p3 Hor% fr%3 anife %n3 :inner- ate p 3 - aceSetting0int i1 : $a#e0i R "1 ;

Cha"ter 6* ?eusing Classes

)63

#p 9 ne. Spoon0i R 213 fr% 9 ne. Hor%0i R T13 %n 9 ne. anife0i R E13 p 9 ne. :inner- ate0i R P13 Sy#te!.Con#o e.VriteLine0 &- aceSetting con#tructor&13 < pu$ ic #tatic *oid Gain 01; - aceSetting x 9 ne. - aceSetting0>13 < <///:8 ,hile the c*+piler 9*rce# y*u t* initiali7e the 3a#e cla##e#, and reDuire# that y*u d* it right at the 3eginning *9 the c*n#truct*r, it d*e#nt !atch *ver y*u t* +ake #ure that y*u initiali7e the +e+3er *34ect#, #* y*u +u#t re+e+3er t* pay attenti*n t* that)

Guaranteeing $ro$er cleanu$


:*u +ay recall 9r*+ chapter #initiali7ati*n# that alth*ugh C# ha# a de#truct*r, !e #aid that the pr*per !ay t* guarantee that an *34ect clean# up a9ter it#el9 inv*lved the B$isposable inter9ace, i+ple+enting the +eth*d $ispose(), and !rapping the Ivalua3le re#*urceJ in a using 3l*ck) =t the ti+e, !e de9erred a di#cu##i*n *9 h*! it !*rked, 3ut !ith an under#tanding *9 inheritance, it #tart# t* 3ec*+e# clear) G=lth*ugh under#tanding h*! the using 3l*ck !*rk# !ill reDuire an under#tanding *9 E;cepi*n#, !hich i# c*+ing in Chapter #e;cepti*n## GI)H C*n#ider an e;a+ple *9 a c*+puterEaided de#ign #y#te+ that dra!# picture# *n the #creen1 //:c0?:C):Sy#te!.c# // +n#uring proper c eanup. u#ing Sy#te!3 c a## Shape : 5:i#po#a$ e ; interna Shape0int i1 ; Sy#te!.Con#o e.VriteLine0&Shape con#tructor&13 < pu$ ic *irtua *oid :i#po#e01 ; Sy#te!.Con#o e.VriteLine0&Shape di#po#ed&13 <

)64

Thinking in C

www.ThinkingIn.!et

< c a## Circ e : Shape ; interna Circ e0int i1 : $a#e0i1 ; Sy#te!.Con#o e.VriteLine0&:ra.ing a Circ e&13 < pu$ ic o*erride *oid :i#po#e01 ; Sy#te!.Con#o e.VriteLine0&+ra#ing a Circ e&13 $a#e.:i#po#e013 < < c a## 'riang e : Shape ; interna 'riang e0int i1 : $a#e0i1 ; Sy#te!.Con#o e.VriteLine0&:ra.ing a 'riang e&13 < pu$ ic o*erride *oid :i#po#e01 ; Sy#te!.Con#o e.VriteLine0&+ra#ing a 'riang e&13 $a#e.:i#po#e013 < < c a## Line : Shape ; pri*ate int #tart2 end3 interna Line0int #tart2 int end1 : $a#e0#tart1; thi#.#tart 9 #tart3 thi#.end 9 end3 Sy#te!.Con#o e.VriteLine0&:ra.ing a Line: & R #tart R &2 & R end13 < pu$ ic o*erride *oid :i#po#e01 ; Sy#te!.Con#o e.VriteLine0&+ra#ing a Line: & R #tart R &2 & R end13 $a#e.:i#po#e013 < < c a## C):Sy#te! : Shape ; pri*ate Circ e c3 pri*ate 'riang e t3 pri*ate LineJK ine# 9 ne. LineJ"0K3

Cha"ter 6* ?eusing Classes

)65

C):Sy#te!0int i1 : $a#e0i R "1; for0int D 9 03 D W "03 DRR1 ine#JDK 9 ne. Line0D2 D=D13 c 9 ne. Circ e0"13 t 9 ne. 'riang e0"13 Sy#te!.Con#o e.VriteLine0&Co!$ined con#tructor&13 < pu$ ic o*erride *oid :i#po#e01 ; Sy#te!.Con#o e.VriteLine0&C):Sy#te!.:i#po#e01&13 // 'he order of c eanup i# the re*er#e // of the order of initia iMation t.:i#po#e013 c.:i#po#e013 for0int i 9 ine#.Length 6 "3 i Z9 03 i661 ine#JiK.:i#po#e013 $a#e.:i#po#e013 < pu$ ic #tatic *oid Gain01 ; C):Sy#te! x 9 ne. C):Sy#te!0EF13 u#ing0x1; // Code and exception hand ing... < Sy#te!.Con#o e.VriteLine0&O#ing $ oc% eft&13 < <///:8 Everything in thi# #y#te+ i# #*+e kind *9 #hape G!hich it#el9 i# a kind *9 ob)ect #ince it# i+plicitly inherited 9r*+ the r**t cla## and !hich i+ple+ent# an inter$ace called -?i#p*#a3leH) Each cla## rede9ine# #hape# $ispose( ) +eth*d in additi*n t* calling the 3a#eEcla## ver#i*n *9 that +eth*d u#ing base) The #peci9ic #hape cla##e#RCircle, +riangle and LineRall have c*n#truct*r# that Idra!,J alth*ugh any +eth*d called during the li9eti+e *9 the *34ect c*uld 3e re#p*n#i3le 9*r d*ing #*+ething that need# cleanup) Each cla## ha# it# *!n $ispose( ) +eth*d t* re#t*re n*n+e+*ry thing# 3ack t* the !ay they !ere 3e9*re the *34ect e;i#ted) -n .ain( ), y*u can #ee the using key!*rd in acti*n) = using 3l*ck take# an B$isposable a# an argu+ent) ,hen e;ecuti*n leave# the 3l*ck Geven i9 an e;cepti*n i# thr*!nH, B$isposable6$ispose() i# called) But 3ecau#e !e have i+ple+ented $ispose() in #hape and all the cla##e#

)66

Thinking in C

www.ThinkingIn.!et

derived 9r*+ it, inheritance kick# in and the appr*priate $ispose() +eth*d i# called) -n thi# ca#e, the u#ing 3l*ck ha# a C'$#ystem) -t# $ispose() +eth*d call#, in turn, the $ispose() +eth*d *9 the *34ect# !hich c*+pri#e it) *te that in y*ur cleanup +eth*d y*u +u#t al#* pay attenti*n t* the calling *rder 9*r the 3a#eEcla## and +e+3erE*34ect cleanup +eth*d# in ca#e *ne #u3*34ect depend# *n an*ther) -n general, y*u #h*uld 9*ll*! the #a+e 9*r+ that i# i+p*#ed 3y a C@@ c*+piler *n it# de#truct*r#1 5ir#t per9*r+ all *9 the cleanup !*rk #peci9ic t* y*ur cla##, in the rever#e *rder *9 creati*n) G-n general, thi# reDuire# that 3a#eEcla## ele+ent# #till 3e via3le)H Then call the 3a#eEcla## $ispose +eth*d, a# de+*n#trated here) There can 3e +any ca#e# in !hich the cleanup i##ue i# n*t a pr*3le+Q y*u 4u#t let the gar3age c*llect*r d* the !*rk) But !hen y*u +u#t d* it e;plicitly, diligence and attenti*n i# reDuired)

Order o0 gar+age collection


There# n*t +uch y*u can rely *n !hen it c*+e# t* gar3age c*llecti*n) The gar3age c*llect*r +ay n*t 3e called until y*ur pr*gra+ e;it#) -9 it i# called, it can reclai+ *34ect# in any *rder it !ant#) -t# 3e#t t* n*t rely *n gar3age c*llecti*n 9*r anything 3ut +e+*ry recla+ati*n) -9 y*u have Ivalua3le re#*urce#J !hich need e;plicit cleanup, al!ay# initiali7e the+ a# late a# p*##i3le, and di#p*#e *9 the+ a# #**n a# y*u can)

Choosing co#$osition vs. inheritance


B*th c*+p*#iti*n and inheritance all*! y*u t* place #u3*34ect# in#ide y*ur ne! cla##) :*u +ight !*nder a3*ut the di99erence 3et!een the t!*, and !hen t* ch**#e *ne *ver the *ther) C*+p*#iti*n i# generally u#ed !hen y*u !ant the 9eature# *9 an e;i#ting cla## in#ide y*ur ne! cla##, 3ut n*t it# inter9ace) That i#, y*u e+3ed an

Cha"ter 6* ?eusing Classes

)6#

*34ect #* that y*u can u#e it t* i+ple+ent 9uncti*nality in y*ur ne! cla##, 3ut the u#er *9 y*ur ne! cla## #ee# the inter9ace y*uve de9ined 9*r the ne! cla## rather than the inter9ace 9r*+ the e+3edded *34ect) 5*r thi# e99ect, y*u e+3ed private *34ect# *9 e;i#ting cla##e# in#ide y*ur ne! cla##) S*+eti+e# it +ake# #en#e t* all*! the cla## u#er t* directly acce## the c*+p*#iti*n *9 y*ur ne! cla##Q that i#, t* +ake the +e+3er *34ect# public) The +e+3er *34ect# u#e i+ple+entati*n hiding the+#elve#, #* thi# i# a #a9e thing t* d*) ,hen the u#er kn*!# y*ure a##e+3ling a 3unch *9 part#, it +ake# the inter9ace ea#ier t* under#tand) = car *34ect i# a g**d e;a+ple1 //:c0?:Car.c# // Co!po#ition .ith pu$ ic o$Dect#. //\todo: _ood p ace to ta % a$out enforced acce## *i#i$i ity 0+ngine can't $e interna if +ngine i# pu$ ic in Car1 pu$ ic c pu$ ic pu$ ic pu$ ic < a## +ngine ; *oid #tart01 ;< *oid re*01 ;< *oid #top01 ;<

pu$ ic c a## Vhee ; pu$ ic *oid inf ate0int p#i1 ;< < pu$ ic c a## Vindo. ; pu$ ic *oid ro up01 ;< pu$ ic *oid ro do.n01 ;< < pu$ ic c pu$ ic pu$ ic pu$ ic < a## :oor ; Vindo. .indo. 9 ne. Vindo.013 *oid open01 ;< *oid c o#e01 ;<

pu$ ic c a## Car ; pu$ ic +ngine engine 9 ne. +ngine013

)6&

Thinking in C

www.ThinkingIn.!et

pu$ ic Vhee JK .hee 9 ne. Vhee JEK3 pu$ ic :oor eft 9 ne. :oor012 right 9 ne. :oor013 // 26door pu$ ic Car01 ; for0int i 9 03 i W E3 iRR1 .hee JiK 9 ne. Vhee 013 < pu$ ic #tatic *oid Gain01 ; Car car 9 ne. Car013 car. eft..indo..ro up013 car..hee J0K.inf ate0F213 < < ///:8 Ot*d*1 >**d place t* talk a3*ut inde;er#F Becau#e the c*+p*#iti*n *9 a car i# part *9 the analy#i# *9 the pr*3le+ Gand n*t #i+ply part *9 the underlying de#ignH, +aking the +e+3er# public a##i#t# the client pr*gra++er# under#tanding *9 h*! t* u#e the cla## and reDuire# le## c*de c*+ple;ity 9*r the creat*r *9 the cla##) H*!ever, keep in +ind that thi# i# a #pecial ca#e and that in general y*u #h*uld +ake 9ield# private) ,hen y*u inherit, y*u take an e;i#ting cla## and +ake a #pecial ver#i*n *9 it) -n general, thi# +ean# that y*ure taking a generalEpurp*#e cla## and #peciali7ing it 9*r a particular need) ,ith a little th*ught, y*ull #ee that it !*uld +ake n* #en#e t* c*+p*#e a car u#ing a vehicle *34ectRa car d*e#nt c*ntain a vehicle, it is a vehicle) The is9a relati*n#hip i# e;pre##ed !ith inheritance, and the has9a relati*n#hip i# e;pre##ed !ith c*+p*#iti*n)

$rotected
*! that y*uve 3een intr*duced t* inheritance, the key!*rd protected 9inally ha# +eaning) -n an ideal !*rld, private +e+3er# !*uld al!ay# 3e hardEandE9a#t private, 3ut in real pr*4ect# there are ti+e# !hen y*u !ant t* +ake #*+ething hidden 9r*+ the !*rld at large and yet all*! acce## 9*r +e+3er# *9 derived cla##e#) The protected key!*rd i# a n*d t* prag+ati#+) -t #ay# IThi# i# private a# 9ar a# the cla## u#er i# c*ncerned,

Cha"ter 6* ?eusing Classes

)6'

3ut availa3le t* any*ne !h* inherit# 9r*+ thi# cla##)J Ot*d*1 -ntr*duce internal in di#cu##i*n *9 na+e#pace# The 3e#t tack t* take i# t* leave the data +e+3er# privateRy*u #h*uld al!ay# pre#erve y*ur right t* change the underlying i+ple+entati*n) :*u can then all*! c*ntr*lled acce## t* inherit*r# *9 y*ur cla## thr*ugh protected +eth*d#1 //:c0?:Orc.c# // 'he protected %ey.ord. pu$ ic c a## Ni ain ; pri*ate int i3 protected int read01 ; return i3 protected *oid #et0int ii1 ; i 9 pu$ ic Ni ain0int ii1 ; i 9 ii3 pu$ ic int *a ue0int !1 ; return <

< ii3 < < !=i3 <

pu$ ic c a## Orc : Ni ain ; pri*ate int D3 pu$ ic Orc0int DD1 :$a#e0DD1 ; D 9 DD3 < pu$ ic *oid change0int x1 ; #et0x13 < < ///:8 :*u can #ee that change( ) ha# acce## t* set( ) 3ecau#e it# protected)

Incre#ental develo$#ent
One *9 the advantage# *9 inheritance i# that it #upp*rt# incremental de-elo"ment 3y all*!ing y*u t* intr*duce ne! c*de !ith*ut cau#ing 3ug# in e;i#ting c*de) Thi# al#* i#*late# ne! 3ug# in#ide the ne! c*de) By inheriting 9r*+ an e;i#ting, 9uncti*nal cla## and adding data +e+3er# and +eth*d# Gand rede9ining e;i#ting +eth*d#H, y*u leave the e;i#ting c*deRthat #*+e*ne el#e +ight #till 3e u#ingRunt*uched and un3ugged) -9 a 3ug happen#, y*u kn*! that it# in y*ur ne! c*de, !hich i# +uch #h*rter and ea#ier t* read than i9 y*u had +*di9ied the 3*dy *9 e;i#ting c*de)

)#(

Thinking in C

www.ThinkingIn.!et

-t# rather a+a7ing h*! cleanly the cla##e# are #eparated) :*u d*nt even need the #*urce c*de 9*r the +eth*d# in *rder t* reu#e the c*de) =t +*#t, y*u 4u#t i+p*rt a package) GThi# i# true 9*r 3*th inheritance and c*+p*#iti*n)H -t# i+p*rtant t* reali7e that pr*gra+ devel*p+ent i# an incre+ental pr*ce##, 4u#t like hu+an learning) :*u can d* a# +uch analy#i# a# y*u !ant, 3ut y*u #till !*nt kn*! all the an#!er# !hen y*u #et *ut *n a pr*4ect) :*ull have +uch +*re #ucce##Rand +*re i++ediate 9eed3ackR i9 y*u #tart *ut t* Igr*!J y*ur pr*4ect a# an *rganic, ev*luti*nary creature, rather than c*n#tructing it all at *nce like a gla##E3*; #ky#craper) =lth*ugh inheritance 9*r e;peri+entati*n can 3e a u#e9ul techniDue, at #*+e p*int a9ter thing# #ta3ili7e y*u need t* take a ne! l**k at y*ur cla## hierarchy !ith an eye t* c*llap#ing it int* a #en#i3le #tructure) Re+e+3er that underneath it all, inheritance i# +eant t* e;pre## a relati*n#hip that #ay# IThi# ne! cla## i# a t4"e o$ that *ld cla##)J :*ur pr*gra+ #h*uld n*t 3e c*ncerned !ith pu#hing 3it# ar*und, 3ut in#tead !ith creating and +anipulating *34ect# *9 vari*u# type# t* e;pre## a +*del in the ter+# that c*+e 9r*+ the pr*3le+ #pace)

>$casting
The +*#t i+p*rtant a#pect *9 inheritance i# n*t that it pr*vide# +eth*d# 9*r the ne! cla##) -t# the relati*n#hip e;pre##ed 3et!een the ne! cla## and the 3a#e cla##) Thi# relati*n#hip can 3e #u++ari7ed 3y #aying IThe ne! cla## is a t4"e o$ the e;i#ting cla##)J Thi# de#cripti*n i# n*t 4u#t a 9anci9ul !ay *9 e;plaining inheritanceRit# #upp*rted directly 3y the language) =# an e;a+ple, c*n#ider a 3a#e cla## called Bnstrument that repre#ent# +u#ical in#tru+ent#, and a derived cla## called =ind) Becau#e inheritance +ean# that all *9 the +eth*d# in the 3a#e cla## are al#* availa3le in the derived cla##, any +e##age y*u can #end t* the 3a#e cla## can al#* 3e #ent t* the derived cla##) -9 the Bnstrument cla## ha# a !lay( ) +eth*d, #* !ill =ind in#tru+ent#) Thi# +ean# !e can accurately #ay that a =ind *34ect i# al#* a type *9 Bnstrument) The 9*ll*!ing e;a+ple #h*!# h*! the c*+piler #upp*rt# thi# n*ti*n1

Cha"ter 6* ?eusing Classes

)#1

//:c0?:Vind.c# // 5nheritance @ upca#ting. pu$ ic c a## 5n#tru!ent ; pu$ ic *oid p ay01 ;< #tatic interna *oid tune05n#tru!ent i1 ; // ... i.p ay013 < < // Vind o$Dect# are in#tru!ent# // $ecau#e they ha*e the #a!e interface: pu$ ic c a## Vind : 5n#tru!ent ; pu$ ic #tatic *oid Gain01 ; Vind f ute 9 ne. Vind013 5n#tru!ent.tune0f ute13 // Opca#ting < < ///:8 ,hat# intere#ting in thi# e;a+ple i# the +une( ) +eth*d, !hich accept# an Bnstrument re9erence) H*!ever, in =ind).ain( ) the +une( ) +eth*d i# called 3y giving it a =ind re9erence) >iven that C# i# particular a3*ut type checking, it #ee+# #trange that a +eth*d that accept# *ne type !ill readily accept an*ther type, until y*u reali7e that a =ind *34ect i# al#* an Bnstrument *34ect, and there# n* +eth*d that +une( ) c*uld call 9*r an Bnstrument that i#nt al#* in =ind) -n#ide +une( ), the c*de !*rk# 9*r Bnstrument and anything derived 9r*+ Bnstrument, and the act *9 c*nverting a =ind re9erence int* an Bnstrument re9erence i# called u"casting)

Wh5 Gu$castingH<
The rea#*n 9*r the ter+ i# hi#t*rical, and 3a#ed *n the !ay cla## inheritance diagra+# have traditi*nally 3een dra!n1 !ith the r**t at the t*p *9 the page, gr*!ing d*!n!ard) GO9 c*ur#e, y*u can dra! y*ur diagra+# any !ay y*u 9ind help9ul)H The inheritance diagra+ 9*r =ind6)ava i# then1

)#)

Thinking in C

www.ThinkingIn.!et

In stru # e n t

W in d

Ca#ting 9r*+ derived t* 3a#e +*ve# u" *n the inheritance diagra+, #* it# c*++*nly re9erred t* a# u"casting) Upca#ting i# al!ay# #a9e 3ecau#e y*ure g*ing 9r*+ a +*re #peci9ic type t* a +*re general type) That i#, the derived cla## i# a #uper#et *9 the 3a#e cla##) -t +ight c*ntain +*re +eth*d# than the 3a#e cla##, 3ut it +u#t c*ntain at least the +eth*d# in the 3a#e cla##) The *nly thing that can *ccur t* the cla## inter9ace during the upca#t i# that it can l*#e +eth*d#, n*t gain the+) Thi# i# !hy the c*+piler all*!# upca#ting !ith*ut any e;plicit ca#t# *r *ther #pecial n*tati*n) :*u can al#* per9*r+ the rever#e *9 upca#ting, called downcasting, 3ut thi# inv*lve# a dile++a that i# the #u34ect *9 Chapter 02)

Co#$osition vs. inheritance revisited


-n *34ectE*riented pr*gra++ing, the +*#t likely !ay that y*ull create and u#e c*de i# 3y #i+ply packaging data and +eth*d# t*gether int* a cla##, and u#ing *34ect# *9 that cla##) :*ull al#* u#e e;i#ting cla##e# t* 3uild ne! cla##e# !ith c*+p*#iti*n) Le## 9reDuently, y*ull u#e inheritance) S* alth*ugh inheritance get# a l*t *9 e+pha#i# !hile learning OOP, it d*e#nt +ean that y*u #h*uld u#e it every!here y*u p*##i3ly can) On the c*ntrary, y*u #h*uld u#e it #paringly, *nly !hen it# clear that inheritance i# u#e9ul) One *9 the cleare#t !ay# t* deter+ine !hether y*u #h*uld u#e c*+p*#iti*n *r inheritance i# t* a#k !hether y*ull ever need t* upca#t 9r*+ y*ur ne! cla## t* the 3a#e cla##) -9 y*u +u#t upca#t, then inheritance i# nece##ary, 3ut i9 y*u d*nt need t* upca#t, then y*u #h*uld l**k cl*#ely at !hether y*u need inheritance) The ne;t chapter Gp*ly+*rphi#+H pr*vide# *ne *9 the +*#t c*+pelling rea#*n# 9*r upca#ting, 3ut i9 y*u re+e+3er t* a#k I?* - need t* upca#tFJ y*ull have a g**d t**l 9*r deciding 3et!een c*+p*#iti*n and inheritance)

Cha"ter 6* ?eusing Classes

)#3

%&$licit Overloading Onl5


S*+e *9 C## +*#t n*ta3le departure# 9r*+ the *34ectE*riented n*r+ are the 3arrier# it place# *n the r*ad t* *verl*ading 9uncti*nality) -n +*#t *34ectE*riented language#, i9 y*u have cla##e# 5*rk and Sp**n that de#cend# 9r*+ Uten#il, a 3a#e +eth*d et:ood, and t!* i+ple+entati*n# *9 it, y*u 4u#t declare the +eth*d in the 3a#e and have identical #ignature# in the de#cending cla##e#1

-n "ava, thi# !*uld l**k like1 c a## Oten#i ; pu$ ic *oid _etHood01; //L< < c a## Hor% extend# Oten#i ; pu$ ic *oid _etHood01; Sy#te!.out.print n0ASpearB13 < < c a## Spoon extend# Oten#i ; pu$ ic *oid _etHood01; Sy#te!.out.print n0AScoopB13 < < -n C#, y*u have t* 4u+p thr*ugh a 3it *9 a h**pQ +eth*d# 9*r !hich *verl*ading i# intended +u#t 3e declared virtual and the *verl*ading

)#4

Thinking in C

www.ThinkingIn.!et

+eth*d +u#t 3e declared a# an override) T* get the de#ired #tructure !*uld l**k like thi#1 c a## Oten#i ; pu$ ic *irtua < *oid _etHood01; //L<

c a## Hor% extend# Oten#i ; pu$ ic o*erride *oid _etHood01; Sy#te!.out.print n0ASpearB13 < < c a## Spoon extend# Oten#i ; pu$ ic o*erride *oid _etHood01; Sy#te!.out.print n0AScoopB13 < < Thi# i# a 3ehavi*r that #te+# 9r*+ Aicr*#*9t# e;perience !ith I?LL HellJ and th*ught# a3*ut a !*rld in !hich *34ectE*riented c*+p*nent# are the 3uilding 3l*ck# *9 very large #y#te+#) -+agine that y*u are u#ing "ava and u#ing a /rdEparty INitchenJ c*+p*nent that include# the 3a#e cla## *9 Uten#il, 3ut y*u cu#t*+i7e it t* u#e that #taple *9 d*r+ li9e P the Sp*rk) But in additi*n t* i+ple+enting et:ood(), y*u add a d*r+Elike +eth*d =ash()1 //Spor%.Da*a c a## Spor% extend# Oten#i ; pu$ ic *oid _etHood01; Sy#te!.out.print n0ASpear OR Scoop!B13 < pu$ ic *oid Va#h01; Sy#te!.out.print n0AVipe .ith nap%inB13 < < O9 c*ur#e, #ince =ash i#nt i+ple+ented in Vtensil, y*u c*uld *nly I!a#hJ a #p*rk G!hich i# 4u#t a# !ell, c*n#idering the unhygienic nature *9 the i+ple+entati*nH) S* the pr*3le+ happen# !hen the /rdEparty Nitchen c*+p*nent vend*r relea#e# a ne! ver#i*n *9 their c*+p*nent, and thi#

Cha"ter 6* ?eusing Classes

)#5

ti+e theyve i+ple+ent a +eth*d !ith an identical #ignature t* the *ne y*u !r*te1 //Oten#i .Da*a \*er#ion: 2.0 c a## Oten#i ; pu$ ic *oid _etHood01; //L < pu$ ic *oid Va#h01; !y:i#h.a#her.add0thi#13 //etcL < < The vend*r ha# i+ple+ented a =ash() +eth*d !ith c*+ple; 3ehavi*r inv*lving a di#h!a#her) >iven thi# ne! capa3ility, pe*ple pr*gra++ing !ith Uten#il v2 !ill have every right t* a##u+e that *nce =ash() ha# 3een called, all Uten#il# !ill have g*ne thr*ugh the di#h!a#her) But in language# #uch a# "ava, the =ash() +eth*d in Sp*rk !ill #till 3e calledK

-t +ay #ee+ highly unlikely that a ne! ver#i*n *9 a 3a#e cla## !*uld I4u#t happenJ t* have the #a+e na+e a# an endEu#er# e;ten#i*n, 3ut i9 y*u think a3*ut it, it# actually kind *9 #urpri#ing it d*e#nt happen +*re *9ten, a# the nu+3er *9 l*gical +eth*d na+e# 9*r a given categ*ry *9 3a#e cla## i# 9airly li+ited) -n C#, the 3ehavi*r in Client# =ash'll() +eth*d !*uld !*rk e;actly the !ay client# e;pect, !ith Vtensil# di#h!a#her =ash() 3eing called 9*r all uten#il# in myVtensils, even i9 *ne happen# t* 3e a #por()

)#6

Thinking in C

www.ThinkingIn.!et

*! let# #ay y*u c*+e al*ng and #tart !*rking *n Sp*rk again a9ter upgrading t* the ver#i*n *9 Uten#il that ha# a =ash() +eth*d) ,hen y*u c*+pile Sp*rk)c#, the c*+piler !ill #ay1 .arning CS0"0I: 'he %ey.ord ne. i# re7uired on 'Spor%.Va#h01' $ecau#e it hide# inherited !e!$er 'Oten#i .Va#h01' =t thi# p*int, call# t* Vtensil6=ash() are re#*lved !ith the di#h!a#her !a#hing +eth*d, !hile i9 y*u have a handle t* a Sp*rk, the napkinE!iping !a#h +eth*d !ill 3e called) //:c0?:Oten#i .c# c a## Oten#i ; pu$ ic *irtua *oid _etHood01; < pu$ ic *oid Va#h01; Sy#te!.Con#o e.VriteLine0&Va#hing in a di#h.a#her&13 < < c a## Hor% : Oten#i ; pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear&13 < < c a## Spor% : Oten#i ; pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear OR Scoop!&13 < pu$ ic *oid Va#h01; Sy#te!.Con#o e.VriteLine0&Vipe .ith nap%in&13 < < c a## C ient; Oten#i JK !yOten#i #3

Cha"ter 6* ?eusing Classes

)##

C ient01; !yOten#i # 9 ne. Oten#i J2K3 !yOten#i #J0K 9 ne. Spor%013 !yOten#i #J"K 9 ne. Hor%013 < pu$ ic *oid Va#h) 01; foreach0Oten#i u in !yOten#i #1; u.Va#h013 < < pu$ ic #tatic *oid Gain01; C ient c 9 ne. C ient013 c.Va#h) 013 Spor% # 9 ne. Spor%013 #.Va#h013 < <///:8 re#ult# in the *utput1 Va#hing in a di#h.a#her Va#hing in a di#h.a#her Vipe .ith nap%in -n *rder t* re+*ve the !arning that #por(6=ash() i# hiding the ne!ly +inted Vtensil6=ash(), !e can add the key!*rd new t* #por(# declarati*n1 pu$ ic ne. *oid Va#h01; //L etc ... -t# even p*##i3le 9*r y*u t* have entirely #eparate +eth*d inheritance hierarchie# 3y declaring a +eth*d a# new virtual) -+agine that 9*r ver#i*n / *9 the Nitchen c*+p*nent, theyve created a ne! type *9 Vtensil, #ilverware, !hich reDuire# p*li#hing a9ter cleaning) Aean!hile, y*uve created a ne! kind *9 #por(, a #uper#por(, !hich al#* ha# *verridden the 3a#e #por(6=ash() +eth*d) The c*de l**k# like thi#1 //:c0?:Oten#i 2.c# c a## Oten#i ; pu$ ic *irtua *oid _etHood01; <

)#&

Thinking in C

www.ThinkingIn.!et

pu$ ic *irtua *oid Va#h01; Sy#te!.Con#o e.VriteLine0&Va#hing in a di#h.a#her&13 < < c a## Si *er.are : Oten#i ; pu$ ic o*erride *oid Va#h01; $a#e.Va#h013 Sy#te!.Con#o e.VriteLine0&-o i#h .ith #i *er c eaner&13 < < c a## Hor% : Si *er.are; pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear&13 < < c a## Spor% : Si *er.are; pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear OR Scoop!&13 < pu$ ic ne. *irtua *oid Va#h01; Sy#te!.Con#o e.VriteLine0&Vipe .ith nap%in&13 < < c a## SuperSpor% : Spor%; pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear )C: Scoop&13 < pu$ ic o*erride *oid Va#h01; $a#e.Va#h013 Sy#te!.Con#o e.VriteLine0&-o i#h .ith #hirt&13 < <

Cha"ter 6* ?eusing Classes

)#'

c a## C ient; Oten#i JK !yOten#i #3 C ient01; !yOten#i # 9 ne. Oten#i JTK3 !yOten#i #J0K 9 ne. Spor%013 !yOten#i #J"K 9 ne. Hor%013 !yOten#i #J2K 9 ne. SuperSpor%013 < pu$ ic *oid Va#h) 01; foreach0Oten#i u in !yOten#i #1; u.Va#h013 < Sy#te!.Con#o e.VriteLine0&) Oten#i # .a#hed&13 < pu$ ic #tatic *oid Gain01; C ient c 9 ne. C ient013 c.Va#h) 013 Spor% # 9 ne. SuperSpor%013 #.Va#h013 < <///:8 *!, all *9 *ur Uten#il# have 3een replaced 3y Silver!are and, !hen Client),a#h=llGH i# called, #ilverware6=ash() *verl*ad# Vtensil6=ash()) G *te that #ilverware6=ash() call# Vtensil6=ash() u#ing base6=ash(), in the #a+e +anner a# 3a#e c*n#truct*r# can 3e called)H =ll Uten#il# in Client# )+yUten#il# array are n*! !a#hed in a di#h!a#her and then p*li#hed) *te the declarati*n in Sp*rk1 pu$ ic ne. *irtua *oid Va#h01; //etc <

and the declarati*n in the ne!ly +inted #uper#por( cla##1 pu$ ic o*erride *oid Va#h01; //etc. <

)&(

Thinking in C

www.ThinkingIn.!et

,hen the Client cla## ha# a re9erence t* a Uten#il #uch a# it d*e# in =ash'llGH G!hether the c*ncrete type *9 that Uten#il 3e a 5*rk, a Sp**n, *r a Sp*rkH, the =ash() +eth*d re#*lve# t* the appr*priate *verl*aded +eth*d in #ilverware) ,hen, h*!ever, the client ha# a re9erence t* a Sp*rk *r any Sp*rkE#u3type, the =ash() +eth*d re#*lve# t* !hatever ha# *verl*aded #por(# new virtual =ash()) The *utput l**k# like thi#1 Va#hing in a di#h.a#her -o i#h .ith #i *er c eaner Va#hing in a di#h.a#her -o i#h .ith #i *er c eaner Va#hing in a di#h.a#her -o i#h .ith #i *er c eaner ) Oten#i # .a#hed Vipe .ith nap%in -o i#h .ith #hirt =nd thi# UAL diagra+ #h*!# the 3ehavi*r graphically1

Cha"ter 6* ?eusing Classes

)&1

Let# #ay that y*u !anted t* create a ne! cla## #elfCleansing#uper#por(, that *verl*aded 3*th the =ash() +eth*d a# de9ined in Vtensil and the =ash() +eth*d a# de9ined in #por() ,hat c*uld y*u d*F :*u cann*t create a #ingle +eth*d na+e that *verride# 3*th 3a#e +eth*d#) =# i# generally the ca#e, !hen 9aced !ith a hard pr*gra++ing pr*3le+, the an#!er lie# in de#ign, n*t language #ynta;) Re+e+3er *ur +a;i+1 3*ring c*de, intere#ting re#ult#) One *9 the 9ir#t thing# that 4u+p# *ut !hen c*n#idering thi# pr*3le+ i# that the inheritance hierarchy i# getting deep) ,hat !ere pr*p*#ing i# that a #elfCleaning#uper#por( i#Ea #uper#por( i#Ea #por( i#Ea #ilverware i#Ea Vtensil i#Ean ob)ect) That# #i; level# *9 hierarchy P *ne +*re than Linnaeu# u#ed t* cla##i9y all living 3eing# in 0%/'K -t# n*t i+p*##i3le 9*r a de#ign t* have thi# +any layer# *9 inheritance, 3ut in general, *ne #h*uld 3e du3i*u# *9 hierarchie# *9 +*re than t!* *r three level# 3el*! ob)ect6

)&)

Thinking in C

www.ThinkingIn.!et

Bearing in +ind that *ur hierarchy i# getting deep, !e +ight al#* n*tice that *ur na+e# are 3ec*+ing l*ng and unnatural P #elfCleaning#uper#por(6 ,hile c*+ing up !ith de#criptive na+e# !ith*ut getting cute i# *ne *9 the harder ta#k# in pr*gra++ing EE - cant tell y*u h*! +any execute(), run(), and %uery() +eth*d# -ve #een, !hile -ve heard a #t*ry *9 a varia3le la3eled beethoven 3ecau#e it# initial value happened t* 3e 020., the c*+p*#er# 3irthday P #*+ething# !r*ng !hen a cla## na+e 3ec*+e# a h*dgeEp*dge *9 ad4ective#) -n thi# ca#e, *ur na+e# are 3eing u#ed t* di#tingui#h 3et!een t!* di99erent pr*pertie# P the #hape *9 the Uten#il G:or(, #poon, #por(, and #uper#por(H and the cleaning 3ehavi*r G#ilverware, #por(, and #elfCleaning#uper#por(H) Thi# i# a clue that *ur de#ign !*uld 3e 3etter u#ing c*+p*#iti*n rather than inheritance) =# i# very *9ten the ca#e, !e di#c*ver that *ne *9 the Ivect*r# *9 changeJ i# +*re naturally #tructural Gthe #hape *9 the uten#ilH and that an*ther i# +*re 3ehavi*ral Gthe cleaning regi+enH) ,e can try *ut the phra#e I= uten#il ha# a cleaning regi+en,J t* #ee i9 it #*und# right, !hich indeed it d*e#1

,hen a Uten#il i# c*n#tructed, it ha# a handle t* a particular type *9 cleaning regi+en, 3ut it# ,a#h +eth*d d*e#nt have t* kn*! the #peci9ic #u3type *9 CleaningRegi+en it i# u#ing1

Cha"ter 6* ?eusing Classes

)&3

Thi# i# called the @trateg4 Pattern and it i#, - think, the +*#t i+p*rtant *9 all the de#ign pattern#)

Thi# i# !hat the c*de !*uld l**k like1 //:c0?:Oten#i T.c# u#ing Sy#te!3

)&4

Thinking in C

www.ThinkingIn.!et

pu$ ic c a## Oten#i ; pri*ate C eaningRegi!en !yC eaningRegi!en3 protected Oten#i 0C eaningRegi!en reg1; !yC eaningRegi!en 9 reg3 < pu$ ic *oid Va#h01; !yC eaningRegi!en.Va#h013 < pu$ ic *irtua < < c a## Hor%; pu$ ic Hor%01 : $a#e0ne. :i#h.a#h011;< pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear food&13 < < c a## Spoon; pu$ ic Spoon01 : $a#e0ne. :i#h.a#h011;< pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Scoop food&13 < < c a## Spor%; pu$ ic Spor%01 : $a#e0ne. VipeVithCap%in011;< pu$ ic o*erride *oid _etHood01; Sy#te!.Con#o e.VriteLine0&Spear or #coop!&13 < < c a## C eaningRegi!en; protected o*erride *oid Va#h013 < *oid _etHood01;

Cha"ter 6* ?eusing Classes

)&5

c a## :i#h.a#h : C eaningRegi!en; protected o*erride *oid Va#h01; Sy#te!.Con#o e.VriteLine0&Va#h in di#h.a#her&13 < < c a## VipeVithCap%in : C eaningRegi!en; protected o*erride *oid Va#h01; Sy#te!.Con#o e.VriteLine0&Vipe .ith nap%in&13 < <///:8 =t thi# p*int, every type *9 Uten#il ha# a particular type *9 CleaningRegi+en a##*ciated !ith it, an a##*ciati*n !hich i# hardEc*ded in the c*n#truct*r# *9 the Uten#il #u3type# Gi)e), public #por(() D base(new =ipe=ith,ap(in())H) H*!ever, y*u can #ee h*! it !*uld 3e a trivial +atter t* t*tally dec*uple the Vtensil# type *9 Cleaning*egimen 9r*+ the c*n#truct*r P y*u c*uld pa## in the Cleaning*egimen 9r*+ #*+eplace el#e, ch**#e it rand*+ly, and #* 9*rth) ,ith thi# de#ign, *ne can ea#ily achieve *ur g*al *9 a #uper uten#il that c*+3ine# +ultiple cleaning #trategie#1 c a## SuperSpor% : Spor%; C eaningRegi!en #econdRegi!en3 pu$ ic SuperSpor%: #uper0ne. :i#h.a#h011; #econdRegi!en 9 ne. Cap%inVa#h013 < pu$ ic o*erride *oid Va#h01; $a#e.Va#h013 #econdRegi!en.Va#h013 < < -n thi# #ituati*n, the SuperSp*rk n*! ha# t!* CleaningRegi+en#, the n*r+al myCleaning*egimen and a ne! second*egimen) Thi# i# the type *9 9le;i3ility that y*u can h*pe t* achieve 3y 9av*ring aggregati*n *ver inheritance)

)&6

Thinking in C

www.ThinkingIn.!et

Our *riginal challenge, th*ugh, inv*lved a /rd party Nitchen c*+p*nent that pr*vided the 3a#ic de#ign) ,ith*ut acce## t* the #*urce c*de, there i# n* !ay t* i+ple+ent *ur i+pr*ved de#ign) Thi# i# *ne *9 the thing# that +ake# it hard t* !rite c*+p*nent# 9*r reu#e P I9ully 3akedJ c*+p*nent# that are ea#y t* u#e *ut *9 the 3*; are *9ten hard t* cu#t*+i7e and e;tend, !hile Ic*n#tructi*n kitJ c*+p*nent# that need t* 3e a##e+3led typically can #*+eti+e# take a l*ng ti+e t* learn)

-he const and readonly *e5words


- kn*! a CTO !h*, !hen revie!ing c*de #a+ple# *9 p*tential pr*gra++er#, #can# 9*r nu+eric c*n#tant# in the c*de P *ne #trike and the re#u+e g*e# in the tra#h) -+ happy - never #h*!ed hi+ any c*de *9 +ine that did calendar +ath, 3ecau#e - d*nt think UABER`O5`?=:S`- `,EEN i# clearer than %) everthele##, applicati*n c*de *9ten ha# l*t# *9 data that never change# and C# pr*vide# t!* ch*ice# a# t* h*! t* e+3*dy the+ in c*de) The const key!*rd can 3e applied t* 9ield# *9 !hat are called the Ivalue type#J1 #3yte, 3yte, #h*rt, u#h*rt, int, uint, l*ng, ul*ng, 9l*at, d*u3le, deci+al, 3**l, char, #tring, and enu+#) Calue type# di99er 9r*+ the +*re c*++*n Ire9erence type#J in that the runti+e d*e# n*t g* thr*ugh a level *9 indirecti*n t* reach value type#) Ot*d* i+age here const 9ield# are evaluated at c*+pileEti+e, all*!ing 9*r +arginal per9*r+ance i+pr*ve+ent#) 5*r in#tance1 //Cu!$er of !i i#econd# in a day con#t ong GSX-+RX:)/ 9 "000 = ?0 = ?0 = 2E3 ,ill 3e replaced at c*+pile ti+e !ith the #ingle value (.,&$$,$$$ rather than triggering three +ultiplicati*n# every ti+e it i# u#ed)

Cha"ter 6* ?eusing Classes

)&#

The readonly key!*rd i# +*re general) -t can 3e applied t* any type and i# evaluated *nceEandE*nlyE*nce at runti+e) Typically, readonly 9ield# are initiali7ed at either the ti+e *9 cla## l*ading Gin the ca#e *9 #tatic 9ield#H, *r at the ti+e *9 in#tance initiali7ati*n 9*r in#tance varia3le#) -t# n*t nece##ary t* li+it readonly 9ield# t* value# that are e##entially c*n#tant, y*u c*uld u#e a readonly 9ield 9*r any data that, *nce a##igned, #h*uld 3e invariant P a per#*n# na+e *r #*cial #ecurity nu+3er, a net!*rk addre## *r p*rt *9 a h*#t, etc) readonly d*e# n*t +ake an *34ect i++uta3le) ,hen applied t* a n*nE valueEtype *34ect, readonly l*ck# *nly y*ur re9erence t* the *34ect, n*t the #tate *9 the *34ect it#el9) Such an *34ect can g* thr*ugh !hatever #tate tran#iti*n# are pr*gra++ed int* it P pr*pertie# can 3e #et, it can change it# internal #tate 3a#ed *n calculati*n#, etc) The *nly thing y*u cant d* i# change the re9erence t* the *34ect) Thi# can 3e #een in thi# e;a+ple, !hich de+*n#trate# readonly) //:c0?:Co!po#ition.c# u#ing Sy#te!3 u#ing Sy#te!.'hreading3 na!e#pace Co!po#ition ; pu$ ic c a## ReadOn y; #tatic readon y :ate'i!e ti!eOfC a##Load 9 :ate'i!e.Co.3 readon y :ate'i!e ti!eOf5n#tanceCreation 9 :ate'i!e.Co.3 pu$ ic ReadOn y01 ; Sy#te!.Con#o e.VriteLine0&C a## oaded at ;0<2 5n#tance created at ;"<&2 ti!eOfC a##Load2 ti!eOf5n#tanceCreation13 < //u#ed in #econd part of progra! #tatic readon y ReadOn y ro 9 ne. ReadOn y013 pu$ ic int id3 pu$ ic int 5d; get; return id3 < #et; id 9 *a ue3 < <

)&&

Thinking in C

www.ThinkingIn.!et

pu$ ic #tatic *oid Gain01; for0int i 9 03 i W "03 iRR1; ne. ReadOn y013 'hread.S eep0"00013 < //Can change !e!$er ro.5d 9 P3 Sy#te!.Con#o e.VriteLine0ro.5d13 //! Co!pi er #ay# Aa #tatic readon y fie d cannot $e // a##igned toB //ro 9 ne. ReadOn y013 < < <///:8

-n *rder t* de+*n#trate h*! *34ect# created at di99erent ti+e# !ill have di99erent 9ield#, the pr*gra+ u#e# the Thread)SleepGH +eth*d 9r*+ the Threading na+e#pace, !hich !ill 3e di#cu##ed at length in #+ultithreading#) The cla## *ead1nly c*ntain# t!* readonly 9ield# P the #tatic +ime1fClassLoad 9ield and the in#tance varia3le time1fBnstanceCreation) The#e 9ield# are *9 type $ate+ime, !hich i# the 3a#ic ) ET *34ect 9*r c*unting ti+e) B*th 9ield# are initiali7ed 9r*+ the #tatic ?ateTi+e pr*perty *!, !hich repre#ent# the #y#te+ cl*ck) ,hen the .ain create# the 9ir#t *ead1nly *34ect and the #tatic 9ield# are initiali7ed a# di#cu##ed previ*u#ly, +ime1fClassLoad i# #et *nceE andE9*rEall) Then, the in#tance varia3le 9ield time1fBnstanceCreation i# initiali7ed) 5inally, the c*n#truct*r i# called, and it print# the value *9 the#e t!* 9ield# t* the c*n#*le) +hread6#leep(7444) i# then u#ed t* pau#e the pr*gra+ 9*r a #ec*nd G0,$$$ +illi#ec*nd#H 3e9*re creating an*ther *ead1nly) The 3ehavi*r *9 the pr*gra+ until thi# p*int !*uld 3e n* di99erent i9 the#e 9ield# !ere n*t declared a# readonly, #ince !e have +ade n* atte+pt t* +*di9y the 9ield#) That change# in the line# 3el*! the l**p) -n additi*n t* the readonly $ate+ime 9ield#, !e have a static readonly *ead1nly 9ield la3eled ro

Cha"ter 6* ?eusing Classes

)&'

Gthe cla## *ead1nly c*ntain# a re9erence t* an in#tance *9 *ead1nly P a c*++*n idi*+ that i# kn*!n a# a I#inglet*nJH) ,e al#* have a pr*perty called Bd, 3ut n*te that it i# n*t readonly) G=# a revie! *9 the di#cu##i*n in #initiali7ati*n#, y*u #h*uld 3e a3le t* 9igure *ut h*! the value# *9 ro# time1fClassLoad and time1fBnstanceCreation !ill relate t* the 9ir#t *ead1nly created in the .ain l**p)H =lth*ugh the re9erence t* ro i# read *nly, the line r*)-d X 'Q de+*n#trate# h*! it i# p*##i3le t* change the #tate *9 a readonly re9erence) ,hat !e cant d*, th*ugh, i# #h*!n in the c*++entedE*ut line# in the e;a+ple P i9 !e atte+pt t* a##ign t* ro, !ell get a c*+pile ti+e err*r) The advantage *9 readonly *ver const i# that const# c*+pileEti+e +ath i# i++uta3le) -9 a cla## Phy#icalC*n#tant# had a public const that #et the #peed *9 light t* /$$,$$$ kil*+eter# per #ec*nd and an*ther cla## u#ed that 9*r c*+pileEti+e +ath Gcon#t ong a5LOG+'+RSX5CX)XL5_U'X/+)R 9 -hy#ica Con#tant#.C = T?00 = 2E = :)/SX-+RX/+)RH, the value *9 a5LOG+'+RSX5CX)XL5_U'X/+)R !ill 3e 3a#ed *n the /$$,$$$ value, even i9 the 3a#e cla## i# updated t* a +*re accurate value #uch a# 266,%62) Thi# !ill 3e true until the cla## that de9ined EBL1.&+&*#AB,A'ALB "+A@&'* i# rec*+piled !ith acce## t* the updated Phy#icalC*n#tant# cla##) -9 the 9ield# !ere readonly th*ugh, the value 9*r EBL1.&+&*#AB,A'ALB "+A@&'* !*uld 3e calculated at runti+e, and !*uld n*t need t* 3e rec*+piled t* pr*perly re9lect the late#t value *9 C) =gain, thi# i# *ne *9 th*#e 9eature# !hich +ay n*t #ee+ like a 3ig deal t* +any applicati*n devel*per#, 3ut !h*#e nece##ity i# clear t* Aicr*#*9t a9ter a decade *9 I?LL Hell)J

'ealed classes
The readonly and const key!*rd# are u#ed 9*r l*cking d*!n value# and re9erence# that #h*uld n*t 3e changed) Becau#e *ne ha# t* declare a +eth*d a# virtual in *rder t* 3e *verridden, it i# ea#y t* create +eth*d# that !ill n*t 3e +*di9ied at runti+e) aturally, there i# a !ay t* #peci9y that an entire cla## 3e un+*di9ia3le) ,hen a cla## i# declared a# sealed, n* *ne can derive 9r*+ it)

)'(

Thinking in C

www.ThinkingIn.!et

There are t!* +ain rea#*n# t* +ake a cla## sealed) = sealed cla## i# +*re #ecure 9r*+ intenti*nal *r unintenti*nal ta+pering) =dditi*nally, virtual +eth*d# e;ecuted *n a sealed cla## can 3e replaced !ith direct 9uncti*n call#, pr*viding a #light per9*r+ance increa#e) //:c0?:`ura##ic.c# // Sea ing a c a## c a## S!a Brain ;<

#ea ed c a## :ino#aur ; interna int i 9 F3 interna int D 9 "3 S!a Brain x 9 ne. S!a interna *oid H01 ;< <

Brain013

//! c a## Hurther : :ino#aur ;< // error: Cannot extend #ea ed c a## ':ino#aur' pu$ ic c a## `ura##ic ; pu$ ic #tatic *oid Gain01 ; :ino#aur n 9 ne. :ino#aur013 n.H013 n.i 9 E03 n.DRR3 < <///:8 ?e9ining the cla## a# sealed #i+ply prevent# inheritanceRn*thing +*re) H*!ever, 3ecau#e it prevent# inheritance all +eth*d# in a sealed cla## are i+plicitly n*nEvirtual, #ince there# n* !ay t* *verride the+)

Ktodo, C# doesnt have 0inal argu#ents<

%#$hasi:e virtual 0unctions


-t can #ee+ #en#i3le t* +ake a# 9e! +eth*d# a# p*##i3le virtual and even t* declare a cla## a# sealed) :*u +ight 9eel that e99iciency i# very i+p*rtant !hen u#ing y*ur cla## and that n* *ne c*uld p*##i3ly !ant t* *verride y*ur +eth*d# any!ay) S*+eti+e# thi# i# true)

Cha"ter 6* ?eusing Classes

)'1

But 3e care9ul !ith y*ur a##u+pti*n#) -n general, it# di99icult t* anticipate h*! a cla## can 3e reu#ed, e#pecially a generalEpurp*#e cla##) Unle## y*u declare a +eth*d a# virtual, y*u prevent the p*##i3ility *9 reu#ing y*ur cla## thr*ugh inheritance in #*+e *ther pr*gra++er# pr*4ect #i+ply 3ecau#e y*u c*uldnt i+agine it 3eing u#ed that !ay)

Initiali:ation and class loading


-n +*re traditi*nal language#, pr*gra+# are l*aded all at *nce a# part *9 the #tartup pr*ce##) Thi# i# 9*ll*!ed 3y initiali7ati*n, and then the pr*gra+ 3egin#) The pr*ce## *9 initiali7ati*n in the#e language# +u#t 3e care9ully c*ntr*lled #* that the *rder *9 initiali7ati*n *9 static# d*e#nt cau#e tr*u3le) C@@, 9*r e;a+ple, ha# pr*3le+# i9 *ne static e;pect# an*ther static t* 3e valid 3e9*re the #ec*nd *ne ha# 3een initiali7ed) C# d*e#nt have thi# pr*3le+ 3ecau#e it take# a di99erent appr*ach t* l*ading) Becau#e everything in C# i# an *34ect, +any activitie# 3ec*+e ea#ier, and thi# i# *ne *9 the+) =# y*u !ill learn +*re 9ully in the ne;t chapter, the c*+piled c*de 9*r a #et *9 related cla##e# e;i#t# in their *!n #eparate 9ile, called an a##e+3ly) That 9ile i#nt l*aded until the c*de i# needed) -n general, y*u can #ay that ICla## c*de i# l*aded at the p*int *9 9ir#t u#e)J Thi# i# *9ten n*t until the 9ir#t *34ect *9 that cla## i# c*n#tructed, 3ut l*ading al#* *ccur# !hen a static 9ield *r static +eth*d i# acce##ed) The p*int *9 9ir#t u#e i# al#* !here the static initiali7ati*n take# place) =ll the static *34ect# and the static c*de 3l*ck !ill 3e initiali7ed in te;tual *rder Gthat i#, the *rder that y*u !rite the+ d*!n in the cla## de9initi*nH at the p*int *9 l*ading) The static#, *9 c*ur#e, are initiali7ed *nly *nce)

Initiali:ation with inheritance


-t# help9ul t* l**k at the !h*le initiali7ati*n pr*ce##, including inheritance, t* get a 9ull picture *9 !hat happen#) C*n#ider the 9*ll*!ing c*de1 //:c0?:Beet e.c#

)')

Thinking in C

www.ThinkingIn.!et

// 'he fu

proce## of initia iMation.

c a## 5n#ect ; int i 9 >3 interna int D3 interna 5n#ect01 ; -rt0&i 9 & R i R &2 D 9 & R D13 D 9 T>3 < #tatic int x" 9 -rt0&#tatic 5n#ect.x" initia iMed&13 interna #tatic int -rt0#tring #1 ; Sy#te!.Con#o e.VriteLine0#13 return EF3 < < c a## Beet e : 5n#ect ; int % 9 -rt0&Beet e.% initia iMed&13 Beet e01 ; -rt0&% 9 & R %13 -rt0&D 9 & R D13 < #tatic int x2 9 -rt0&#tatic Beet e.x2 initia iMed&13 pu$ ic #tatic *oid Gain01 ; -rt0&Beet e con#tructor&13 Beet e $ 9 ne. Beet e013 < < ///:8 The *utput 9*r thi# pr*gra+ i#1 #tatic 5n#ect.x" initia iMed #tatic Beet e.x2 initia iMed Beet e con#tructor i 9 >2 D 9 0 Beet e.% initia iMed % 9 EF D 9 T>

Cha"ter 6* ?eusing Classes

)'3

The 9ir#t thing that happen# !hen y*u run Beetle i# that y*u try t* acce## Beetle6.ain( ) Ga static +eth*dH, #* the l*ader g*e# *ut and 9ind# the c*+piled c*de 9*r the Beetle cla## Gthi# happen# t* 3e in an a##e+3ly called Beetle6exeH) -n the pr*ce## *9 l*ading it, the l*ader n*tice# that it ha# a 3a#e cla## Gthat# !hat the c*l*n a9ter class Beetle #ay#H, !hich it then l*ad#) Thi# !ill happen !hether *r n*t y*ure g*ing t* +ake an *34ect *9 that 3a#e cla##) GTry c*++enting *ut the *34ect creati*n t* pr*ve it t* y*ur#el9)H -9 the 3a#e cla## ha# a 3a#e cla##, that #ec*nd 3a#e cla## !*uld then 3e l*aded, and #* *n) e;t, the static initiali7ati*n in the r**t 3a#e cla## Gin thi# ca#e, BnsectH i# per9*r+ed, and then the ne;t derived cla##, and #* *n) Thi# i# i+p*rtant 3ecau#e the derivedEcla## #tatic initiali7ati*n +ight depend *n the 3a#e cla## +e+3er 3eing initiali7ed pr*perly) =t thi# p*int, the nece##ary cla##e# have all 3een l*aded #* the *34ect can 3e created) 5ir#t, all the pri+itive# in thi# *34ect are #et t* their de9ault value# and the *34ect re9erence# are #et t* nullRthi# happen# in *ne 9ell #!**p 3y #etting the +e+*ry in the *34ect t* 3inary 7er*) Then the 3a#eE cla## c*n#truct*r !ill 3e called) -n thi# ca#e the call i# aut*+atic, 3ut y*u can al#* #peci9y the 3a#eEcla## c*n#truct*r call Ga# the 9ir#t *perati*n in the Beetle( ) c*n#truct*rH u#ing base) The 3a#e cla## c*n#tructi*n g*e# thr*ugh the #a+e pr*ce## in the #a+e *rder a# the derivedEcla## c*n#truct*r) =9ter the 3a#eEcla## c*n#truct*r c*+plete#, the in#tance varia3le# are initiali7ed in te;tual *rder) 5inally, the re#t *9 the 3*dy *9 the c*n#truct*r i# e;ecuted)

'u##ar5
B*th inheritance and c*+p*#iti*n all*! y*u t* create a ne! type 9r*+ e;i#ting type#) Typically, h*!ever, y*u u#e c*+p*#iti*n t* reu#e e;i#ting type# a# part *9 the underlying i+ple+entati*n *9 the ne! type, and inheritance !hen y*u !ant t* reu#e the inter9ace) Since the derived cla## ha# the 3a#eEcla## inter9ace, it can 3e u"cast t* the 3a#e, !hich i# critical 9*r p*ly+*rphi#+, a# y*ull #ee in the ne;t chapter) ?e#pite the #tr*ng e+pha#i# *n inheritance in *34ectE*riented pr*gra++ing, !hen y*u #tart a de#ign y*u #h*uld generally pre9er c*+p*#iti*n during the 9ir#t cut and u#e inheritance *nly !hen it i# clearly

)'4

Thinking in C

www.ThinkingIn.!et

nece##ary) C*+p*#iti*n tend# t* 3e +*re 9le;i3le) -n additi*n, 3y u#ing the added arti9ice *9 inheritance !ith y*ur +e+3er type, y*u can change the e;act type, and thu# the 3ehavi*r, *9 th*#e +e+3er *34ect# at runE ti+e) There9*re, y*u can change the 3ehavi*r *9 the c*+p*#ed *34ect at runEti+e) =lth*ugh c*de reu#e thr*ugh c*+p*#iti*n and inheritance i# help9ul 9*r rapid pr*4ect devel*p+ent, y*ull generally !ant t* rede#ign y*ur cla## hierarchy 3e9*re all*!ing *ther pr*gra++er# t* 3ec*+e dependent *n it) :*ur g*al i# a hierarchy in !hich each cla## ha# a #peci9ic u#e and i# neither t** 3ig Genc*+pa##ing #* +uch 9uncti*nality that it# un!ieldy t* reu#eH n*r ann*yingly #+all Gy*u cant u#e it 3y it#el9 *r !ith*ut adding 9uncti*nalityH)

%&ercises

Cha"ter 6* ?eusing Classes

)'5

D, Inter0aces and I#$le#entation


-nheritance i# all !ell and g**d, 3ut p*ly+*rphi#+ i# the true c*rner#t*ne *9 *34ectE *riented pr*gra++ing) ,hat di#tingui#he# an OOP pr*gra+ i# that c*ntr*l i# per9*r+ed pri+arily 3y p*ly+*rphi#+, not 9l*!Ec*ntr*l #tate+ent# #uch a# i9) Thi# chapter tie# the previ*u# 9*ur chapter# t*gether int* a #ingle appr*ach t* #*9t!are architecture that #cale# 9r*+ *ne hundred line# *9 c*de t* a hundred th*u#and line# and 3ey*nd) S+all, #i+ple e;a+ple# are u#ed t* de+*n#trate the techniDue# that are u#ed *verEandE*ver again t* create even the +*#t c*+ple; #*9t!are #y#te+#) Structural and 3ehavi*ral pattern# are 3rie9ly di#cu##ed and reader# are put *n the path t*!ard# c*+p*#ing #y#te+# 9r*+ gr*up# *9 pattern#)

Cha"ter 6* ?eusing Classes

)'#

P*ly+*rphi#+ i# the ne;t e##ential 9eature *9 an *34ectE *riented pr*gra++ing language a9ter data a3#tracti*n) -t all*!# pr*gra+# t* 3e devel*ped in the 9*r+ *9 interacting agree+ent# *r Ic*ntract#J that #peci9y the 3ehavi*r, 3ut n*t the i+ple+entati*n, *9 cla##e#)
P*ly+*rphi#+ pr*vide# a di+en#i*n *9 #eparati*n *9 inter9ace 9r*+ i+ple+entati*n, t* dec*uple what 9r*+ how) P*ly+*rphi#+ all*!# i+pr*ved c*de *rgani7ati*n and reada3ility a# !ell a# the creati*n *9 e%tensi2le pr*gra+# that can 3e Igr*!nJ n*t *nly during the *riginal creati*n *9 the pr*4ect 3ut al#* !hen ne! 9eature# are de#ired) Encap#ulati*n create# ne! data type# 3y c*+3ining characteri#tic# and 3ehavi*r#) -+ple+entati*n hiding #eparate# the inter9ace 9r*+ the i+ple+entati*n 3y +aking the detail# private) Thi# #*rt *9 +echanical *rgani7ati*n +ake# ready #en#e t* #*+e*ne !ith a pr*cedural pr*gra++ing 3ackgr*und) But p*ly+*rphi#+ deal# !ith dec*upling in ter+# *9 t4"es) -n the la#t chapter, y*u #a! h*! inheritance all*!# the treat+ent *9 an *34ect a# it# *!n type or it# 3a#e type) Thi# a3ility i# critical 3ecau#e it all*!# +any type# Gderived 9r*+ the #a+e 3a#e typeH t* 3e treated a# i9 they !ere *ne type, and a #ingle piece *9 c*de t* !*rk *n all th*#e di99erent type# eDually) The p*ly+*rphic +eth*d call all*!# *ne type t* e;pre## it# di#tincti*n 9r*+ an*ther, #i+ilar type, a# l*ng a# theyre 3*th derived 9r*+ the #a+e 3a#e type) Thi# di#tincti*n i# e;pre##ed thr*ugh di99erence# in 3ehavi*r *9 the +eth*d# that y*u can call thr*ugh the 3a#e cla##)

)''

-n thi# chapter, y*ull learn a3*ut p*ly+*rphi#+ Gal#* called d4namic 2inding *r late 2inding *r run9time 2indingH #tarting 9r*+ the 3a#ic#, !ith #i+ple e;a+ple# that #trip a!ay everything 3ut the p*ly+*rphic 3ehavi*r *9 the pr*gra+)

>$casting revisited
-n Chapter #Reu#ing y*ur *34ect## y*u #a! h*! an *34ect can 3e u#ed a# it# *!n type *r a# an *34ect *9 it# 3a#e type) Taking an *34ect re9erence and treating it a# a re9erence t* it# 3a#e type i# called u"casting6 3ecau#e *9 the !ay inheritance tree# are dra!n !ith the 3a#e cla## at the t*p) :*u al#* #a! a pr*3le+ ari#e, !hich i# e+3*died in the 9*ll*!ing1 //:c0F:Gu#ic.c# // 5nheritance @ upca#ting. pu$ ic c a## Cote ; pri*ate int *a ue3 pri*ate Cote0int *a 1 ; *a ue 9 *a 3 < pu$ ic #tatic Cote G5::L+XC 9 ne. Cote0012 CXSU)R- 9 ne. Cote0"12 BXHL)' 9 ne. Cote0213 < // +tc. pu$ ic c a## 5n#tru!ent ;

3((

pu$ ic *irtua *oid - ay0Cote n1 ; Sy#te!.Con#o e.VriteLine0&5n#tru!ent.- ay01&13 < < // Vind o$Dect# are in#tru!ent# // $ecau#e they ha*e the #a!e interface: pu$ ic c a## Vind : 5n#tru!ent ; // Redefine interface !ethod: pu$ ic o*erride *oid - ay0Cote n1 ; Sy#te!.Con#o e.VriteLine0&Vind.- ay01&13 < < pu$ ic c a## Gu#ic ; pu$ ic #tatic *oid 'une05n#tru!ent i1 ; // ... i.- ay0Cote.G5::L+XC13 < pu$ ic #tatic *oid Gain01 ; Vind f ute 9 ne. Vind013 'une0f ute13 // Opca#ting < < ///:8 The +eth*d .usic6+une( ) accept# an Bnstrument re9erence, 3ut al#* anything derived 9r*+ Bnstrument) -n .ain( ), y*u can #ee thi# happening a# a =ind re9erence i# pa##ed t* +une( ), !ith n* ca#t nece##ary) Thi# i# accepta3leQ the inter9ace in Bnstrument +u#t e;i#t in =ind, 3ecau#e =ind i# inherited 9r*+ Bnstrument) Upca#ting 9r*+ =ind t* Bnstrument +ay Inarr*!J that inter9ace, 3ut it cann*t +ake it anything le## than the 9ull inter9ace t* Bnstrument)

7orgetting the o+/ect t5$e


Thi# pr*gra+ +ight #ee+ #trange t* y*u) ,hy #h*uld any*ne intenti*nally $orget the type *9 an *34ectF Thi# i# !hat happen# !hen y*u upca#t, and it #ee+# like it c*uld 3e +uch +*re #traight9*r!ard i9 +une( ) #i+ply take# a =ind re9erence a# it# argu+ent) Thi# 3ring# up an e##ential p*int1 -9 y*u did that, y*ud need t* !rite a ne! +une( ) 9*r

Cha"ter #* /ol4mor"hism

3(1

every type *9 Bnstrument in y*ur #y#te+) Supp*#e !e 9*ll*! thi# rea#*ning and add #tringed and Brass in#tru+ent#1 //:c0F:Gu#ic2.c# // O*er oading in#tead of upca#ting. c a## Cote ; pri*ate int *a ue3 pri*ate Cote0int *a 1 ; *a ue 9 *a 3 < pu$ ic #tatic readon y Cote G5::L+XC 9 ne. Cote0012 CXSU)R- 9 ne. Cote0"12 BXHL)' 9 ne. Cote0213 < // +tc. c a## 5n#tru!ent ; interna *irtua *oid - ay0Cote n1 ; Sy#te!.Con#o e.VriteLine0&5n#tru!ent.- ay01&13 < < c a## Vind : 5n#tru!ent ; interna o*erride *oid - ay0Cote n1 ; Sy#te!.Con#o e.VriteLine0&Vind.- ay01&13 < < c a## Stringed : 5n#tru!ent ; interna o*erride *oid - ay0Cote n1 ; Sy#te!.Con#o e.VriteLine0&Stringed.- ay01&13 < < c a## Bra## : 5n#tru!ent ; interna o*erride *oid - ay0Cote n1 ; Sy#te!.Con#o e.VriteLine0&Bra##.- ay01&13 < < pu$ ic c a## Gu#ic2 ; interna #tatic *oid 'une0Vind i1 ;

3()

Thinking in C

www.ThinkingIn.!et

i.- ay0Cote.G5::L+XC13 < interna #tatic *oid 'une0Stringed i1 ; i.- ay0Cote.G5::L+XC13 < interna #tatic *oid 'une0Bra## i1 ; i.- ay0Cote.G5::L+XC13 < pu$ ic #tatic *oid Gain01 ; Vind f ute 9 ne. Vind013 Stringed *io in 9 ne. Stringed013 Bra## frenchUorn 9 ne. Bra##013 'une0f ute13 // Co upca#ting 'une0*io in13 'une0frenchUorn13 < < ///:8 Thi# !*rk#, 3ut there# a +a4*r dra!3ack1 :*u +u#t !rite typeE#peci9ic +eth*d# 9*r each ne! Bnstrument cla## y*u add) Thi# +ean# +*re pr*gra++ing in the 9ir#t place, 3ut it al#* +ean# that i9 y*u !ant t* add a ne! +eth*d like +une( ) *r a ne! type *9 Bnstrument, y*uve g*t a l*t *9 !*rk t* d*) =dd the 9act that the c*+piler !*nt give y*u any err*r +e##age# i9 y*u 9*rget t* *verl*ad *ne *9 y*ur +eth*d# and the !h*le pr*ce## *9 !*rking !ith type# 3ec*+e# un+anagea3le) ,*uldnt it 3e +uch nicer i9 y*u c*uld 4u#t !rite a #ingle +eth*d that take# the 3a#e cla## a# it# argu+ent, and n*t any *9 the #peci9ic derived cla##e#F That i#, !*uldnt it 3e nice i9 y*u c*uld 9*rget that there are derived cla##e#, and !rite y*ur c*de t* talk *nly t* the 3a#e cla##F That# e;actly !hat p*ly+*rphi#+ all*!# y*u t* d*) H*!ever, +*#t pr*gra++er# !h* c*+e 9r*+ a pr*cedural pr*gra++ing 3ackgr*und have a 3it *9 tr*u3le !ith the !ay p*ly+*rphi#+ !*rk#)

-he twist
The di99iculty !ith .usic)cs can 3e #een 3y running the pr*gra+) The *utput i# =ind6!lay( )) Thi# i# clearly the de#ired *utput, 3ut it d*e#nt

Cha"ter #* /ol4mor"hism

3(3

#ee+ t* +ake #en#e that it !*uld !*rk that !ay) L**k at the +une( ) +eth*d1 pu$ ic #tatic *oid tune05n#tru!ent i1 ; // ... i.- ay0Cote.G5::L+XC13 < -t receive# an Bnstrument re9erence) S* h*! can the c*+piler p*##i3ly kn*! that thi# Bnstrument re9erence p*int# t* a =ind in thi# ca#e and n*t a Brass *r #tringedF The c*+piler cant) T* get a deeper under#tanding *9 the i##ue, it# help9ul t* e;a+ine the #u34ect *9 2inding)

@ethod;call +inding
C*nnecting a +eth*d call t* a +eth*d 3*dy i# called 2inding) ,hen 3inding i# per9*r+ed 3e9*re the pr*gra+ i# run G3y the c*+piler and linker, i9 there i# *neH, it# called earl4 2inding) :*u +ight n*t have heard the ter+ 3e9*re 3ecau#e it ha# never 3een an *pti*n !ith pr*cedural language#) C c*+piler# have *nly *ne kind *9 +eth*d call, and that# early 3inding) The c*n9u#ing part *9 the a3*ve pr*gra+ rev*lve# ar*und early 3inding 3ecau#e the c*+piler cann*t kn*! the c*rrect +eth*d t* call !hen it ha# *nly an Bnstrument re9erence) The #*luti*n i# called late 2inding, !hich +ean# that the 3inding *ccur# at runEti+e 3a#ed *n the type *9 *34ect) Late 3inding i# al#* called d4namic 2inding *r run9time 2inding) ,hen a language i+ple+ent# late 3inding, there +u#t 3e #*+e +echani#+ t* deter+ine the type *9 the *34ect at runEti+e and t* call the appr*priate +eth*d) That i#, the c*+piler #till d*e#nt kn*! the *34ect type, 3ut the +eth*dEcall +echani#+ 9ind# *ut and call# the c*rrect +eth*d 3*dy) The lateE3inding +echani#+ varie# 9r*+ language t* language, 3ut y*u can i+agine that #*+e #*rt *9 type in9*r+ati*n +u#t 3e in#talled in the *34ect#) O3vi*u#ly, #ince there# additi*nal 3ehavi*r at runti+e, late 3inding i# a little +*re ti+eEc*n#u+ing than early 3inding) A*re i+p*rtantly, i9 a +eth*d i# early 3*und and #*+e *ther c*nditi*n# are +et, an *pti+i7ing c*+piler +ay decide n*t t* +ake a call at all, 3ut in#tead t* place a c*py

3(4

Thinking in C

www.ThinkingIn.!et

*9 the +eth*d# #*urce c*de directly int* the #*urce c*de !here the call *ccur#) Such inlining +ay cau#e the re#ulting 3inary c*de t* 3e a little larger, 3ut can re#ult in #igni9icant per9*r+ance increa#e# in tight l**p#, e#pecially !hen the called +eth*d i# #+all) =dditi*nally, the c*ntent# *9 an earlyE3*und +eth*d can 3e analy7ed and additi*nal *pti+i7ati*n# that can never 3e #a9ely applied t* lateE3*und +eth*d# G#uch a# aggre##ive code motion *pti+i7ati*n#H +ay 3e p*##i3le) T* give y*u an idea, a 2$$0 #tudy0 #h*!ed 5*rtranE6$ running #everal ti+e# a# 9a#t a#, and #*+eti+e# +*re than an *rder *9 +agnitude 9a#ter than, "ava *n a #erie# *9 +athE *riented 3ench+ark# Gthe auth*r# pr*t*type per9*r+anceE*riented "ava c*+piler and li3rarie# gave dra+atic #peedup#H) - p*rted #*+e *9 the 3ench+ark# t* C# and !a# di#app*inted t* #ee re#ult# that !ere very c*+para3le t* "ava per9*r+ance2) =ll +eth*d# declared a# virtual *r override in C# u#e late 3inding, *ther!i#e, they u#e early 3inding Gc*n9ir+H) Thi# i# an irritati*n 3ut n*t a 3ig 3urden) There are t!* #cenari*#1 either y*u kn*! that y*ure g*ing t* *verride a +eth*d later *n, in !hich ca#e it# n* 3ig deal t* add the key!*rd, *r y*u di#c*ver d*!n the r*ad that y*u need t* *verride a +eth*d that y*u hadnt planned *n *verriding, !hich i# a #igni9icant en*ugh de#ign change t* 4u#ti9y a reEe;a+inati*n and rec*+pilati*n *9 the 3a#e cla## c*deK The *ne thing y*u cant d* i# change the 3inding 9r*+ earlyE3*und t* lateE3*und in a c*+p*nent 9*r !hich y*u cant per9*r+ a rec*+pile 3ecau#e y*u d*nt have the #*urce c*de)

Producing the right +ehavior


Once y*u kn*! that virtual +eth*d 3inding in C# happen# p*ly+*rphically via late 3inding, y*u can !rite y*ur c*de t* talk t* the 3a#e cla## and kn*! that all the derivedEcla## ca#e# !ill !*rk c*rrectly u#ing the #a+e c*de) Or t* put it an*ther !ay, y*u I#end a +e##age t* an *34ect and let the *34ect 9igure *ut the right thing t* d*)J The cla##ic e;a+ple in OOP i# the I#hapeJ e;a+ple) Thi# i# c*++*nly u#ed 3ecau#e it i# ea#y t* vi#uali7e, 3ut un9*rtunately it can c*n9u#e n*vice pr*gra++er# int* thinking that OOP i# 4u#t 9*r graphic# pr*gra++ing, !hich i# *9 c*ur#e n*t the ca#e)
0 The

in4a Pr*4ect, A*reira et al), C=CA &&G0$H, Oct 2$$0

2 5*r detail#, #ee !!!)thinkingin)net

Cha"ter #* /ol4mor"hism

3(5

The #hape e;a+ple ha# a 3a#e cla## called #hape and vari*u# derived type#1 Circle, #%uare, +riangle, etc) The rea#*n the e;a+ple !*rk# #* !ell i# that it# ea#y t* #ay Ia circle i# a type *9 #hapeJ and 3e under#t**d) The inheritance diagra+ #h*!# the relati*n#hip#1

Cast =u$= the inheritance diagra#

Shape 4raw12 %rase12

Circle Circle 9andle 4raw12 %rase12

Square 4raw12 %rase12

Triangle 4raw12 %rase12

The upca#t c*uld *ccur in a #tate+ent a# #i+ple a#1 Shape # 9 ne. Circ e013

Here, a Circle *34ect i# created and the re#ulting re9erence i# i++ediately a##igned t* a #hape, !hich !*uld #ee+ t* 3e an err*r Ga##igning *ne type t* an*therHQ and yet it# 9ine 3ecau#e a Circle is a #hape 3y inheritance) S* the c*+piler agree# !ith the #tate+ent and d*e#nt i##ue an err*r +e##age) Supp*#e y*u call *ne *9 the 3a#eEcla## +eth*d# Gthat have 3een *verridden in the derived cla##e#H1 #.:ra.013 =gain, y*u +ight e;pect that #hape# $raw( ) i# called 3ecau#e thi# i#, a9ter all, a #hape re9erenceR#* h*! c*uld the c*+piler kn*! t* d* anything el#eF =nd yet the pr*per Circle6$raw( ) i# called 3ecau#e *9 late 3inding Gp*ly+*rphi#+H)

3(6

Thinking in C

www.ThinkingIn.!et

The 9*ll*!ing e;a+ple put# it a #lightly di99erent !ay1 //:c0F:Shape#.c# // -o y!orphi#! in C( u#ing Sy#te!3 pu$ ic c a## Shape ; interna *irtua *oid :ra.01 ;< interna *irtua *oid +ra#e01 ;< < c a## Circ e : Shape ; interna o*erride *oid :ra.01 ; Sy#te!.Con#o e.VriteLine0&Circ e.:ra.01&13 < interna o*erride *oid +ra#e01 ; Sy#te!.Con#o e.VriteLine0&Circ e.+ra#e01&13 < < c a## S7uare : Shape ; interna o*erride *oid :ra.01 ; Sy#te!.Con#o e.VriteLine0&S7uare.:ra.01&13 < interna o*erride *oid +ra#e01 ; Sy#te!.Con#o e.VriteLine0&S7uare.+ra#e01&13 < < c a## 'riang e : Shape ; interna o*erride *oid :ra.01 ; Sy#te!.Con#o e.VriteLine0&'riang e.:ra.01&13 < interna o*erride *oid +ra#e01 ; Sy#te!.Con#o e.VriteLine0&'riang e.+ra#e01&13 < < pu$ ic c a## Shape# ; #tatic Rando! rand 9 ne. Rando!013

Cha"ter #* /ol4mor"hism

3(#

pu$ ic #tatic Shape RandShape01 ; #.itch0rand.Cext0T11 ; ca#e 0: return ne. Circ e013 ca#e ": return ne. S7uare013 ca#e 2: return ne. 'riang e013 defau t: return nu 3 < < pu$ ic #tatic *oid Gain01 ; ShapeJK # 9 ne. ShapeJ>K3 // Hi up the array .ith #hape#: for0int i 9 03 i W #.Length3iRR1 #JiK 9 RandShape013 // Ga%e po y!orphic !ethod ca #: foreach0Shape aShape in #1 aShape.:ra.013 < < ///:8 The 3a#e cla## #hape e#ta3li#he# the c*++*n inter9ace t* anything inherited 9r*+ #hapeRthat i#, all #hape# can 3e dra!n and era#ed) The derived cla##e# *verride the#e de9initi*n# t* pr*vide uniDue 3ehavi*r 9*r each #peci9ic type *9 #hape) The +ain cla## #hapes c*ntain# a static +eth*d *and#hape( ) that pr*duce# a re9erence t* a rand*+lyE#elected #hape *34ect each ti+e y*u call it) *te that the upca#ting happen# in the return #tate+ent#, each *9 !hich take# a re9erence t* a Circle, #%uare, *r +riangle and #end# it *ut *9 the +eth*d a# the return type, #hape) S* !henever y*u call thi# +eth*d y*u never get a chance t* #ee !hat #peci9ic type it i#, #ince y*u al!ay# get 3ack a plain #hape re9erence) .ain( ) c*ntain# an array *9 #hape re9erence# 9illed thr*ugh call# t* *and#hape( )) =t thi# p*int y*u kn*! y*u have #hape#, 3ut y*u d*nt kn*! anything +*re #peci9ic than that Gand neither d*e# the c*+pilerH) H*!ever, !hen y*u #tep thr*ugh thi# array and call $raw( ) 9*r each *ne, the c*rrect typeE#peci9ic 3ehavi*r +agically *ccur#, a# y*u can #ee 9r*+ *ne *utput e;a+ple1 Circ e.:ra.01 'riang e.:ra.01 Circ e.:ra.01

3(&

Thinking in C

www.ThinkingIn.!et

Circ e.:ra.01 Circ e.:ra.01 S7uare.:ra.01 'riang e.:ra.01 S7uare.:ra.01 S7uare.:ra.01 O9 c*ur#e, #ince the #hape# are all ch*#en rand*+ly each ti+e, y*ur run# !ill have di99erent re#ult#) The p*int *9 ch**#ing the #hape# rand*+ly i# t* drive h*+e the under#tanding that the c*+piler can have n* #pecial kn*!ledge that all*!# it t* +ake the c*rrect call# at c*+pileEti+e) =ll the call# t* $raw( ) are +ade thr*ugh dyna+ic 3inding)

%&tensi+ilit5
*! let# return t* the +u#ical in#tru+ent e;a+ple) Becau#e *9 p*ly+*rphi#+, y*u can add a# +any ne! type# a# y*u !ant t* the #y#te+ !ith*ut changing the +une( ) +eth*d) -n a !ellEde#igned OOP pr*gra+, +*#t *r all *9 y*ur +eth*d# !ill 9*ll*! the +*del *9 +une( ) and c*++unicate *nly !ith the 3a#eEcla## inter9ace) Such a pr*gra+ i# e%tensi2le 3ecau#e y*u can add ne! 9uncti*nality 3y inheriting ne! data type# 9r*+ the c*++*n 3a#e cla##) The +eth*d# that +anipulate the 3a#eEcla## inter9ace !ill n*t need t* 3e changed at all t* acc*++*date the ne! cla##e#) C*n#ider !hat happen# i9 y*u take the in#tru+ent e;a+ple and add +*re +eth*d# in the 3a#e cla## and a nu+3er *9 ne! cla##e#) Here# the diagra+1

Cha"ter #* /ol4mor"hism

3('

Instru#ent void Pla512 'tring What12 void )d/ust12

Wind void Pla512 'tring What12 void )d/ust12

Percussion void Pla512 'tring What12 void )d/ust12

'tringed void Pla512 'tring What12 void )d/ust12

Woodwind void Pla512 'tring What12

3rass void Pla512 void )d/ust12

=ll the#e ne! cla##e# !*rk c*rrectly !ith the *ld, unchanged +une( ) +eth*d) Even i9 +une( ) i# in a #eparate 9ile and ne! +eth*d# are added t* the inter9ace *9 Bnstrument, +une( ) !*rk# c*rrectly !ith*ut rec*+pilati*n) Here i# the i+ple+entati*n *9 the a3*ve diagra+1 //:c0F:Gu#icT.c# // )n exten#i$ e progra!. c a## 5n#tru!ent ; pu$ ic *irtua *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&5n#tru!ent.- ay01&13 < pu$ ic *irtua #tring Vhat01 ; return &5n#tru!ent&3 <

31(

Thinking in C

www.ThinkingIn.!et

pu$ ic *irtua <

*oid )dDu#t01 ;<

c a## Vind : 5n#tru!ent ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Vind.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &Vind&3 < pu$ ic o*erride *oid )dDu#t01 ;< < c a## -ercu##ion : 5n#tru!ent ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&-ercu##ion.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &-ercu##ion&3 < pu$ ic o*erride *oid )dDu#t01 ;< < c a## Stringed : 5n#tru!ent ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&#tringed.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &#tringed&3 < pu$ ic o*erride *oid )dDu#t01 ;< < c a## Bra## : Vind ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Bra##.- ay01&13 < pu$ ic o*erride *oid )dDu#t01 ; Sy#te!.Con#o e.VriteLine0&Bra##.)dDu#t01&13 < < c a## Vood.ind : Vind ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Vood.ind.- ay01&13 <

Cha"ter #* /ol4mor"hism

311

pu$ ic o*erride #tring Vhat01 ; return &Vood.ind&3 < < pu$ ic c a## Gu#icT ; // :oe#n't care a$out type2 #o ne. type# // added to the #y#te! #ti .or% right: #tatic *oid 'une05n#tru!ent i1 ; // ... i.- ay013 < #tatic *oid 'une) 05n#tru!entJK e1 ; foreach05n#tru!ent i in e1 'une0i13 < pu$ ic #tatic *oid Gain01 ; 5n#tru!entJK orche#tra 9 ne. 5n#tru!entJPK3 int i 9 03 // Opca#ting during addition to the array: orche#traJiRRK 9 ne. Vind013 orche#traJiRRK 9 ne. -ercu##ion013 orche#traJiRRK 9 ne. Stringed013 orche#traJiRRK 9 ne. Bra##013 orche#traJiRRK 9 ne. Vood.ind013 'une) 0orche#tra13 < < ///:8 The ne! +eth*d# are =hat( ), !hich return# a #tring re9erence !ith a de#cripti*n *9 the cla##, and 'd)ust( ), !hich pr*vide# #*+e !ay t* ad4u#t each in#tru+ent) -n .ain( ), !hen y*u place #*+ething in#ide the Bnstrument array y*u aut*+atically upca#t t* Bnstrument) :*u can #ee that the +une( ) +eth*d i# 3li##9ully ign*rant *9 all the c*de change# that have happened ar*und it, and yet it !*rk# c*rrectly) Thi# i# e;actly !hat p*ly+*rphi#+ i# #upp*#ed t* pr*vide) :*ur c*de change# d*nt cau#e da+age t* part# *9 the pr*gra+ that #h*uld n*t 3e a99ected) Put an*ther !ay, p*ly+*rphi#+ i# *ne *9 the +*#t i+p*rtant techniDue# that all*! the pr*gra++er t* I#eparate the thing# that change 9r*+ the thing# that #tay the #a+e)J

31)

Thinking in C

www.ThinkingIn.!et

Overriding vs. overloading


Let# take a di99erent l**k at the 9ir#t e;a+ple in thi# chapter) -n the 9*ll*!ing pr*gra+, the inter9ace *9 the +eth*d !lay( ) i# changed in the pr*ce## *9 *verriding it, !hich +ean# that y*u havent o-erridden the +eth*d, 3ut in#tead o-erloaded it) The c*+piler all*!# y*u t* *verl*ad +eth*d# #* it give# n* c*+plaint) But the 3ehavi*r i# pr*3a3ly n*t !hat y*u !ant) Here# the e;a+ple1 //:c0F:Vind+rror.c# // )ccidenta y changing the interface. pu$ ic c a## Cote, ; pu$ ic con#t int G5::L+XC 9 02 CXSU)R- 9 "2 CXHL)' 9 23 < pu$ ic c a## 5n#tru!ent, ; pu$ ic *oid - ay0int Cote,1 ; Sy#te!.Con#o e.VriteLine0&5n#tru!ent,.- ay01&13 < < pu$ ic c a## Vind, : 5n#tru!ent, ; // OO-S! Change# the !ethod interface: pu$ ic *oid - ay0Cote, n1 ; Sy#te!.Con#o e.VriteLine0&Vind,.- ay0Cote, n1&13 < < pu$ ic c a## Vind+rror ; pu$ ic #tatic *oid 'une05n#tru!ent, i1 ; // ... i.- ay0Cote,.G5::L+XC13 < pu$ ic #tatic *oid Gain01 ; Vind, f ute 9 ne. Vind,013 'une0f ute13 // Cot the de#ired $eha*ior! < < ///:8

Cha"ter #* /ol4mor"hism

313

There# an*ther c*n9u#ing a#pect thr*!n in here) -n Bnstrument?, the !lay( ) +eth*d take# an int that ha# the identi9ier ,ote?) That i#, even th*ugh ,ote? i# a cla## na+e, it can al#* 3e u#ed a# an identi9ier !ith*ut c*+plaint) But in =ind?, !lay( ) take# a ,ote? re9erence that ha# an identi9ier n6 G=lth*ugh y*u c*uld even #ay !lay(,ote? ,ote?) !ith*ut an err*r)H Thu# it appear# that the pr*gra++er intended t* *verride !lay( ) 3ut +i#typed the +eth*d a 3it) The c*+piler, h*!ever, a##u+ed that an *verl*ad and n*t an *verride !a# intended) *te that i9 y*u 9*ll*! the #tandard C# na+ing c*nventi*n, the argu+ent identi9ier !*uld 3e note? Gl*!erca#e TnH, !hich !*uld di#tingui#h it 9r*+ the cla## na+e) -n +une, the Bnstrument? i i# #ent the !lay( ) +e##age, !ith *ne *9 ,ote?# +e+3er# G.B$$L&ACH a# an argu+ent) Since ,ote? c*ntain# int de9initi*n#, thi# +ean# that the int ver#i*n *9 the n*!E*verl*aded !lay( ) +eth*d i# called, and #ince that ha# not 3een *verridden the 3a#eE cla## ver#i*n i# u#ed) The *utput i#1 5n#tru!ent,.- ay01 Thi# certainly d*e#nt appear t* 3e a p*ly+*rphic +eth*d call) Once y*u under#tand !hat# happening, y*u can 9i; the pr*3le+ 9airly ea#ily, 3ut i+agine h*! di99icult it +ight 3e t* 9ind the 3ug i9 it# 3uried in a pr*gra+ *9 #igni9icant #i7e)

O$erator Overloading )+stract classes and #ethods


-n all the in#tru+ent e;a+ple#, the +eth*d# in the 3a#e cla## Bnstrument !ere al!ay# Idu++yJ +eth*d#) -9 the#e +eth*d# are ever called, y*uve d*ne #*+ething !r*ng) That# 3ecau#e the intent *9 Bnstrument i# t* create a common inter$ace 9*r all the cla##e# derived 9r*+ it)

314

Thinking in C

www.ThinkingIn.!et

The *nly rea#*n t* e#ta3li#h thi# c*++*n inter9ace i# #* it can 3e e;pre##ed di99erently 9*r each di99erent #u3type) -t e#ta3li#he# a 3a#ic 9*r+, #* y*u can #ay !hat# in c*++*n !ith all the derived cla##e#) =n*ther !ay *9 #aying thi# i# t* call Bnstrument an a2stract 2ase class G*r #i+ply an a2stract classH) :*u create an a3#tract cla## !hen y*u !ant t* +anipulate a #et *9 cla##e# thr*ugh thi# c*++*n inter9ace) =ll derivedE cla## +eth*d# that +atch the #ignature *9 the 3a#eEcla## declarati*n !ill 3e called u#ing the dyna+ic 3inding +echani#+) GH*!ever, a# #een in the la#t #ecti*n, i9 the +eth*d# na+e i# the #a+e a# the 3a#e cla## 3ut the argu+ent# are di99erent, y*uve g*t *verl*ading, !hich pr*3a3ly i#nt !hat y*u !ant)H -9 y*u have an a3#tract cla## like Bnstrument, *34ect# *9 that cla## al+*#t al!ay# have n* +eaning) That i#, Bnstrument i# +eant t* e;pre## *nly the inter9ace, and n*t a particular i+ple+entati*n, #* creating an Bnstrument *34ect +ake# n* #en#e, and y*ull pr*3a3ly !ant t* prevent the u#er 9r*+ d*ing it) Thi# can 3e acc*+pli#hed 3y +aking all the +eth*d# in Bnstrument print err*r +e##age#, 3ut that delay# the in9*r+ati*n until runEti+e and reDuire# relia3le e;hau#tive te#ting *n the u#er# part) -t# al!ay# 3etter t* catch pr*3le+# at c*+pileEti+e) C# pr*vide# a +echani#+ 9*r d*ing thi# called the a2stract method/) Thi# i# a +eth*d that i# inc*+pleteQ it ha# *nly a declarati*n and n* +eth*d 3*dy) Here i# the #ynta; 9*r an a3#tract +eth*d declarati*n1 a$#tract *oid H013 = cla## c*ntaining a3#tract +eth*d# i# called an a2stract class) -9 a cla## c*ntain# *ne *r +*re a3#tract +eth*d#, the cla## +u#t 3e Duali9ied a# abstract) GOther!i#e, the c*+piler give# y*u an err*r +e##age)H There# n* need t* Duali9y abstract +eth*d# a# virtual, a# they are al!ay# re#*lved !ith late 3inding) -9 an a3#tract cla## i# inc*+plete, !hat i# the c*+piler #upp*#ed t* d* !hen #*+e*ne trie# t* in#tantiate an *34ect *9 that cla##F -t cann*t #a9ely create an *34ect *9 an a3#tract cla##, #* y*u get an err*r +e##age 9r*+ the c*+piler) Thi# !ay the c*+piler en#ure# the purity *9 the a3#tract cla##, and y*u d*nt need t* !*rry a3*ut +i#u#ing it)
/ 5*r C@@ pr*gra++er#, thi# i# the anal*gue *9 C@@# "ure -irtual $unction)

Cha"ter #* /ol4mor"hism

315

-9 y*u inherit 9r*+ an a3#tract cla## and y*u !ant t* +ake *34ect# *9 the ne! type, y*u +u#t pr*vide +eth*d de9initi*n# 9*r all the a3#tract +eth*d# in the 3a#e cla##) -9 y*u d*nt Gand y*u +ay ch**#e n*t t*H, then the derived cla## i# al#* a3#tract and the c*+piler !ill 9*rce y*u t* Duali9y that cla## !ith the abstract key!*rd) -t# p*##i3le t* create a cla## a# abstract !ith*ut including any abstract +eth*d#) Thi# i# u#e9ul !hen y*uve g*t a cla## in !hich it d*e#nt +ake #en#e t* have any abstract +eth*d#, and yet y*u !ant t* prevent any in#tance# *9 that cla##) The Bnstrument cla## can ea#ily 3e turned int* an abstract cla##) Only #*+e *9 the +eth*d# !ill 3e abstract, #ince +aking a cla## a3#tract d*e#nt 9*rce y*u t* +ake all the +eth*d# abstract) Here# !hat it l**k# like1

316

Thinking in C

www.ThinkingIn.!et

a+stract Instru#ent a+stract void Pla512L 'tring What12 M ?N ... N? O a+stract void )d/ust12L

Wind void Pla512 'tring What12 void )d/ust12

Percussion void Pla512 'tring What12 void )d/ust12

'tringed void Pla512 'tring What12 void )d/ust12

Woodwind void Pla512 'tring What12

3rass void Pla512 void )d/ust12

Here# the *rche#tra e;a+ple +*di9ied t* u#e abstract cla##e# and +eth*d#1 //:c0F:Gu#icE.c# // )n exten#i$ e progra!. a$#tract c a## 5n#tru!ent ; pu$ ic a$#tract *oid - ay013 pu$ ic *irtua #tring Vhat01 ; return &5n#tru!ent&3 < pu$ ic a$#tract *oid )dDu#t013

Cha"ter #* /ol4mor"hism

31#

< c a## Vind : 5n#tru!ent ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Vind.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &Vind&3 < pu$ ic o*erride *oid )dDu#t01 ;< < c a## -ercu##ion : 5n#tru!ent ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&-ercu##ion.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &-ercu##ion&3 < pu$ ic o*erride *oid )dDu#t01 ;< < c a## Stringed : 5n#tru!ent ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&#tringed.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &#tringed&3 < pu$ ic o*erride *oid )dDu#t01 ;< < c a## Bra## : Vind ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Bra##.- ay01&13 < pu$ ic o*erride *oid )dDu#t01 ; Sy#te!.Con#o e.VriteLine0&Bra##.)dDu#t01&13 <

31&

Thinking in C

www.ThinkingIn.!et

< c a## Vood.ind : Vind ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Vood.ind.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &Vood.ind&3 < < pu$ ic c a## Gu#icT ; // :oe#n't care a$out type2 #o ne. type# // added to the #y#te! #ti .or% right: #tatic *oid 'une05n#tru!ent i1 ; // ... i.- ay013 < #tatic *oid 'une) 05n#tru!entJK e1 ; foreach05n#tru!ent i in e1 'une0i13 < pu$ ic #tatic *oid Gain01 ; 5n#tru!entJK orche#tra 9 ne. 5n#tru!entJPK3 int i 9 03 // Opca#ting during addition to the array: orche#traJiRRK 9 ne. Vind013 orche#traJiRRK 9 ne. -ercu##ion013 orche#traJiRRK 9 ne. Stringed013 orche#traJiRRK 9 ne. Bra##013 orche#traJiRRK 9 ne. Vood.ind013 'une) 0orche#tra13 < < ///:8 :*u can #ee that there# really n* change e;cept in the 3a#e cla##)

Cha"ter #* /ol4mor"hism

31'

-t# help9ul t* create abstract cla##e# and +eth*d# 3ecau#e they +ake the a3#tractne## *9 a cla## e;plicit, and tell 3*th the u#er and the c*+piler h*! it !a# intended t* 3e u#ed)

Constructors and $ol5#or$his#


=# u#ual, c*n#truct*r# are di99erent 9r*+ *ther kind# *9 +eth*d#) Thi# i# al#* true !hen p*ly+*rphi#+ i# inv*lved) Even th*ugh c*n#truct*r# are n*t p*ly+*rphic Galth*ugh y*u can have a kind *9 Ivirtual c*n#truct*r,J a# y*u !ill #ee in Chapter #virtual c*n#truct*r#H, it# i+p*rtant t* under#tand the !ay c*n#truct*r# !*rk in c*+ple; hierarchie# and !ith p*ly+*rphi#+) Thi# under#tanding !ill help y*u av*id unplea#ant entangle+ent#)

Order o0 constructor calls


The *rder *9 c*n#truct*r call# !a# 3rie9ly di#cu##ed in Chapter #initiali7ati*n#, 3ut that !a# 3e9*re p*ly+*rphi#+ !a# intr*duced) = c*n#truct*r 9*r the 3a#e cla## i# al!ay# called in the c*n#truct*r 9*r a derived cla##, chaining up the inheritance hierarchy #* that a c*n#truct*r 9*r every 3a#e cla## i# called) Thi# +ake# #en#e 3ecau#e the c*n#truct*r ha# a #pecial 4*31 t* #ee that the *34ect i# 3uilt pr*perly) = derived cla## ha# acce## t* it# *!n +e+3er# *nly, and n*t t* private +e+3er# *9 the 3a#e cla##) Only the 3a#eEcla## c*n#truct*r ha# the pr*per kn*!ledge and acce## t* initiali7e it# *!n ele+ent#) There9*re, it# e##ential that all c*n#truct*r# get called, *ther!i#e the entire *34ect !*uldnt 3e c*n#i#tently c*n#tructed) That# !hy the c*+piler en9*rce# a c*n#truct*r call 9*r every p*rti*n *9 a derived cla##) -t !ill #ilently call the de9ault c*n#truct*r i9 y*u d*nt e;plicitly call a 3a#eEcla## c*n#truct*r in the derivedEcla## c*n#truct*r 3*dy) -9 there i# n* de9ault c*n#truct*r, the c*+piler !ill c*+plain) G-n the ca#e !here a cla## ha# n* c*n#truct*r#, the c*+piler !ill aut*+atically #ynthe#i7e a de9ault c*n#truct*r)H Let# take a l**k at an e;a+ple that #h*!# the e99ect# *9 c*+p*#iti*n, inheritance, and p*ly+*rphi#+ *n the *rder *9 c*n#tructi*n1

3)(

Thinking in C

www.ThinkingIn.!et

//:c0F:Sand.ich.c# // Order of con#tructor ca

#.

pu$ ic c a## Gea ; interna Gea 01 ; Sy#te!.Con#o e.VriteLine0&Gea 01&13 < < pu$ ic c a## Bread ; interna Bread01 ; Sy#te!.Con#o e.VriteLine0&Bread01&13 < < pu$ ic c a## Chee#e ; interna Chee#e01 ; Sy#te!.Con#o e.VriteLine0&Chee#e01&13 < < pu$ ic c a## Lettuce ; interna Lettuce01 ; Sy#te!.Con#o e.VriteLine0&Lettuce01&13 < < pu$ ic c a## Lunch : Gea ; interna Lunch01 ; Sy#te!.Con#o e.VriteLine0&Lunch01&13< < pu$ ic c a## -orta$ eLunch : Lunch ; interna -orta$ eLunch01 ; Sy#te!.Con#o e.VriteLine0&-orta$ eLunch01&13 < < pu$ ic c a## Sand.ich : -orta$ eLunch ; Bread $ 9 ne. Bread013 Chee#e c 9 ne. Chee#e013 Lettuce 9 ne. Lettuce013 interna Sand.ich01 ; Sy#te!.Con#o e.VriteLine0&Sand.ich01&13 <

Cha"ter #* /ol4mor"hism

3)1

pu$ ic #tatic *oid Gain01 ; ne. Sand.ich013 < < ///:8 Thi# e;a+ple create# a c*+ple; cla## *ut *9 *ther cla##e#, and each cla## ha# a c*n#truct*r that ann*unce# it#el9) The i+p*rtant cla## i# #andwich, !hich re9lect# three level# *9 inheritance G9*ur, i9 y*u c*unt the i+plicit inheritance 9r*+ ob)ectH and three +e+3er *34ect#) ,hen a #andwich *34ect i# created in .ain( ), the *utput i#1 Bread01 Chee#e01 Lettuce01 Gea 01 Lunch01 -orta$ eLunch01 Sand.ich01 Thi# +ean# that the *rder *9 c*n#truct*r call# 9*r a c*+ple; *34ect i# a# 9*ll*!#1 &) Ae+3er initiali7er# are called in the *rder *9 declarati*n ') The 3a#eEcla## c*n#truct*r i# called) Thi# #tep i# repeated recur#ively #uch that the r**t *9 the hierarchy i# c*n#tructed 9ir#t, 9*ll*!ed 3y the ne;tEderived cla##, etc), until the +*#tEderived cla## i# reached) .) The 3*dy *9 the derivedEcla## c*n#truct*r i# called) The *rder *9 the c*n#truct*r call# i# i+p*rtant) ,hen y*u inherit, y*u kn*! all a3*ut the 3a#e cla## and can acce## any public, protected, *r internal +e+3er# *9 the 3a#e cla##) Thi# +ean# that y*u +u#t 3e a3le t* a##u+e that all the +e+3er# *9 the 3a#e cla## are valid !hen y*ure in the derived cla##) -n a n*r+al +eth*d, c*n#tructi*n ha# already taken place, #* all the +e+3er# *9 all part# *9 the *34ect have 3een 3uilt) -n#ide the c*n#truct*r, h*!ever, y*u +u#t 3e a3le t* a##u+e that all +e+3er# that y*u u#e have 3een 3uilt) The *nly !ay t* guarantee thi# i# 9*r the 3a#eE cla## c*n#truct*r t* 3e called 9ir#t) Then !hen y*ure in the derivedEcla## c*n#truct*r, all the +e+3er# y*u can acce## in the 3a#e cla## have 3een initiali7ed) INn*!ing that all +e+3er# are validJ in#ide the c*n#truct*r i# al#* the rea#*n that, !henever p*##i3le, y*u #h*uld initiali7e all +e+3er *34ect# Gthat i#, *34ect# placed in the cla## u#ing c*+p*#iti*nH at their

3))

Thinking in C

www.ThinkingIn.!et

p*int *9 de9initi*n in the cla## Ge)g), b, c, and l in the e;a+ple a3*veH) -9 y*u 9*ll*! thi# practice, y*u !ill help en#ure that all 3a#e cla## +e+3er# and +e+3er *34ect# *9 the current *34ect have 3een initiali7ed) Un9*rtunately, thi# d*e#nt handle every ca#e, a# y*u !ill #ee in the ne;t #ecti*n)

3ehavior o0 $ol5#or$hic #ethods inside constructors


The hierarchy *9 c*n#truct*r call# 3ring# up an intere#ting dile++a) ,hat happen# i9 y*ure in#ide a c*n#truct*r and y*u call a dyna+ically 3*und +eth*d *9 the *34ect 3eing c*n#tructedF -n#ide an *rdinary +eth*d y*u can i+agine !hat !ill happenRthe dyna+ically 3*und call i# re#*lved at runEti+e 3ecau#e the *34ect cann*t kn*! !hether it 3el*ng# t* the cla## that the +eth*d i# in *r #*+e cla## derived 9r*+ it) 5*r c*n#i#tency, y*u +ight think thi# i# !hat #h*uld happen in#ide c*n#truct*r#) Thi# i# n*t e;actly the ca#e) -9 y*u call a dyna+ically 3*und +eth*d in#ide a c*n#truct*r, the *verridden de9initi*n 9*r that +eth*d i# u#ed) H*!ever, the e$$ect can 3e rather une;pected, and can c*nceal #*+e di99icultEt*E9ind 3ug#) C*nceptually, the c*n#truct*r# 4*3 i# t* 3ring the *34ect int* e;i#tence G!hich i# hardly an *rdinary 9eatH) -n#ide any c*n#truct*r, the entire *34ect +ight 3e *nly partially 9*r+edRy*u can kn*! *nly that the 3a#eE cla## *34ect# have 3een initiali7ed, 3ut y*u cann*t kn*! !hich cla##e# are inherited 9r*+ y*u) = dyna+ically 3*und +eth*d call, h*!ever, reache# I*ut!ardJ int* the inheritance hierarchy) -t call# a +eth*d in a derived cla##) -9 y*u d* thi# in#ide a c*n#truct*r, y*u call a +eth*d that +ight +anipulate +e+3er# that havent 3een initiali7ed yetRa #ure recipe 9*r di#a#ter) :*u can #ee the pr*3le+ in the 9*ll*!ing e;a+ple1 //:c0F:-o yCon#tructor#.c# // Con#tructor# and po y!orphi#! // don't produce .hat you !ight expect. a$#tract c a## _ yph ;

Cha"ter #* /ol4mor"hism

3)3

protected a$#tract *oid :ra.013 interna _ yph01 ; Sy#te!.Con#o e.VriteLine0&_ yph01 $efore dra.01&13 :ra.013 Sy#te!.Con#o e.VriteLine0&_ yph01 after dra.01&13 < < c a## Round_ yph : _ yph ; int radiu# 9 "3 int thic%ne##3 interna Round_ yph0int r1 ; radiu# 9 r3 thic%ne## 9 23 Sy#te!.Con#o e.VriteLine0 &Round_ yph.Round_ yph012 radiu# 9 ;0< thic%ne## 9 ;"<&2 radiu#2 thic%ne##13 < protected o*erride *oid :ra.01 ; Sy#te!.Con#o e.VriteLine0 &Round_ yph.:ra.012 radiu# 9 ;0< thic%ne## 9 ;"<&2 radiu#2 thic%ne##13 < < pu$ ic c a## -o yCon#tructor# ; pu$ ic #tatic *oid Gain01 ; ne. Round_ yph0P13 < < ///:8 -n lyph, the $raw( ) +eth*d i# abstract, #* it i# de#igned t* 3e *verridden) -ndeed, y*u are 9*rced t* *verride it in *ound lyph) But

3)4

Thinking in C

www.ThinkingIn.!et

the lyph c*n#truct*r call# thi# +eth*d, and the call end# up in *ound lyph6$raw( ), !hich !*uld #ee+ t* 3e the intent) But l**k at the *utput1 _ yph01 $efore dra.01 Round_ yph.:ra.012 radiu# 9 " thic%ne## 9 0 _ yph01 after dra.01 Round_ yph.Round_ yph012 radiu# 9 P thic%ne## 9 2 ,hen lyph# c*n#truct*r call# $raw( ), the value *9 radius are #et t* their de9ault value#, n*t their p*#tEc*n#tructi*n intended value#) = g**d guideline 9*r c*n#truct*r# i#, I-9 p*##i3le, initiali7e +e+3er varia3le# directly) ?* a# little a# p*##i3le in a c*n#truct*r t* #et the *34ect int* a g**d #tate, and i9 y*u can p*##i3ly av*id it, d*nt call any +eth*d#)J The *nly #a9e +eth*d# t* call in#ide a c*n#truct*r are n*nEvirtual)

4esigning with inheritance


Once y*u learn a3*ut p*ly+*rphi#+, it can #ee+ that everything *ught t* 3e inherited 3ecau#e p*ly+*rphi#+ i# #uch a clever t**l) Thi# can 3urden y*ur de#ign#Q in 9act i9 y*u ch**#e inheritance 9ir#t !hen y*ure u#ing an e;i#ting cla## t* +ake a ne! cla##, thing# can 3ec*+e needle##ly c*+plicated) = 3etter appr*ach i# t* ch**#e c*+p*#iti*n 9ir#t, !hen it# n*t *3vi*u# !hich *ne y*u #h*uld u#e) C*+p*#iti*n d*e# n*t 9*rce a de#ign int* an inheritance hierarchy) But c*+p*#iti*n i# al#* +*re 9le;i3le #ince it# p*##i3le t* dyna+ically ch**#e a type Gand thu# 3ehavi*rH !hen u#ing c*+p*#iti*n, !herea# inheritance reDuire# an e;act type t* 3e kn*!n at c*+pileEti+e) The 9*ll*!ing e;a+ple illu#trate# thi#1 //:c0F:'ran#!ogrify.c# // :yna!ica y changing the $eha*ior of // an o$Dect *ia co!po#ition. a$#tract c a## )ctor ; pu$ ic a$#tract *oid )ct013 <

Cha"ter #* /ol4mor"hism

3)5

c a## Uappy)ctor : )ctor ; pu$ ic o*erride *oid )ct01 ; Sy#te!.Con#o e.VriteLine0&Uappy)ctor&13 < < c a## Sad)ctor : )ctor ; pu$ ic o*erride *oid )ct01 ; Sy#te!.Con#o e.VriteLine0&Sad)ctor&13 < < c a## Stage ; )ctor a 9 ne. Uappy)ctor013 interna *oid Change01 ; a 9 ne. Sad)ctor013 < interna *oid _o01 ; a.)ct013 < < pu$ ic c a## 'ran#!ogrify ; pu$ ic #tatic *oid Gain01 ; Stage # 9 ne. Stage013 #._o013 // -rint# &Uappy)ctor& #.Change013 #._o013 // -rint# &Sad)ctor& < < ///:8 = #tage *34ect c*ntain# a re9erence t* an 'ctor, !hich i# initiali7ed t* a "appy'ctor *34ect) Thi# +ean# o( ) pr*duce# a particular 3ehavi*r) But #ince a re9erence can 3e re3*und t* a di99erent *34ect at runEti+e, a re9erence 9*r a #ad'ctor *34ect can 3e #u3#tituted in a and then the 3ehavi*r pr*duced 3y o( ) change#) Thu# y*u gain dyna+ic 9le;i3ility at runEti+e) GThi# i# al#* called the @tate /attern. See Thinking in /atterns, d*!nl*ada3le at www.BruceEckel.com.H -n c*ntra#t, y*u cant decide t* inherit di99erently at runEti+eQ that +u#t 3e c*+pletely deter+ined at c*+pileEti+e) = general guideline i# IU#e inheritance t* e;pre## di99erence# in 3ehavi*r, and 9ield# t* e;pre## variati*n# in #tate)J -n the a3*ve e;a+ple, 3*th are u#ed1 t!* di99erent cla##e# are inherited t* e;pre## the di99erence in the

3)6

Thinking in C

www.ThinkingIn.!et

'ct( ) +eth*d, and #tage u#e# c*+p*#iti*n t* all*! it# #tate t* 3e changed) -n thi# ca#e, that change in #tate happen# t* pr*duce a change in 3ehavi*r)

Pure inheritance vs. e&tension


,hen #tudying inheritance, it !*uld #ee+ that the cleane#t !ay t* create an inheritance hierarchy i# t* take the IpureJ appr*ach) That i#, *nly +eth*d# that have 3een e#ta3li#hed in the 3a#e cla## *r interface are t* 3e *verridden in the derived cla##, a# #een in thi# diagra+1
Shape d ra w 12 e ra se 12

C ir c le d ra w 12 e ra se 12

S q u a re d ra w 12 e ra se 12

T r ia n g le d ra w 12 e ra se 12

Thi# can 3e ter+ed a pure Ii#EaJ relati*n#hip 3ecau#e the inter9ace *9 a cla## e#ta3li#he# !hat it i#) -nheritance guarantee# that any derived cla## !ill have the inter9ace *9 the 3a#e cla## and n*thing le##) -9 y*u 9*ll*! the a3*ve diagra+, derived cla##e# !ill al#* have no more than the 3a#e cla## inter9ace) Thi# can 3e th*ught *9 a# "ure su2stitution, 3ecau#e derived cla## *34ect# can 3e per9ectly #u3#tituted 9*r the 3a#e cla##, and y*u never need t* kn*! any e;tra in9*r+ati*n a3*ut the #u3cla##e# !hen y*ure u#ing the+1

- a l* s t o ' h a $ e =Is;a = r e la t io n s h i$

@ essage

C ir c le . ' q u a r e . L in e . o r n e w t 5 $ e o0 'ha$e

Cha"ter #* /ol4mor"hism

3)#

That i#, the 3a#e cla## can receive any +e##age y*u can #end t* the derived cla## 3ecau#e the t!* have e;actly the #a+e inter9ace) =ll y*u need t* d* i# upca#t 9r*+ the derived cla## and never l**k 3ack t* #ee !hat e;act type *9 *34ect y*ure dealing !ith) Everything i# handled thr*ugh p*ly+*rphi#+) ,hen y*u #ee it thi# !ay, it #ee+# like a pure Ii#EaJ relati*n#hip i# the *nly #en#i3le !ay t* d* thing#, and any *ther de#ign indicate# +uddled thinking and i# 3y de9initi*n 3r*ken) Thi# t** i# a trap) =# #**n a# y*u #tart thinking thi# !ay, y*ull turn ar*und and di#c*ver that e;tending the inter9ace i# the per9ect #*luti*n t* a particular pr*3le+) Thi# c*uld 3e ter+ed an Ii#ElikeEaJ relati*n#hip 3ecau#e the derived cla## i# like the 3a#e cla##Rit ha# the #a+e 9unda+ental inter9aceR3ut it ha# *ther 9eature# that reDuire additi*nal +eth*d# t* i+ple+ent1
> s e 0u l v o id 0 1 2 v o id g 1 2

) s s u # e t h is r e $ r e s e n t s a + ig in t e r 0 a c e

@ o re > s e 0u l vo vo vo vo vo id id id id id 01 2 g 12 u 12 v12 w 12

= I s ; li* e ; a =

% & t e n d in g t h e in t e r 0 a c e

,hile thi# i# al#* a u#e9ul and #en#i3le appr*ach Gdepending *n the #ituati*nH it ha# a dra!3ack) The e;tended part *9 the inter9ace in the derived cla## i# n*t availa3le 9r*+ the 3a#e cla##, #* *nce y*u upca#t y*u cant call the ne! +eth*d#1

3)&

Thinking in C

www.ThinkingIn.!et

- a l* s t o > s e 0u l o + /e c t

@ essage

> s e 0u l $ a rt @ o re > s e 0u l $ a rt

-9 y*ure n*t upca#ting in thi# ca#e, it !*nt 3*ther y*u, 3ut *9ten y*ull get int* a #ituati*n in !hich y*u need t* redi#c*ver the e;act type *9 the *34ect #* y*u can acce## the e;tended +eth*d# *9 that type) The 9*ll*!ing #ecti*n #h*!# h*! thi# i# d*ne)

4owncasting and run;ti#e t5$e identi0ication


Since y*u l*#e the #peci9ic type in9*r+ati*n via an u"cast G+*ving up the inheritance hierarchyH, it +ake# #en#e that t* retrieve the type in9*r+ati*nRthat i#, t* +*ve 3ack d*!n the inheritance hierarchyRy*u u#e a downcast) H*!ever, y*u kn*! an upca#t i# al!ay# #a9eQ the 3a#e cla## cann*t have a 3igger inter9ace than the derived cla##, there9*re every +e##age y*u #end thr*ugh the 3a#e cla## inter9ace i# guaranteed t* 3e accepted) But !ith a d*!nca#t, y*u d*nt really kn*! that a #hape G9*r e;a+pleH i# actually a circle) -t c*uld in#tead 3e a triangle *r #Duare *r #*+e *ther type)
> s e 0u l v o id 0 1 2 v o id g 1 2

) s s u # e t h is r e $ r e s e n t s a + ig in t e r 0a c e

@ o re > s e 0u l vo vo vo vo vo id id id id id 01 2 g 12 u 12 v12 w 12

= I s ; li* e ; a =

% & t e n d in g t h e in t e r 0 a c e

Cha"ter #* /ol4mor"hism

3)'

T* #*lve thi# pr*3le+ there +u#t 3e #*+e !ay t* guarantee that a d*!nca#t i# c*rrect, #* y*u !*nt accidentally ca#t t* the !r*ng type and then #end a +e##age that the *34ect cant accept) Thi# !*uld 3e Duite un#a9e) -n #*+e language# Glike C@@H y*u +u#t per9*r+ a #pecial *perati*n in *rder t* get a typeE#a9e d*!nca#t, 3ut in C# e-er4 cast i# checkedK C# #upp*rt# t!* type# *9 d*!nca#t1 a parenthe#i7ed ca#t that l**k# #i+ilar t* the ca#t# in *ther CEderived language#1 GoreO#efu do.nCa#tO$Dect 9 0GoreO#efu 1 !yO#efu Uand e3 and the as key!*rd1 GoreO#efu do.nCa#tO$Dect 9 !yO#efu Uand e a# GoreO#efu 3 =t runEti+e, 3*th the#e ca#t# are checked t* en#ure that the myVseful"andle d*e# in 9act re9er t* an in#tance *9 type .oreVseful6 -9 thi# a 3ad a##u+pti*n, the parenthe#i7e ca#t !ill thr*! an BnvalidCast&xception and the as ca#t !ill a##ign downCast1b)ect the value *9 null) Thi# act *9 checking type# at runEti+e i# called run9time t4"e identi$ication GRTT-H) The 9*ll*!ing e;a+ple de+*n#trate# the 3ehavi*r *9 RTT-1 //:c0F:R''5.CS // :o.nca#ting @ Run6ti!e 'ype // 5dentification 0R''51. c a## O#efu ; pu$ ic *irtua pu$ ic *irtua <

*oid H01 ;< *oid _01 ;<

c a## GoreO#efu : O#efu ; pu$ ic o*erride *oid H01 ;< pu$ ic o*erride *oid _01 ;<

33(

Thinking in C

www.ThinkingIn.!et

pu$ ic *oid O01 ;< pu$ ic *oid N01 ;< pu$ ic *oid V01 ;< < pu$ ic c a## R''5 ; pu$ ic #tatic *oid Gain01 ; O#efu JK x 9 ; ne. O#efu 012 ne. GoreO#efu 01 <3 xJ0K.H013 xJ"K._013 // Co!pi e6ti!e: !ethod not found in O#efu : //! xJ"K.O013 00GoreO#efu 1xJ"K1.O013 // -arenthe#iMed do.nca#t 0xJ"K a# GoreO#efu 1.O013 //a# %ey.ord 00GoreO#efu 1xJ0K1.O013 // +xception thro.n < < ///:8 ,hen y*u run thi# pr*gra+, y*u !ill #ee #*+ething !eve n*t yet di#cu##ed, Ci#ual Studi*# "u#tE-nETi+e ?e3ugging dial*gue1

Cha"ter #* /ol4mor"hism

331

Thi# i# certainly +*re !elc*+e than a ?r) ,at#*n du+p *r a Blue Screen *9 ?eath, 3ut !e kn*! the cau#e P !ere trying t* treat x<4> a# a .oreVseful !hen it# *nly a Vseful) Select I *J and the pr*gra+ !ill end !ith a c*+plaint a3*ut an unhandled BnvalidCast&xception) =# in the diagra+, .oreVseful e;tend# the inter9ace *9 Vseful) But #ince it# inherited, it can al#* 3e upca#t t* a Vseful) :*u can #ee thi# happening in the initiali7ati*n *9 the array x in .ain( )) Since 3*th *34ect# in the array are *9 cla## Vseful, y*u can #end the :( ) and ( ) +eth*d# t* 3*th, and i9 y*u try t* call V( ) G!hich e;i#t# *nly in .oreVsefulH y*ull get a c*+pileEti+e err*r +e##age) -9 y*u !ant t* acce## the e;tended inter9ace *9 a .oreVseful *34ect, y*u can try t* d*!nca#t) -9 it# the c*rrect type, it !ill 3e #ucce##9ul) Other!i#e, y*ull get an BnvalidCast&xception)

33)

Thinking in C

www.ThinkingIn.!et

There# +*re t* RTT- than a #i+ple ca#t) The is key!*rd all*!# y*u check the type *9 an *34ect 3e9*re atte+pting a d*!nca#t) //:c0F:R''52.c# // :o.nca#ting @ Run6ti!e 'ype // 5dentification 0R''51. c a## O#efu ; pu$ ic *irtua pu$ ic *irtua < c a## pu$ pu$ pu$ pu$ pu$ < *oid H01 ;< *oid _01 ;<

GoreO#efu : O#efu ; ic o*erride *oid H01 ;< ic o*erride *oid _01 ;< ic *oid O01 ;< ic *oid N01 ;< ic *oid V01 ;<

pu$ ic c a## R''52 ; pu$ ic #tatic *oid Gain01 ; O#efu JK x 9 ; ne. O#efu 012 ne. GoreO#efu 01 <3 xJ0K.H013 xJ"K._013 foreach0O#efu u in x1; if0u i# GoreO#efu 1; 00GoreO#efu 1 u1.O013 < < < < ///:8 Thi# pr*gra+ run# t* c*+pleti*n !ith*ut any e;cepti*n# 3eing thr*!n) Everything #tay# the #a+e e;cept the 9inal iterati*n *ver the x array) The foreach l**p iterate# *ver the array Gall t!* ele+ent# *9 itKH, 3ut !e guard the d*!nca#t !ith a B**lean te#t t* en#ure that !e *nly atte+pt the d*!nca#t *n *34ect# *9 type .oreVseful)

Cha"ter #* /ol4mor"hism

333

'u##ar5
P*ly+*rphi#+ +ean# Idi99erent 9*r+#)J -n *34ectE*riented pr*gra++ing, y*u have the #a+e 9ace Gthe c*++*n inter9ace in the 3a#e cla##H and di99erent 9*r+# u#ing that 9ace1 the di99erent ver#i*n# *9 the dyna+ically 3*und +eth*d#) :*uve #een in thi# chapter that it# i+p*##i3le t* under#tand, *r even create, an e;a+ple *9 p*ly+*rphi#+ !ith*ut u#ing data a3#tracti*n and inheritance) P*ly+*rphi#+ i# a 9eature that cann*t 3e vie!ed in i#*lati*n Glike a switch #tate+ent can, 9*r e;a+pleH, 3ut in#tead !*rk# *nly in c*ncert, a# part *9 a I3ig pictureJ *9 cla## relati*n#hip#) Pe*ple are *9ten c*n9u#ed 3y *ther, n*nE*34ectE*riented 9eature# *9 C#, like +eth*d *verl*ading, !hich are #*+eti+e# pre#ented a# *34ectE*riented) ?*nt 3e 9**led1 -9 it i#nt late 3inding, it i#nt p*ly+*rphi#+) T* u#e p*ly+*rphi#+Rand thu# *34ectE*riented techniDue#Re99ectively in y*ur pr*gra+# y*u +u#t e;pand y*ur vie! *9 pr*gra++ing t* include n*t 4u#t +e+3er# and +e##age# *9 an individual cla##, 3ut al#* the c*++*nality a+*ng cla##e# and their relati*n#hip# !ith each *ther) =lth*ugh thi# reDuire# #igni9icant e99*rt, it# a !*rthy #truggle, 3ecau#e the re#ult# are 9a#ter pr*gra+ devel*p+ent, 3etter c*de *rgani7ati*n, e;ten#i3le pr*gra+#, and ea#ier c*de +aintenance)

%&ercises

334

Thinking in C

www.ThinkingIn.!et

Da, Inter0aces
-nter9ace# pr*vide +*re #*phi#ticated !ay# t* *rgani7e and c*ntr*l the *34ect# in y*ur #y#te+)
C@@, 9*r e;a+ple, d*e# n*t c*ntain #uch +echani#+#, alth*ugh the clever pr*gra++er +ay #i+ulate the+) The 9act that they e;i#t in "ava indicate# that they !ere c*n#idered i+p*rtant en*ugh t* pr*vide direct #upp*rt thr*ugh language key!*rd#) -n Chapter %, y*u learned a3*ut the abstract key!*rd, !hich all*!# y*u t* create *ne *r +*re +eth*d# in a cla## that have n* de9initi*n#Ry*u pr*vide part *9 the inter9ace !ith*ut pr*viding a c*rre#p*nding i+ple+entati*n, !hich i# created 3y inherit*r#) The interface key!*rd pr*duce# a c*+pletely a3#tract cla##, *ne that pr*vide# n* i+ple+entati*n at all) :*ull learn that the interface i# +*re than 4u#t an a3#tract cla## taken t* the e;tre+e, #ince it all*!# y*u t* per9*r+ a variati*n *n C@@# I+ultiple inheritance,J 3y creating a cla## that can 3e upca#t t* +*re than *ne 3a#e type) =t 9ir#t, inner cla##e# l**k like a #i+ple c*deEhiding +echani#+1 y*u place cla##e# in#ide *ther cla##e#) :*ull learn, h*!ever, that the inner cla##

335

d*e# +*re than thatRit kn*!# a3*ut and can c*++unicate !ith the #urr*unding cla##Rand that the kind *9 c*de y*u can !rite !ith inner cla##e# i# +*re elegant and clear, alth*ugh it i# a ne! c*ncept t* +*#t) -t take# #*+e ti+e t* 3ec*+e c*+9*rta3le !ith de#ign u#ing inner cla##e#)

Inter0aces
The interface key!*rd take# the abstract c*ncept *ne #tep 9urther) :*u c*uld think *9 it a# a IpureJ abstract cla##) -t all*!# the creat*r t* e#ta3li#h the 9*r+ 9*r a cla##1 +eth*d na+e#, argu+ent li#t#, and return type#, 3ut n* +eth*d 3*die#) =n interface can al#* c*ntain 9ield#, 3ut the#e are i+plicitly static and final) =n interface pr*vide# *nly a 9*r+, 3ut n* i+ple+entati*n) =n interface #ay#1 IThi# i# !hat all cla##e# that im"lement thi# particular inter9ace !ill l**k like)J Thu#, any c*de that u#e# a particular interface kn*!# !hat +eth*d# +ight 3e called 9*r that interface, and that# all) S* the interface i# u#ed t* e#ta3li#h a Ipr*t*c*lJ 3et!een cla##e#) GS*+e *34ectE*riented pr*gra++ing language# have a key!*rd called "rotocol t* d* the #a+e thing)H T* create an interface, u#e the interface key!*rd in#tead *9 the class key!*rd) Like a cla##, y*u can add the public key!*rd 3e9*re the interface key!*rd G3ut *nly i9 that interface i# de9ined in a 9ile *9 the

336

#a+e na+eH *r leave it *99 t* give I9riendlyJ #tatu# #* that it i# *nly u#a3le !ithin the #a+e package) T* +ake a cla## that c*n9*r+# t* a particular interface G*r gr*up *9 interface#H u#e the implements key!*rd) :*ure #aying IThe interface i# !hat it l**k# like 3ut n*! -+ g*ing t* #ay h*! it works)J Other than that, it l**k# like inheritance) The diagra+ 9*r the in#tru+ent e;a+ple #h*!# thi#1
in t e r 0a c e I n s t r u # e n t v o id $ la 5 1 2 L ' t r in g w h a t 1 2 L v o id a d /u s t 1 2 L

i# $ le # e n t s W in d v o id $ la 5 1 2 ' t r in g w h a t 1 2 v o id a d /u s t 1 2

i# $ le # e n t s P e r c u s s io n v o id $ la 5 1 2 ' t r in g w h a t 1 2 v o id a d /u s t 1 2

i# $ le # e n t s ' t r in g e d v o id $ la 5 1 2 ' t r in g w h a t 1 2 v o id a d / u s t 1 2

e & te n d s W o o d w in d v o id $ la 5 1 2 ' t r in g w h a t 1 2

e & te n d s 3 ra ss v o id $ la 5 1 2 v o id a d / u s t 1 2

Once y*uve i+ple+ented an interface, that i+ple+entati*n 3ec*+e# an *rdinary cla## that can 3e e;tended in the regular !ay) :*u can ch**#e t* e;plicitly declare the +eth*d declarati*n# in an interface a# public) But they are public even i9 y*u d*nt #ay it) S* !hen y*u implement an interface, the +eth*d# 9r*+ the interface +u#t 3e de9ined a# public) Other!i#e they !*uld de9ault t* I9riendly,J

Cha"ter &* Inter$aces = Inner Classes

33#

and y*ud 3e reducing the acce##i3ility *9 a +eth*d during inheritance, !hich i# n*t all*!ed 3y the "ava c*+piler) :*u can #ee thi# in the +*di9ied ver#i*n *9 the Bnstrument e;a+ple) *te that every +eth*d in the interface i# #trictly a declarati*n, !hich i# the *nly thing the c*+piler all*!#) -n additi*n, n*ne *9 the +eth*d# in Bnstrument are declared a# public, 3ut theyre aut*+atically public any!ay1 )B)1 -+ple+enting inter9ace can:t 3e declared virtual, #ince it# n*t rede9ining a cla##) *te that inter9ace# cant have c*+pileEti+e c*n#tant# GcheckH) //:c0I:Gu#icP.c# // 5nterface#. interface 5n#tru!ent ; // Co!pi e6ti!e con#tant: //! Co co!pi e con#tant# int i 9 P3 // Cannot ha*e !ethod definition#: *oid - ay013 // )uto!atica y pu$ ic #tring Vhat013 *oid )dDu#t013 < c a## Vind : 5n#tru!ent ; pu$ ic *irtua *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Vind.- ay01&13 < pu$ ic *irtua #tring Vhat01 ; return &Vind&3 < pu$ ic *irtua *oid )dDu#t01 ;< < c a## -ercu##ion pu$ ic *irtua Sy#te!.Con#o < pu$ ic *irtua &-ercu##ion&3 < pu$ ic *irtua < : 5n#tru!ent ; *oid - ay01 ; e.VriteLine0&-ercu##ion.- ay01&13 #tring Vhat01 ; return *oid )dDu#t01 ;<

33&

Thinking in C

www.ThinkingIn.!et

c a## Stringed : pu$ ic *irtua Sy#te!.Con#o < pu$ ic *irtua pu$ ic *irtua <

5n#tru!ent ; *oid - ay01 ; e.VriteLine0&#tringed.- ay01&13 #tring Vhat01 ; return &#tringed&3 < *oid )dDu#t01 ;<

c a## Bra## : Vind ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Bra##.- ay01&13 < pu$ ic o*erride *oid )dDu#t01 ; Sy#te!.Con#o e.VriteLine0&Bra##.)dDu#t01&13 < < c a## Vood.ind : Vind ; pu$ ic o*erride *oid - ay01 ; Sy#te!.Con#o e.VriteLine0&Vood.ind.- ay01&13 < pu$ ic o*erride #tring Vhat01 ; return &Vood.ind&3 < < pu$ ic c a## Gu#icP ; // :oe#n't care a$out type2 #o ne. type# // added to the #y#te! #ti .or% right: #tatic *oid tune05n#tru!ent i1 ; // ... i.- ay013 < #tatic *oid tune) 05n#tru!entJK e1 ; for0int i 9 03 i W e.Length3 iRR1 tune0eJiK13 < pu$ ic #tatic *oid Gain01 ; 5n#tru!entJK orche#tra 9 ne. 5n#tru!entJPK3 int i 9 03 // Opca#ting during addition to the array: orche#traJiRRK 9 ne. Vind013

Cha"ter &* Inter$aces = Inner Classes

33'

orche#traJiRRK 9 ne. orche#traJiRRK 9 ne. orche#traJiRRK 9 ne. orche#traJiRRK 9 ne. tune) 0orche#tra13 < < ///:8

-ercu##ion013 Stringed013 Bra##013 Vood.ind013

The re#t *9 the c*de !*rk# the #a+e) -t d*e#nt +atter i9 y*u are upca#ting t* a IregularJ cla## called Bnstrument, an abstract cla## called Bnstrument, *r t* an interface called Bnstrument) The 3ehavi*r i# the #a+e) -n 9act, y*u can #ee in the tune( ) +eth*d that there i#nt any evidence a3*ut !hether Bnstrument i# a IregularJ cla##, an abstract cla##, *r an interface) Thi# i# the intent1 Each appr*ach give# the pr*gra++er di99erent c*ntr*l *ver the !ay *34ect# are created and u#ed)

G@ulti$le inheritanceH in Aava


The interface i#nt #i+ply a I+*re pureJ 9*r+ *9 abstract cla##) -t ha# a higher purp*#e than that) Becau#e an interface ha# n* i+ple+entati*n at allRthat i#, there i# n* #t*rage a##*ciated !ith an interface[there# n*thing t* prevent +any interface# 9r*+ 3eing c*+3ined) Thi# i# valua3le 3ecau#e there are ti+e# !hen y*u need t* #ay I=n x i# an a and a b and a c)J -n C@@, thi# act *9 c*+3ining +ultiple cla## inter9ace# i# called multi"le inheritance, and it carrie# #*+e rather #ticky 3aggage 3ecau#e each cla## can have an i+ple+entati*n) -n "ava, y*u can per9*r+ the #a+e act, 3ut *nly *ne *9 the cla##e# can have an i+ple+entati*n, #* the pr*3le+# #een in C@@ d* n*t *ccur !ith "ava !hen c*+3ining +ultiple inter9ace#1
) + s tra c t o r C o n c re te 3 a s e C la s s in t e r 0 a c e 1 in t e r 0 a c e 2

...

...

in t e r 0 a c e n

3 a s e C la s s 7 u n c t io n s

in t e r 0 a c e 1

in t e r 0a c e 2

...

in t e r 0 a c e n

34(

Thinking in C

www.ThinkingIn.!et

-n a derived cla##, y*u arent 9*rced t* have a 3a#e cla## that i# either an abstract *r Ic*ncreteJ G*ne !ith n* abstract +eth*d#H) -9 y*u do inherit 9r*+ a n*nEinterface, y*u can inherit 9r*+ *nly *ne) =ll the re#t *9 the 3a#e ele+ent# +u#t 3e interface#) :*u place all the inter9ace na+e# a9ter the implements key!*rd and #eparate the+ !ith c*++a#) :*u can have a# +any interface# a# y*u !antReach *ne 3ec*+e# an independent type that y*u can upca#t t*) The 9*ll*!ing e;a+ple #h*!# a c*ncrete cla## c*+3ined !ith #everal interface# t* pr*duce a ne! cla##1 //:c0I:)d*enture.c# // Gu tip e interface#. interface 5CanHight ; *oid Hight013 < interface 5CanS.i! ; *oid S.i!013 < interface 5CanH y ; *oid H y013 < c a## )ctionCharacter ; pu$ ic *oid Hight01 ;Sy#te!.Con#o e.VriteLine0&Highting&13< < c a## Uero : )ctionCharacter2 5CanHight2 5CanS.i!2 5CanH y ; pu$ ic *oid S.i!01 ;Sy#te!.Con#o e.VriteLine0&S.i!!ing&13< pu$ ic *oid H y01 ;Sy#te!.Con#o e.VriteLine0&H ying&13< < pu$ ic c #tatic #tatic #tatic a## )d*enture ; *oid '05CanHight x1 ; x.Hight013 < *oid O05CanS.i! x1 ; x.S.i!013 < *oid N05CanH y x1 ; x.H y013 <

Cha"ter &* Inter$aces = Inner Classes

341

#tatic *oid V0)ctionCharacter x1 ; x.Hight013 < pu$ ic #tatic *oid Gain01 ; Uero h 9 ne. Uero013 '0h13 // 'reat it a# an 5CanHight O0h13 // 'reat it a# an 5CanS.i! N0h13 // 'reat it a# an 5CanH y V0h13 // 'reat it a# an )ctionCharacter < < ///:8 :*u can #ee that "ero c*+3ine# the c*ncrete cla## 'ctionCharacter !ith the inter9ace# Can:ight, Can#wim, and Can:ly) ,hen y*u c*+3ine a c*ncrete cla## !ith inter9ace# thi# !ay, the c*ncrete cla## +u#t c*+e 9ir#t, then the inter9ace#) GThe c*+piler give# an err*r *ther!i#e)H *te that the #ignature 9*r fight( ) i# the #a+e in the interface Can:ight and the cla## 'ctionCharacter, and that fight( ) i# not pr*vided !ith a de9initi*n in "ero) The rule 9*r an interface i# that y*u can inherit 9r*+ it Ga# y*u !ill #ee #h*rtlyH, 3ut then y*uve g*t an*ther interface) -9 y*u !ant t* create an *34ect *9 the ne! type, it +u#t 3e a cla## !ith all de9initi*n# pr*vided) Even th*ugh "ero d*e# n*t e;plicitly pr*vide a de9initi*n 9*r fight( ), the de9initi*n c*+e# al*ng !ith 'ctionCharacter #* it i# aut*+atically pr*vided and it# p*##i3le t* create *34ect# *9 "ero) -n cla## 'dventure, y*u can #ee that there are 9*ur +eth*d# that take a# argu+ent# the vari*u# inter9ace# and the c*ncrete cla##) ,hen a "ero *34ect i# created, it can 3e pa##ed t* any *9 the#e +eth*d#, !hich +ean# it i# 3eing upca#t t* each interface in turn) Becau#e *9 the !ay inter9ace# are de#igned in "ava, thi# !*rk# !ith*ut a hitch and !ith*ut any particular e99*rt *n the part *9 the pr*gra++er) Neep in +ind that the c*re rea#*n 9*r inter9ace# i# #h*!n in the a3*ve e;a+ple1 t* 3e a3le t* upca#t t* +*re than *ne 3a#e type) H*!ever, a #ec*nd rea#*n 9*r u#ing inter9ace# i# the #a+e a# u#ing an abstract 3a#e cla##1 t* prevent the client pr*gra++er 9r*+ +aking an *34ect *9 thi# cla## and t* e#ta3li#h that it i# *nly an inter9ace) Thi# 3ring# up a Due#ti*n1 Sh*uld y*u u#e an interface *r an abstract cla##F =n interface give# y*u the 3ene9it# *9 an abstract cla## and the 3ene9it# *9 an interface, #* i9 it# p*##i3le t* create y*ur 3a#e cla## !ith*ut any +eth*d de9initi*n# *r +e+3er varia3le# y*u #h*uld al!ay# pre9er

34)

Thinking in C

www.ThinkingIn.!et

interface# t* abstract cla##e#) -n 9act, i9 y*u kn*! #*+ething i# g*ing t* 3e a 3a#e cla##, y*ur 9ir#t ch*ice #h*uld 3e t* +ake it an interface, and *nly i9 y*ure 9*rced t* have +eth*d de9initi*n# *r +e+3er varia3le# #h*uld y*u change t* an abstract cla##, *r i9 nece##ary a c*ncrete cla##)

(a#e collisions when co#+ining inter0aces


:*u can enc*unter a #+all pit9all !hen i+ple+enting +ultiple inter9ace#) -n the a3*ve e;a+ple, 3*th Can:ight and 'ctionCharacter have an identical void fight( ) +eth*d) Thi# i# n* pr*3le+ 3ecau#e the +eth*d i# identical in 3*th ca#e#, 3ut !hat i9 it# n*tF Here# an e;a+ple1 E;plicit inter9ace i+ple+entati*n //:c0I:5nterfaceCo i#ion.c# interface 5" ; *oid H013 < interface 52 ; int H0int i13 < interface 5T ; int H013 < c a## C ; pu$ ic *irtua int H01 ; return "3 < < c a## C2 : 5"2 52 ; pu$ ic *oid H01 ;< pu$ ic int H0int i1 ; return "3 < < c a## CT : C2 52 ; pu$ ic int H0int i1 ; return "3 < < c a## CE : C2 5T ; // 5dentica 2 no pro$ e!: pu$ ic o*erride int H01 ; return "3 < < c a## CP : C 2 5" ; pu$ ic o*erride int H01; return "3 < *oid 5".H01; < < interface 5E : 5"2 5T ;<

Cha"ter &* Inter$aces = Inner Classes

343

c a## C?: 5E; *oid 5".H01 ; < int 5T.H01 ; return "3 < <///:8 The di99iculty *ccur# 3ecau#e *verriding, i+ple+entati*n, and *verl*ading get unplea#antly +i;ed t*gether, and *verl*aded 9uncti*n# cann*t di99er *nly 3y return type) ,hen the la#t t!* line# are unc*++ented, the err*r +e##age# #ay it all1 Inter$aceCollision.3a-a*)3* $AB in C cannot im"lement $AB in I17 attem"ting to use incom"ati2le return t4"e $ound * int re8uired* -oid Inter$aceCollision.3a-a*)4* inter$aces I3 and I1 are incom"ati2le7 2oth de$ine $AB6 2ut with di$$erent return t4"e U#ing the #a+e +eth*d na+e# in di99erent inter9ace# that are intended t* 3e c*+3ined generally cau#e# c*n9u#i*n in the reada3ility *9 the c*de, a# !ell) Strive t* av*id it)

%&tending an inter0ace with inheritance


:*u can ea#ily add ne! +eth*d declarati*n# t* an interface u#ing inheritance, and y*u can al#* c*+3ine #everal interface# int* a ne! interface !ith inheritance) -n 3*th ca#e# y*u get a ne! interface, a# #een in thi# e;a+ple1 //:c0I:UorrorSho..c# // +xtending an interface .ith inheritance. interface Gon#ter ; *oid Genace013 < interface :angerou#Gon#ter : Gon#ter ; *oid :e#troy013 <

344

Thinking in C

www.ThinkingIn.!et

interface Letha *oid ai 013 <

c a## :ragonbi a : :angerou#Gon#ter ; pu$ ic *oid Genace01 ;< pu$ ic *oid :e#troy01 ;< < interface Na!pire : :angerou#Gon#ter2 Letha *oid :rin%B ood013 < pu$ ic c a## UorrorSho. ; #tatic *oid O0Gon#ter $1 ; $.Genace013 < #tatic *oid N0:angerou#Gon#ter d1 ; d.Genace013 d.:e#troy013 < pu$ ic #tatic *oid Gain01 ; :ragonbi a if2 9 ne. :ragonbi a013 O0if213 N0if213 < < ///:8 $angerous.onster i# a #i+ple e;ten#i*n t* .onster that pr*duce# a ne! interface) Thi# i# i+ple+ented in $ragon\illa) The #ynta; u#ed in Hampire !*rk# onl4 !hen inheriting inter9ace#) *r+ally, y*u can u#e extends !ith *nly a #ingle cla##, 3ut #ince an interface can 3e +ade 9r*+ +ultiple *ther inter9ace#, extends can re9er t* +ultiple 3a#e inter9ace# !hen 3uilding a ne! interface) =# y*u can #ee, the interface na+e# are #i+ply #eparated !ith c*++a#) ;

Cha"ter &* Inter$aces = Inner Classes

345

4oesnt wor* in C#. @ust have section on enu#s and structs earlier
Becau#e any 9ield# y*u put int* an interface are aut*+atically static and final, the interface i# a c*nvenient t**l 9*r creating gr*up# *9 c*n#tant value#, +uch a# y*u !*uld !ith an enum in C *r C@@) 5*r e;a+ple1 //:c0I:Gonth#.Da*a // O#ing interface# to create group# of con#tant#. pac%age c0I3 pu$ ic interface Gonth# ; int `)CO)R/ 9 "2 H+BRO)R/ 9 22 G)RCU 9 T2 )-R5L 9 E2 G)/ 9 P2 `OC+ 9 ?2 `OL/ 9 F2 )O_OS' 9 I2 S+-'+GB+R 9 >2 OC'OB+R 9 "02 CON+GB+R 9 ""2 :+C+GB+R 9 "23 < ///:8 *tice the "ava #tyle *9 u#ing all upperca#e letter# G!ith under#c*re# t* #eparate +ultiple !*rd# in a #ingle identi9ierH 9*r static final# that have c*n#tant initiali7er#) The 9ield# in an interface are aut*+atically public, #* it# unnece##ary t* #peci9y that) *! y*u can u#e the c*n#tant# 9r*+ *ut#ide the package 3y i+p*rting c4]6; *r c4]6.onths 4u#t a# y*u !*uld !ith any *ther package, and re9erencing the value# !ith e;pre##i*n# like .onths6X',V'*@) O9 c*ur#e, !hat y*u get i# 4u#t an int, #* there i#nt the e;tra type #a9ety that C@@# enum ha#, 3ut thi# Gc*++*nly u#edH techniDue i# certainly an i+pr*ve+ent *ver hardEc*ding nu+3er# int* y*ur pr*gra+#) GThat appr*ach i# *9ten re9erred t* a# u#ing I+agic nu+3er#J and it pr*duce# very di99icultEt*E+aintain c*de)H -9 y*u d* !ant e;tra type #a9ety, y*u can 3uild a cla## like thi# 01
0 Thi# appr*ach !a# in#pired 3y an eE+ail 9r*+ Rich H*99arth)

346

Thinking in C

www.ThinkingIn.!et

//: c0I:Gonth2.Da*a // ) !ore ro$u#t enu!eration #y#te!. pac%age c0I3 pu$ ic fina c a## Gonth2 ; pri*ate String na!e3 pri*ate int order3 pri*ate Gonth20int ord2 String n!1 ; order 9 ord3 na!e 9 n!3 < pu$ ic String toString01 ; return na!e3 < pu$ ic fina #tatic Gonth2 `)C 9 ne. Gonth20"2 &`anuary&12 H+B 9 ne. Gonth2022 &He$ruary&12 G)R 9 ne. Gonth20T2 &Garch&12 )-R 9 ne. Gonth20E2 &)pri &12 G)/ 9 ne. Gonth20P2 &Gay&12 `OC 9 ne. Gonth20?2 &`une&12 `OL 9 ne. Gonth20F2 &`u y&12 )O_ 9 ne. Gonth20I2 &)ugu#t&12 S+- 9 ne. Gonth20>2 &Septe!$er&12 OC' 9 ne. Gonth20"02 &Octo$er&12 CON 9 ne. Gonth20""2 &Co*e!$er&12 :+C 9 ne. Gonth20"22 &:ece!$er&13 pu$ ic fina #tatic Gonth2JK !onth 9 ; `)C2 H+B2 G)R2 )-R2 G)/2 `OC2 `OL2 )O_2 S+-2 OC'2 CON2 :+C <3 pu$ ic fina #tatic Gonth2 nu!$er0int ord1 ; return !onthJord 6 "K3 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; Gonth2 ! 9 Gonth2.`)C3 Sy#te!.out.print n0!13 ! 9 Gonth2.nu!$er0"213 Sy#te!.out.print n0!13 Sy#te!.out.print n0! 99 Gonth2.:+C13 Sy#te!.out.print n0!.e7ua #0Gonth2.:+C113 < < ///:8

Cha"ter &* Inter$aces = Inner Classes

34#

The cla## i# called .onth8, #ince there# already a .onth in the #tandard "ava li3rary) -t# a final cla## !ith a private c*n#truct*r #* n* *ne can inherit 9r*+ it *r +ake any in#tance# *9 it) The *nly in#tance# are the final static *ne# created in the cla## it#el91 X',, :&B, .'*, etc) The#e *34ect# are al#* u#ed in the array month, !hich let# y*u iterate thr*ugh an array *9 .onth8 *34ect#) The number( ) +eth*d all*!# y*u t* #elect a .onth8 3y giving it# c*rre#p*nding +*nth nu+3er) -n main( ) y*u can #ee the type #a9ety1 m i# a .onth8 *34ect #* it can 3e a##igned *nly t* a .onth8) The previ*u# e;a+ple .onths6)ava pr*vided *nly int value#, #* an int varia3le intended t* repre#ent a +*nth c*uld actually 3e given any integer value, !hich !a#nt very #a9e) Thi# appr*ach al#* all*!# y*u t* u#e II *r e%uals( ) interchangea3ly, a# #h*!n at the end *9 main( )) Thi# !*rk# 3ecau#e there can 3e *nly *ne in#tance *9 each value *9 .onth8)

Initiali:ing 0ields in inter0aces


5ield# de9ined in inter9ace# are aut*+atically static and final) The#e cann*t 3e I3lank 9inal#,J 3ut they can 3e initiali7ed !ith n*nc*n#tant e;pre##i*n#) 5*r e;a+ple1 //: c0I:RandNa #.Da*a // 5nitia iMing interface fie d# .ith // non6con#tant initia iMer#. i!port Da*a.uti .=3 pu$ ic interface RandNa # ; int rint 9 0int10Gath.rando!01 = "013 ong r ong 9 0 ong10Gath.rando!01 = "013 f oat rf oat 9 0f oat10Gath.rando!01 = "013 dou$ e rdou$ e 9 Gath.rando!01 = "03 < ///:8 Since the 9ield# are static, they are initiali7ed !hen the cla## i# 9ir#t l*aded, !hich happen# !hen any *9 the 9ield# are acce##ed 9*r the 9ir#t ti+e) Here# a #i+ple te#t1 //: c0I:'e#tRandNa #.Da*a

34&

Thinking in C

www.ThinkingIn.!et

pu$ ic c a## 'e#tRandNa # ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; Sy#te!.out.print n0RandNa #.rint13 Sy#te!.out.print n0RandNa #.r ong13 Sy#te!.out.print n0RandNa #.rf oat13 Sy#te!.out.print n0RandNa #.rdou$ e13 < < ///:8 The 9ield#, *9 c*ur#e, are n*t part *9 the inter9ace 3ut in#tead are #t*red in the static #t*rage area 9*r that inter9ace)

(esting inter0aces
-nter9ace# +ay 3e ne#ted !ithin cla##e# and !ithin *ther inter9ace#) Thi# reveal# a nu+3er *9 very intere#ting 9eature#1
2

//: c0I:Ce#ting5nterface#.Da*a c a## ) ; interface B ; *oid f013 < pu$ ic c a## B5!p i!p e!ent# B ; pu$ ic *oid f01 ;< < pri*ate c a## B5!p2 i!p e!ent# B ; pu$ ic *oid f01 ;< < pu$ ic interface C ; *oid f013 < c a## C5!p i!p e!ent# C ; pu$ ic *oid f01 ;< < pri*ate c a## C5!p2 i!p e!ent# C ; pu$ ic *oid f01 ;< < pri*ate interface : ; *oid f013
2 Thank# t* Aartin ?anner 9*r a#king thi# Due#ti*n during a #e+inar)

Cha"ter &* Inter$aces = Inner Classes

34'

< pri*ate c a## :5!p i!p e!ent# : ; pu$ ic *oid f01 ;< < pu$ ic c a## :5!p2 i!p e!ent# : ; pu$ ic *oid f01 ;< < pu$ ic : get:01 ; return ne. :5!p2013 < pri*ate : dRef3 pu$ ic *oid recei*e:0: d1 ; dRef 9 d3 dRef.f013 < < interface + ; interface _ ; *oid f013 < // Redundant &pu$ ic&: pu$ ic interface U ; *oid f013 < *oid g013 // Cannot $e pri*ate .ithin an interface: //! pri*ate interface 5 ;< < pu$ ic c a## Ce#ting5nterface# ; pu$ ic c a## B5!p i!p e!ent# ).B ; pu$ ic *oid f01 ;< < c a## C5!p i!p e!ent# ).C ; pu$ ic *oid f01 ;< < // Cannot i!p e!ent a pri*ate interface except // .ithin that interface'# defining c a##: //! c a## :5!p i!p e!ent# ).: ; //! pu$ ic *oid f01 ;< //! < c a## +5!p i!p e!ent# + ;

35(

Thinking in C

www.ThinkingIn.!et

pu$ ic *oid g01 ;< < c a## +_5!p i!p e!ent# +._ ; pu$ ic *oid f01 ;< < c a## +5!p2 i!p e!ent# + ; pu$ ic *oid g01 ;< c a## +_ i!p e!ent# +._ ; pu$ ic *oid f01 ;< < < pu$ ic #tatic *oid !ain0StringJK arg#1 ; ) a 9 ne. )013 // Can't acce## ).:: //! ).: ad 9 a.get:013 // :oe#n't return anything $ut ).:: //! ).:5!p2 di2 9 a.get:013 // Cannot acce## a !e!$er of the interface: //! a.get:01.f013 // On y another ) can do anything .ith get:01: ) a2 9 ne. )013 a2.recei*e:0a.get:0113 < < ///:8 The #ynta; 9*r ne#ting an inter9ace !ithin a cla## i# rea#*na3ly *3vi*u#, and 4u#t like n*nEne#ted inter9ace# the#e can have public *r I9riendlyJ vi#i3ility) :*u can al#* #ee that 3*th public and I9riendlyJ ne#ted inter9ace# can 3e i+ple+ented a# public, I9riendly,J and private ne#ted cla##e#) =# a ne! t!i#t, inter9ace# can al#* 3e private a# #een in '6$ Gthe #a+e Duali9icati*n #ynta; i# u#ed 9*r ne#ted inter9ace# a# 9*r ne#ted cla##e#H) ,hat g**d i# a private ne#ted inter9aceF :*u +ight gue## that it can *nly 3e i+ple+ented a# a private ne#ted cla## a# in $Bmp, 3ut '6$Bmp8 #h*!# that it can al#* 3e i+ple+ented a# a public cla##) H*!ever, '6$Bmp8 can *nly 3e u#ed a# it#el9) :*u are n*t all*!ed t* +enti*n the 9act that it i+ple+ent# the private inter9ace, #* i+ple+enting a private inter9ace i# a !ay t* 9*rce the de9initi*n *9 the +eth*d# in that inter9ace !ith*ut adding any type in9*r+ati*n Gthat i#, !ith*ut all*!ing any upca#tingH)

Cha"ter &* Inter$aces = Inner Classes

351

The +eth*d get$( ) pr*duce# a 9urther Duandary c*ncerning the private inter9ace1 it# a public +eth*d that return# a re9erence t* a private inter9ace) ,hat can y*u d* !ith the return value *9 thi# +eth*dF -n main( ), y*u can #ee #everal atte+pt# t* u#e the return value, all *9 !hich 9ail) The *nly thing that !*rk# i# i9 the return value i# handed t* an *34ect that ha# per+i##i*n t* u#e itRin thi# ca#e, an*ther ', via the receive$( ) +eth*d) -nter9ace & #h*!# that inter9ace# can 3e ne#ted !ithin each *ther) H*!ever, the rule# a3*ut inter9ace#Rin particular, that all inter9ace ele+ent# +u#t 3e publicRare #trictly en9*rced here, #* an inter9ace ne#ted !ithin an*ther inter9ace i# aut*+atically public and cann*t 3e +ade private) ,estingBnterfaces #h*!# the vari*u# !ay# that ne#ted inter9ace# can 3e i+ple+ented) -n particular, n*tice that !hen y*u i+ple+ent an inter9ace, y*u are n*t reDuired t* i+ple+ent any inter9ace# ne#ted !ithin) =l#*, private inter9ace# cann*t 3e i+ple+ented *ut#ide *9 their de9ining cla##e#) -nitially, the#e 9eature# +ay #ee+ like they are added #trictly 9*r #yntactic c*n#i#tency, 3ut - generally 9ind that *nce y*u kn*! a3*ut a 9eature, y*u *9ten di#c*ver place# !here it i# u#e9ul)

Inner classes
-t# p*##i3le t* place a cla## de9initi*n !ithin an*ther cla## de9initi*n) Thi# i# called an inner class) The inner cla## i# a valua3le 9eature 3ecau#e it all*!# y*u t* gr*up cla##e# that l*gically 3el*ng t*gether and t* c*ntr*l the vi#i3ility *9 *ne !ithin the *ther) H*!ever, it# i+p*rtant t* under#tand that inner cla##e# are di#tinctly di99erent 9r*+ c*+p*#iti*n) O9ten, !hile y*ure learning a3*ut the+, the need 9*r inner cla##e# i#nt i++ediately *3vi*u#) =t the end *9 thi# #ecti*n, a9ter all *9 the #ynta; and #e+antic# *9 inner cla##e# have 3een de#cri3ed, y*ull 9ind e;a+ple# that #h*uld +ake clear the 3ene9it# *9 inner cla##e#)

35)

Thinking in C

www.ThinkingIn.!et

:*u create an inner cla## 4u#t a# y*ud e;pectR3y placing the cla## de9initi*n in#ide a #urr*unding cla##1 //: c0I:-arce ".Da*a // Creating inner c a##e#. pu$ ic c a## -arce " ; c a## Content# ; pri*ate int i 9 ""3 pu$ ic int *a ue01 ; return i3 < < c a## :e#tination ; pri*ate String a$e 3 :e#tination0String .here'o1 ; a$e 9 .here'o3 < String readLa$e 01 ; return a$e 3 < < // O#ing inner c a##e# oo%# Du#t i%e // u#ing any other c a##2 .ithin -arce ": pu$ ic *oid #hip0String de#t1 ; Content# c 9 ne. Content#013 :e#tination d 9 ne. :e#tination0de#t13 Sy#te!.out.print n0d.readLa$e 0113 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce " p 9 ne. -arce "013 p.#hip0&'anMania&13 < < ///:8 The inner cla##e#, !hen u#ed in#ide ship( ), l**k 4u#t like the u#e *9 any *ther cla##e#) Here, the *nly practical di99erence i# that the na+e# are ne#ted !ithin !arcel7) :*ull #ee in a !hile that thi# i#nt the *nly di99erence) A*re typically, an *uter cla## !ill have a +eth*d that return# a re9erence t* an inner cla##, like thi#1 //: c0I:-arce 2.Da*a // Returning a reference to an inner c a##.

Cha"ter &* Inter$aces = Inner Classes

353

pu$ ic c a## -arce 2 ; c a## Content# ; pri*ate int i 9 ""3 pu$ ic int *a ue01 ; return i3 < < c a## :e#tination ; pri*ate String a$e 3 :e#tination0String .here'o1 ; a$e 9 .here'o3 < String readLa$e 01 ; return a$e 3 < < pu$ ic :e#tination to0String #1 ; return ne. :e#tination0#13 < pu$ ic Content# cont01 ; return ne. Content#013 < pu$ ic *oid #hip0String de#t1 ; Content# c 9 cont013 :e#tination d 9 to0de#t13 Sy#te!.out.print n0d.readLa$e 0113 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce 2 p 9 ne. -arce 2013 p.#hip0&'anMania&13 -arce 2 7 9 ne. -arce 2013 // :efining reference# to inner c a##e#: -arce 2.Content# c 9 7.cont013 -arce 2.:e#tination d 9 7.to0&Borneo&13 < < ///:8 -9 y*u !ant t* +ake an *34ect *9 the inner cla## any!here e;cept 9r*+ !ithin a n*nEstatic +eth*d *9 the *uter cla##, y*u +u#t #peci9y the type *9 that *34ect a# 1uterClass!ame.InnerClass!ame, a# #een in main( ))

354

Thinking in C

www.ThinkingIn.!et

Inner classes and u$casting


S* 9ar, inner cla##e# d*nt #ee+ that dra+atic) =9ter all, i9 it# hiding y*ure a9ter, "ava already ha# a per9ectly g**d hiding +echani#+R4u#t all*! the cla## t* 3e I9riendlyJ Gvi#i3le *nly !ithin a packageH rather than creating it a# an inner cla##) H*!ever, inner cla##e# really c*+e int* their *!n !hen y*u #tart upca#ting t* a 3a#e cla##, and in particular t* an interface) GThe e99ect *9 pr*ducing an inter9ace re9erence 9r*+ an *34ect that i+ple+ent# it i# e##entially the #a+e a# upca#ting t* a 3a#e cla##)H That# 3ecau#e the inner cla##Rthe i+ple+entati*n *9 the interfaceRcan then 3e c*+pletely un#een and unavaila3le t* any*ne, !hich i# c*nvenient 9*r hiding the i+ple+entati*n) =ll y*u get 3ack i# a re9erence t* the 3a#e cla## *r the interface) 5ir#t, the c*++*n inter9ace# !ill 3e de9ined in their *!n 9ile# #* they can 3e u#ed in all the e;a+ple#1 //: c0I::e#tination.Da*a pu$ ic interface :e#tination ; String readLa$e 013 < ///:8 //: c0I:Content#.Da*a pu$ ic interface Content# ; int *a ue013 < ///:8 *! Contents and $estination repre#ent inter9ace# availa3le t* the client pr*gra++er) GThe interface, re+e+3er, aut*+atically +ake# all *9 it# +e+3er# public)H ,hen y*u get 3ack a re9erence t* the 3a#e cla## *r the interface, it# p*##i3le that y*u cant even 9ind *ut the e;act type, a# #h*!n here1 //: c0I:-arce T.Da*a // Returning a reference to an inner c a##. pu$ ic c a## -arce T ; pri*ate c a## -Content# i!p e!ent# Content# ; pri*ate int i 9 ""3

Cha"ter &* Inter$aces = Inner Classes

355

pu$ ic int *a ue01 ; return i3 < < protected c a## -:e#tination i!p e!ent# :e#tination ; pri*ate String a$e 3 pri*ate -:e#tination0String .here'o1 ; a$e 9 .here'o3 < pu$ ic String readLa$e 01 ; return a$e 3 < < pu$ ic :e#tination de#t0String #1 ; return ne. -:e#tination0#13 < pu$ ic Content# cont01 ; return ne. -Content#013 < < c a## 'e#t ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce T p 9 ne. -arce T013 Content# c 9 p.cont013 :e#tination d 9 p.de#t0&'anMania&13 // 5 ega 66 can't acce## pri*ate c a##: //! -arce T.-Content# pc 9 p.ne. -Content#013 < < ///:8 *te that #ince main( ) i# in +est, !hen y*u !ant t* run thi# pr*gra+ y*u d*nt e;ecute !arcel9, 3ut in#tead1 Da*a 'e#t -n the e;a+ple, main( ) +u#t 3e in a #eparate cla## in *rder t* de+*n#trate the privatene## *9 the inner cla## !Contents) -n !arcel9, #*+ething ne! ha# 3een added1 the inner cla## !Contents i# private #* n* *ne 3ut !arcel9 can acce## it) !$estination i# protected, #* n* *ne 3ut !arcel9, cla##e# in the !arcel9 package G#ince protected al#* give# package acce##Rthat i#, protected i# al#* I9riendlyJH, and the inherit*r# *9 !arcel9 can acce## !$estination) Thi# +ean# that the client pr*gra++er ha# re#tricted kn*!ledge and acce## t*

356

Thinking in C

www.ThinkingIn.!et

the#e +e+3er#) -n 9act, y*u cant even d*!nca#t t* a private inner cla## G*r a protected inner cla## unle## y*ure an inherit*rH, 3ecau#e y*u cant acce## the na+e, a# y*u can #ee in class +est) Thu#, the private inner cla## pr*vide# a !ay 9*r the cla## de#igner t* c*+pletely prevent any typeE c*ding dependencie# and t* c*+pletely hide detail# a3*ut i+ple+entati*n) -n additi*n, e;ten#i*n *9 an interface i# u#ele## 9r*+ the client pr*gra++er# per#pective #ince the client pr*gra++er cann*t acce## any additi*nal +eth*d# that arent part *9 the public interface) Thi# al#* pr*vide# an *pp*rtunity 9*r the "ava c*+piler t* generate +*re e99icient c*de) *r+al Gn*nEinnerH cla##e# cann*t 3e +ade private *r protected[*nly public *r I9riendly)J

Inner classes in #ethods and sco$es


,hat y*uve #een #* 9ar enc*+pa##e# the typical u#e 9*r inner cla##e#) -n general, the c*de that y*ull !rite and read inv*lving inner cla##e# !ill 3e IplainJ inner cla##e# that are #i+ple and ea#y t* under#tand) H*!ever, the de#ign 9*r inner cla##e# i# Duite c*+plete and there are a nu+3er *9 *ther, +*re *3#cure, !ay# that y*u can u#e the+ i9 y*u ch**#e1 inner cla##e# can 3e created !ithin a +eth*d *r even an ar3itrary #c*pe) There are t!* rea#*n# 9*r d*ing thi#1 1. 2. =# #h*!n previ*u#ly, y*ure i+ple+enting an inter9ace *9 #*+e kind #* that y*u can create and return a re9erence) :*ure #*lving a c*+plicated pr*3le+ and y*u !ant t* create a cla## t* aid in y*ur #*luti*n, 3ut y*u d*nt !ant it pu3licly availa3le)

-n the 9*ll*!ing e;a+ple#, the previ*u# c*de !ill 3e +*di9ied t* u#e1 1. 2. 3. = cla## de9ined !ithin a +eth*d = cla## de9ined !ithin a #c*pe in#ide a +eth*d =n an*ny+*u# cla## i+ple+enting an inter9ace

Cha"ter &* Inter$aces = Inner Classes

35#

. !. ".

=n an*ny+*u# cla## e;tending a cla## that ha# a n*nde9ault c*n#truct*r =n an*ny+*u# cla## that per9*r+# 9ield initiali7ati*n =n an*ny+*u# cla## that per9*r+# c*n#tructi*n u#ing in#tance initiali7ati*n Gan*ny+*u# inner cla##e# cann*t have c*n#truct*r#H

=lth*ugh it# an *rdinary cla## !ith an i+ple+entati*n, =rapping i# al#* 3eing u#ed a# a c*++*n Iinter9aceJ t* it# derived cla##e#1 //: c0I:Vrapping.Da*a pu$ ic c a## Vrapping ; pri*ate int i3 pu$ ic Vrapping0int x1 ; i 9 x3 < pu$ ic int *a ue01 ; return i3 < < ///:8 :*ull n*tice a3*ve that =rapping ha# a c*n#truct*r that reDuire# an argu+ent, t* +ake thing# a 3it +*re intere#ting) The 9ir#t e;a+ple #h*!# the creati*n *9 an entire cla## !ithin the #c*pe *9 a +eth*d Gin#tead *9 the #c*pe *9 an*ther cla##H1 //: c0I:-arce E.Da*a // Ce#ting a c a## .ithin a !ethod. pu$ ic c a## -arce E ; pu$ ic :e#tination de#t0String #1 ; c a## -:e#tination i!p e!ent# :e#tination ; pri*ate String a$e 3 pri*ate -:e#tination0String .here'o1 ; a$e 9 .here'o3 < pu$ ic String readLa$e 01 ; return a$e 3 < < return ne. -:e#tination0#13 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce E p 9 ne. -arce E013 :e#tination d 9 p.de#t0&'anMania&13

35&

Thinking in C

www.ThinkingIn.!et

< < ///:8 The cla## !$estination i# part *9 dest( ) rather than 3eing part *9 !arcelJ) G=l#* n*tice that y*u c*uld u#e the cla## identi9ier !$estination 9*r an inner cla## in#ide each cla## in the #a+e #u3direct*ry !ith*ut a na+e cla#h)H There9*re, !$estination cann*t 3e acce##ed *ut#ide *9 dest( )) *tice the upca#ting that *ccur# in the return #tate+entRn*thing c*+e# *ut *9 dest( ) e;cept a re9erence t* $estination, the 3a#e cla##) O9 c*ur#e, the 9act that the na+e *9 the cla## !$estination i# placed in#ide dest( ) d*e#nt +ean that !$estination i# n*t a valid *34ect *nce dest( ) return#) The ne;t e;a+ple #h*!# h*! y*u can ne#t an inner cla## !ithin any ar3itrary #c*pe1 //: c0I:-arce P.Da*a // Ce#ting a c a## .ithin a #cope. pu$ ic c a## -arce P ; pri*ate *oid interna 'rac%ing0$oo ean $1 ; if0$1 ; c a## 'rac%ingS ip ; pri*ate String id3 'rac%ingS ip0String #1 ; id 9 #3 < String getS ip01 ; return id3 < < 'rac%ingS ip t# 9 ne. 'rac%ingS ip0&# ip&13 String # 9 t#.getS ip013 < // Can't u#e it here! Out of #cope: //! 'rac%ingS ip t# 9 ne. 'rac%ingS ip0&x&13 < pu$ ic *oid trac%01 ; interna 'rac%ing0true13 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce P p 9 ne. -arce P013 p.trac%013 < < ///:8

Cha"ter &* Inter$aces = Inner Classes

35'

The cla## +rac(ing#lip i# ne#ted in#ide the #c*pe *9 an if #tate+ent) Thi# d*e# n*t +ean that the cla## i# c*nditi*nally createdRit get# c*+piled al*ng !ith everything el#e) H*!ever, it# n*t availa3le *ut#ide the #c*pe in !hich it i# de9ined) Other than that, it l**k# 4u#t like an *rdinary cla##)

)non5#ous inner classes


The ne;t e;a+ple l**k# a little #trange1 //: c0I:-arce ?.Da*a // ) !ethod that return# an anony!ou# inner c a##. pu$ ic c a## -arce ? ; pu$ ic Content# cont01 ; return ne. Content#01 ; pri*ate int i 9 ""3 pu$ ic int *a ue01 ; return i3 < <3 // Se!ico on re7uired in thi# ca#e < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce ? p 9 ne. -arce ?013 Content# c 9 p.cont013 < < ///:8 The cont( ) +eth*d c*+3ine# the creati*n *9 the return value !ith the de9initi*n *9 the cla## that repre#ent# that return valueK -n additi*n, the cla## i# an*ny+*u#Rit ha# n* na+e) T* +ake +atter# a 3it !*r#e, it l**k# like y*ure #tarting *ut t* create a Contents *34ect1 return ne. Content#01 But then, 3e9*re y*u get t* the #e+ic*l*n, y*u #ay, IBut !ait, - think -ll #lip in a cla## de9initi*nJ1 return ne. Content#01 ; pri*ate int i 9 ""3 pu$ ic int *a ue01 ; return i3 < <3

36(

Thinking in C

www.ThinkingIn.!et

,hat thi# #trange #ynta; +ean# i#1 ICreate an *34ect *9 an an*ny+*u# cla## that# inherited 9r*+ Contents)J The re9erence returned 3y the new e;pre##i*n i# aut*+atically upca#t t* a Contents re9erence) The an*ny+*u# innerEcla## #ynta; i# a #h*rthand 9*r1 c a## GyContent# i!p e!ent# Content# ; pri*ate int i 9 ""3 pu$ ic int *a ue01 ; return i3 < < return ne. GyContent#013 -n the an*ny+*u# inner cla##, Contents i# created u#ing a de9ault c*n#truct*r) The 9*ll*!ing c*de #h*!# !hat t* d* i9 y*ur 3a#e cla## need# a c*n#truct*r !ith an argu+ent1 //: c0I:-arce F.Da*a // )n anony!ou# inner c a## that ca // the $a#e6c a## con#tructor. #

pu$ ic c a## -arce F ; pu$ ic Vrapping .rap0int x1 ; // Ba#e con#tructor ca : return ne. Vrapping0x1 ; pu$ ic int *a ue01 ; return #uper.*a ue01 = EF3 < <3 // Se!ico on re7uired < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce F p 9 ne. -arce F013 Vrapping . 9 p..rap0"013 < < ///:8 That i#, y*u #i+ply pa## the appr*priate argu+ent t* the 3a#eEcla## c*n#truct*r, #een here a# the x pa##ed in new =rapping(x)) =n an*ny+*u# cla## cann*t have a c*n#truct*r !here y*u !*uld n*r+ally call super( )) -n 3*th *9 the previ*u# e;a+ple#, the #e+ic*l*n d*e#nt +ark the end *9 the cla## 3*dy Ga# it d*e# in C@@H) -n#tead, it +ark# the end *9 the

Cha"ter &* Inter$aces = Inner Classes

361

e;pre##i*n that happen# t* c*ntain the an*ny+*u# cla##) Thu#, it# identical t* the u#e *9 the #e+ic*l*n every!here el#e) ,hat happen# i9 y*u need t* per9*r+ #*+e kind *9 initiali7ati*n 9*r an *34ect *9 an an*ny+*u# inner cla##F Since it# an*ny+*u#, there# n* na+e t* give the c*n#truct*rR#* y*u cant have a c*n#truct*r) :*u can, h*!ever, per9*r+ initiali7ati*n at the p*int *9 de9initi*n *9 y*ur 9ield#1 //: c0I:-arce I.Da*a // )n anony!ou# inner c a## that perfor!# // initia iMation. ) $riefer *er#ion // of -arce P.Da*a. pu$ ic c a## -arce I ; // )rgu!ent !u#t $e fina to u#e in#ide // anony!ou# inner c a##: pu$ ic :e#tination de#t0fina String de#t1 ; return ne. :e#tination01 ; pri*ate String a$e 9 de#t3 pu$ ic String readLa$e 01 ; return a$e 3 < <3 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce I p 9 ne. -arce I013 :e#tination d 9 p.de#t0&'anMania&13 < < ///:8 -9 y*ure de9ining an an*ny+*u# inner cla## and !ant t* u#e an *34ect that# de9ined *ut#ide the an*ny+*u# inner cla##, the c*+piler reDuire# that the *ut#ide *34ect 3e final) Thi# i# !hy the argu+ent t* dest( ) i# final) -9 y*u 9*rget, y*ull get a c*+pileEti+e err*r +e##age) =# l*ng a# y*ure #i+ply a##igning a 9ield, the a3*ve appr*ach i# 9ine) But !hat i9 y*u need t* per9*r+ #*+e c*n#truct*rElike activityF ,ith instance initiali;ation, y*u can, in e99ect, create a c*n#truct*r 9*r an an*ny+*u# inner cla##1 //: c0I:-arce >.Da*a // O#ing &in#tance initia iMation& to perfor! // con#truction on an anony!ou# inner c a##.

36)

Thinking in C

www.ThinkingIn.!et

pu$ ic c a## -arce > ; pu$ ic :e#tination de#t0fina String de#t2 fina f oat price1 ; return ne. :e#tination01 ; pri*ate int co#t3 // 5n#tance initia iMation for each o$Dect: ; co#t 9 Gath.round0price13 if0co#t Z "001 Sy#te!.out.print n0&O*er $udget!&13 < pri*ate String a$e 9 de#t3 pu$ ic String readLa$e 01 ; return a$e 3 < <3 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce > p 9 ne. -arce >013 :e#tination d 9 p.de#t0&'anMania&2 "0".T>PH13 < < ///:8 -n#ide the in#tance initiali7er y*u can #ee c*de that c*uldnt 3e e;ecuted a# part *9 a 9ield initiali7er Gthat i#, the if #tate+entH) S* in e99ect, an in#tance initiali7er i# the c*n#truct*r 9*r an an*ny+*u# inner cla##) O9 c*ur#e, it# li+itedQ y*u cant *verl*ad in#tance initiali7er# #* y*u can have *nly *ne *9 the#e c*n#truct*r#)

-he lin* to the outer class


S* 9ar, it appear# that inner cla##e# are 4u#t a na+eEhiding and c*deE *rgani7ati*n #che+e, !hich i# help9ul 3ut n*t t*tally c*+pelling) H*!ever, there# an*ther t!i#t) ,hen y*u create an inner cla##, an *34ect *9 that inner cla## ha# a link t* the encl*#ing *34ect that +ade it, and #* it can acce## the +e+3er# *9 that encl*#ing *34ectRwithout any #pecial Duali9icati*n#) -n additi*n, inner cla##e# have acce## right# t* all the ele+ent# in the encl*#ing cla##/) The 9*ll*!ing e;a+ple de+*n#trate# thi#1
/ Thi# i# very di99erent 9r*+ the de#ign *9 nested classes in C@@, !hich i# #i+ply a na+eE

hiding +echani#+) There i# n* link t* an encl*#ing *34ect and n* i+plied per+i##i*n# in C@@)

Cha"ter &* Inter$aces = Inner Classes

363

//: c0I:Se7uence.Da*a // Uo d# a #e7uence of O$Dect#. interface Se ector ; $oo ean end013 O$Dect current013 *oid next013 < pu$ ic c a## Se7uence ; pri*ate O$DectJK o$#3 pri*ate int next 9 03 pu$ ic Se7uence0int #iMe1 ; o$# 9 ne. O$DectJ#iMeK3 < pu$ ic *oid add0O$Dect x1 ; if0next W o$#. ength1 ; o$#JnextK 9 x3 nextRR3 < < pri*ate c a## SSe ector i!p e!ent# Se ector ; int i 9 03 pu$ ic $oo ean end01 ; return i 99 o$#. ength3 < pu$ ic O$Dect current01 ; return o$#JiK3 < pu$ ic *oid next01 ; if0i W o$#. ength1 iRR3 < < pu$ ic Se ector getSe ector01 ; return ne. SSe ector013 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; Se7uence # 9 ne. Se7uence0"013 for0int i 9 03 i W "03 iRR1 #.add05nteger.toString0i113 Se ector # 9 #.getSe ector013

364

Thinking in C

www.ThinkingIn.!et

.hi e0!# .end011 ; Sy#te!.out.print n0# .current0113 # .next013 < < < ///:8 The #e%uence i# #i+ply a 9i;edE#i7ed array *9 ob)ect !ith a cla## !rapped ar*und it) :*u call add( ) t* add a ne! ob)ect t* the end *9 the #eDuence Gi9 there# r**+ le9tH) T* 9etch each *9 the *34ect# in a #e%uence, there# an inter9ace called #elector, !hich all*!# y*u t* #ee i9 y*ure at the end( ), t* l**k at the current( ) ob)ect, and t* +*ve t* the next( ) ob)ect in the #e%uence) Becau#e #elector i# an interface, +any *ther cla##e# can i+ple+ent the interface in their *!n !ay#, and +any +eth*d# can take the interface a# an argu+ent, in *rder t* create generic c*de) Here, the ##elector i# a private cla## that pr*vide# #elector 9uncti*nality) -n main( ), y*u can #ee the creati*n *9 a #e%uence, 9*ll*!ed 3y the additi*n *9 a nu+3er *9 #tring *34ect#) Then, a #elector i# pr*duced !ith a call t* get#elector( ) and thi# i# u#ed t* +*ve thr*ugh the #e%uence and #elect each ite+) =t 9ir#t, the creati*n *9 ##elector l**k# like 4u#t an*ther inner cla##) But e;a+ine it cl*#ely) *te that each *9 the +eth*d# end( ), current( ), and next( ) re9er t* obs, !hich i# a re9erence that i#nt part *9 ##elector, 3ut i# in#tead a private 9ield in the encl*#ing cla##) H*!ever, the inner cla## can acce## +eth*d# and 9ield# 9r*+ the encl*#ing cla## a# i9 they *!ned the+) Thi# turn# *ut t* 3e very c*nvenient, a# y*u can #ee in the a3*ve e;a+ple) S* an inner cla## ha# aut*+atic acce## t* the +e+3er# *9 the encl*#ing cla##) H*! can thi# happenF The inner cla## +u#t keep a re9erence t* the particular *34ect *9 the encl*#ing cla## that !a# re#p*n#i3le 9*r creating it) Then !hen y*u re9er t* a +e+3er *9 the encl*#ing cla##, that GhiddenH re9erence i# u#ed t* #elect that +e+3er) 5*rtunately, the c*+piler take# care *9 all the#e detail# 9*r y*u, 3ut y*u can al#* under#tand n*! that an *34ect *9 an inner cla## can 3e created *nly in a##*ciati*n !ith an *34ect *9 the encl*#ing cla##) C*n#tructi*n *9 the inner cla## *34ect reDuire# the re9erence t* the *34ect *9 the encl*#ing cla##, and the c*+piler !ill

Cha"ter &* Inter$aces = Inner Classes

365

c*+plain i9 it cann*t acce## that re9erence) A*#t *9 the ti+e thi# *ccur# !ith*ut any interventi*n *n the part *9 the pr*gra++er)

static inner classes


-9 y*u d*nt need a c*nnecti*n 3et!een the inner cla## *34ect and the *uter cla## *34ect, then y*u can +ake the inner cla## static) T* under#tand the +eaning *9 static !hen applied t* inner cla##e#, y*u +u#t re+e+3er that the *34ect *9 an *rdinary inner cla## i+plicitly keep# a re9erence t* the *34ect *9 the encl*#ing cla## that created it) Thi# i# n*t true, h*!ever, !hen y*u #ay an inner cla## i# static) = static inner cla## +ean#1 1. 2. :*u d*nt need an *uterEcla## *34ect in *rder t* create an *34ect *9 a static inner cla##) :*u cant acce## an *uterEcla## *34ect 9r*+ an *34ect *9 a static inner cla##)

static inner cla##e# are di99erent than n*nEstatic inner cla##e# in an*ther !ay, a# !ell) 5ield# and +eth*d# in n*nEstatic inner cla##e# can *nly 3e at the *uter level *9 a cla##, #* n*nEstatic inner cla##e# cann*t have static data, static 9ield#, *r static inner cla##e#) H*!ever, static inner cla##e# can have all *9 the#e1 //: c0I:-arce "0.Da*a // Static inner c a##e#. pu$ ic c a## -arce "0 ; pri*ate #tatic c a## -Content# i!p e!ent# Content# ; pri*ate int i 9 ""3 pu$ ic int *a ue01 ; return i3 < < protected #tatic c a## -:e#tination i!p e!ent# :e#tination ; pri*ate String a$e 3 pri*ate -:e#tination0String .here'o1 ; a$e 9 .here'o3 < pu$ ic String readLa$e 01 ; return a$e 3 <

366

Thinking in C

www.ThinkingIn.!et

// Static inner c a##e# can contain // other #tatic e e!ent#: pu$ ic #tatic *oid f01 ;< #tatic int x 9 "03 #tatic c a## )notherLe*e ; pu$ ic #tatic *oid f01 ;< #tatic int x 9 "03 < < pu$ ic #tatic :e#tination de#t0String #1 ; return ne. -:e#tination0#13 < pu$ ic #tatic Content# cont01 ; return ne. -Content#013 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; Content# c 9 cont013 :e#tination d 9 de#t0&'anMania&13 < < ///:8 -n main( ), n* *34ect *9 !arcel74 i# nece##aryQ in#tead y*u u#e the n*r+al #ynta; 9*r #electing a static +e+3er t* call the +eth*d# that return re9erence# t* Contents and $estination) =# y*u !ill #ee #h*rtly, in an *rdinary Gn*nEstaticH inner cla##, the link t* the *uter cla## *34ect i# achieved !ith a #pecial this re9erence) = static inner cla## d*e# n*t have thi# #pecial this re9erence, !hich +ake# it anal*g*u# t* a static +eth*d) *r+ally y*u cant put any c*de in#ide an interface, 3ut a static inner cla## can 3e part *9 an interface) Since the cla## i# static it d*e#nt vi*late the rule# 9*r inter9ace#Rthe static inner cla## i# *nly placed in#ide the na+e#pace *9 the inter9ace1 //: c0I:55nterface.Da*a // Static inner c a##e# in#ide interface#. pu$ ic interface 55nterface ; #tatic c a## 5nner ; int i2 D2 %3

Cha"ter &* Inter$aces = Inner Classes

36#

pu$ ic 5nner01 ;< *oid f01 ;< < < ///:8 Earlier in thi# 3**k - #ugge#ted putting a main( ) in every cla## t* act a# a te#t 3ed 9*r that cla##) One dra!3ack t* thi# i# the a+*unt *9 e;tra c*+piled c*de y*u +u#t carry ar*und) -9 thi# i# a pr*3le+, y*u can u#e a static inner cla## t* h*ld y*ur te#t c*de1 //: c0I:'e#tBed.Da*a // -utting te#t code in a #tatic inner c a##. pu$ ic c a## 'e#tBed ; 'e#tBed01 ;< *oid f01 ; Sy#te!.out.print n0&f01&13 < pu$ ic #tatic c a## 'e#ter ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; 'e#tBed t 9 ne. 'e#tBed013 t.f013 < < < ///:8 Thi# generate# a #eparate cla## called +estBed^+ester Gt* run the pr*gra+, y*u #ay )ava +estBed^+esterH) :*u can u#e thi# cla## 9*r te#ting, 3ut y*u d*nt need t* include it in y*ur #hipping pr*duct)

6e0erring to the outer class o+/ect


-9 y*u need t* pr*duce the re9erence t* the *uter cla## *34ect, y*u na+e the *uter cla## 9*ll*!ed 3y a d*t and this) 5*r e;a+ple, in the cla## #e%uence6##elector, any *9 it# +eth*d# can pr*duce the #t*red re9erence t* the *uter cla## #e%uence 3y #aying #e%uence6this) The re#ulting re9erence i# aut*+atically the c*rrect type) GThi# i# kn*!n and checked at c*+pileEti+e, #* there i# n* runEti+e *verhead)H S*+eti+e# y*u !ant t* tell #*+e *ther *34ect t* create an *34ect *9 *ne *9 it# inner cla##e#) T* d* thi# y*u +u#t pr*vide a re9erence t* the *ther *uter cla## *34ect in the new e;pre##i*n, like thi#1 //: c0I:-arce "".Da*a

36&

Thinking in C

www.ThinkingIn.!et

// Creating in#tance# of inner c a##e#. pu$ ic c a## -arce "" ; c a## Content# ; pri*ate int i 9 ""3 pu$ ic int *a ue01 ; return i3 < < c a## :e#tination ; pri*ate String a$e 3 :e#tination0String .here'o1 ; a$e 9 .here'o3 < String readLa$e 01 ; return a$e 3 < < pu$ ic #tatic *oid !ain0StringJK arg#1 ; -arce "" p 9 ne. -arce ""013 // Gu#t u#e in#tance of outer c a## // to create an in#tance# of the inner c a##: -arce "".Content# c 9 p.ne. Content#013 -arce "".:e#tination d 9 p.ne. :e#tination0&'anMania&13 < < ///:8 T* create an *34ect *9 the inner cla## directly, y*u d*nt 9*ll*! the #a+e 9*r+ and re9er t* the *uter cla## na+e !arcel77 a# y*u +ight e;pect, 3ut in#tead y*u +u#t u#e an o23ect *9 the *uter cla## t* +ake an *34ect *9 the inner cla##1 -arce "".Content# c 9 p.ne. Content#013 Thu#, it# n*t p*##i3le t* create an *34ect *9 the inner cla## unle## y*u already have an *34ect *9 the *uter cla##) Thi# i# 3ecau#e the *34ect *9 the inner cla## i# Duietly c*nnected t* the *34ect *9 the *uter cla## that it !a# +ade 9r*+) H*!ever, i9 y*u +ake a static inner cla##, then it d*e#nt need a re9erence t* the *uter cla## *34ect)

Cha"ter &* Inter$aces = Inner Classes

36'

6eaching outward 0ro# a #ulti$l5; nested class


-t d*e#nt +atter h*! deeply an inner cla## +ay 3e ne#tedRit can tran#parently acce## all *9 the +e+3er# *9 all the cla##e# it i# ne#ted !ithin, a# #een here1
&

//: c0I:Gu tiCe#ting)cce##.Da*a // Ce#ted c a##e# can acce## a !e!$er# of a // e*e # of the c a##e# they are ne#ted .ithin. c a## GC) ; pri*ate *oid f01 ;< c a## ) ; pri*ate *oid g01 ;< pu$ ic c a## B ; *oid h01 ; g013 f013 < < < < pu$ ic c a## Gu tiCe#ting)cce## ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; GC) !na 9 ne. GC)013 GC).) !naa 9 !na.ne. )013 GC).).B !naa$ 9 !naa.ne. B013 !naa$.h013 < < ///:8 :*u can #ee that in .,'6'6B, the +eth*d# g( ) and f( ) are calla3le !ith*ut any Duali9icati*n Gde#pite the 9act that they are privateH) Thi# e;a+ple al#* de+*n#trate# the #ynta; nece##ary t* create *34ect# *9 +ultiplyEne#ted inner cla##e# !hen y*u create the *34ect# in a di99erent cla##) The I6newJ #ynta; pr*duce# the c*rrect #c*pe #* y*u d* n*t have t* Duali9y the cla## na+e in the c*n#truct*r call)
& Thank# again t* Aartin ?anner)

3#(

Thinking in C

www.ThinkingIn.!et

Inheriting 0ro# inner classes


Becau#e the inner cla## c*n#truct*r +u#t attach t* a re9erence *9 the encl*#ing cla## *34ect, thing# are #lightly c*+plicated !hen y*u inherit 9r*+ an inner cla##) The pr*3le+ i# that the I#ecretJ re9erence t* the encl*#ing cla## *34ect must 3e initiali7ed, and yet in the derived cla## there# n* l*nger a de9ault *34ect t* attach t*) The an#!er i# t* u#e a #ynta; pr*vided t* +ake the a##*ciati*n e;plicit1 //: c0I:5nherit5nner.Da*a // 5nheriting an inner c a##. c a## Vith5nner ; c a## 5nner ;< < pu$ ic c a## 5nherit5nner extend# Vith5nner.5nner ; //! 5nherit5nner01 ;< // Von't co!pi e 5nherit5nner0Vith5nner .i1 ; .i.#uper013 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; Vith5nner .i 9 ne. Vith5nner013 5nherit5nner ii 9 ne. 5nherit5nner0.i13 < < ///:8 :*u can #ee that BnheritBnner i# e;tending *nly the inner cla##, n*t the *uter *ne) But !hen it c*+e# ti+e t* create a c*n#truct*r, the de9ault *ne i# n* g**d and y*u cant 4u#t pa## a re9erence t* an encl*#ing *34ect) -n additi*n, y*u +u#t u#e the #ynta; enc o#ingC a##Reference.#uper013 in#ide the c*n#truct*r) Thi# pr*vide# the nece##ary re9erence and the pr*gra+ !ill then c*+pile)

Cha"ter &* Inter$aces = Inner Classes

3#1

Can inner classes +e overridden<


,hat happen# !hen y*u create an inner cla##, then inherit 9r*+ the encl*#ing cla## and rede9ine the inner cla##F That i#, i# it p*##i3le t* *verride an inner cla##F Thi# #ee+# like it !*uld 3e a p*!er9ul c*ncept, 3ut I*verridingJ an inner cla## a# i9 it !ere an*ther +eth*d *9 the *uter cla## d*e#nt really d* anything1 //: c0I:Big+gg.Da*a // )n inner c a## cannot $e o*erriden // i%e a !ethod. c a## +gg ; protected c a## /o % ; pu$ ic /o %01 ; Sy#te!.out.print n0&+gg./o %01&13 < < pri*ate /o % y3 pu$ ic +gg01 ; Sy#te!.out.print n0&Ce. +gg01&13 y 9 ne. /o %013 < < pu$ ic c a## Big+gg extend# +gg ; pu$ ic c a## /o % ; pu$ ic /o %01 ; Sy#te!.out.print n0&Big+gg./o %01&13 < < pu$ ic #tatic *oid !ain0StringJK arg#1 ; ne. Big+gg013 < < ///:8 The de9ault c*n#truct*r i# #ynthe#i7ed aut*+atically 3y the c*+piler, and thi# call# the 3a#eEcla## de9ault c*n#truct*r) :*u +ight think that #ince a Big&gg i# 3eing created, the I*verriddenJ ver#i*n *9 @ol( !*uld 3e u#ed, 3ut thi# i# n*t the ca#e) The *utput i#1

3#)

Thinking in C

www.ThinkingIn.!et

Ce. +gg01 +gg./o %01 Thi# e;a+ple #i+ply #h*!# that there i#nt any e;tra inner cla## +agic g*ing *n !hen y*u inherit 9r*+ the *uter cla##) The t!* inner cla##e# are c*+pletely #eparate entitie#, each in their *!n na+e#pace) H*!ever, it# #till p*##i3le t* e;plicitly inherit 9r*+ the inner cla##1 //: c0I:Big+gg2.Da*a // -roper inheritance of an inner c a##. c a## +gg2 ; protected c a## /o % ; pu$ ic /o %01 ; Sy#te!.out.print n0&+gg2./o %01&13 < pu$ ic *oid f01 ; Sy#te!.out.print n0&+gg2./o %.f01&13 < < pri*ate /o % y 9 ne. /o %013 pu$ ic +gg201 ; Sy#te!.out.print n0&Ce. +gg201&13 < pu$ ic *oid in#ert/o %0/o % yy1 ; y 9 yy3 < pu$ ic *oid g01 ; y.f013 < < pu$ ic c a## Big+gg2 extend# +gg2 ; pu$ ic c a## /o % extend# +gg2./o % ; pu$ ic /o %01 ; Sy#te!.out.print n0&Big+gg2./o %01&13 < pu$ ic *oid f01 ; Sy#te!.out.print n0&Big+gg2./o %.f01&13 < < pu$ ic Big+gg201 ; in#ert/o %0ne. /o %0113 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; +gg2 e2 9 ne. Big+gg2013 e2.g013

Cha"ter &* Inter$aces = Inner Classes

3#3

< < ///:8 *! Big&gg86@ol( e;plicitly extends &gg86@ol( and *verride# it# +eth*d#) The +eth*d insert@ol(( ) all*!# Big&gg8 t* upca#t *ne *9 it# *!n @ol( *34ect# int* the y re9erence in &gg8, #* !hen g( ) call# y6f( ) the *verridden ver#i*n *9 f( ) i# u#ed) The *utput i#1 +gg2./o %01 Ce. +gg201 +gg2./o %01 Big+gg2./o %01 Big+gg2./o %.f01 The #ec*nd call t* &gg86@ol(( ) i# the 3a#eEcla## c*n#truct*r call *9 the Big&gg86@ol( c*n#truct*r) :*u can #ee that the *verridden ver#i*n *9 f( ) i# u#ed !hen g( ) i# called)

Inner class identi0iers


Since every cla## pr*duce# a 6class 9ile that h*ld# all the in9*r+ati*n a3*ut h*! t* create *34ect# *9 thi# type Gthi# in9*r+ati*n pr*duce# a I+etaEcla##J called the Class *34ectH, y*u +ight gue## that inner cla##e# +u#t al#* pr*duce 6class 9ile# t* c*ntain the in9*r+ati*n 9*r their Class *34ect#) The na+e# *9 the#e 9ile#<cla##e# have a #trict 9*r+ula1 the na+e *9 the encl*#ing cla##, 9*ll*!ed 3y a T^, 9*ll*!ed 3y the na+e *9 the inner cla##) 5*r e;a+ple, the 6class 9ile# created 3y BnheritBnner6)ava include1 5nherit5nner.c a## Vith5nnerc5nner.c a## Vith5nner.c a## -9 inner cla##e# are an*ny+*u#, the c*+piler #i+ply #tart# generating nu+3er# a# inner cla## identi9ier#) -9 inner cla##e# are ne#ted !ithin inner cla##e#, their na+e# are #i+ply appended a9ter a T^ and the *uter cla## identi9ierG#H)

3#4

Thinking in C

www.ThinkingIn.!et

=lth*ugh thi# #che+e *9 generating internal na+e# i# #i+ple and #traight9*r!ard, it# al#* r*3u#t and handle# +*#t #ituati*n# ') Since it i# the #tandard na+ing #che+e 9*r "ava, the generated 9ile# are aut*+atically plat9*r+Eindependent) G *te that the "ava c*+piler i# changing y*ur inner cla##e# in all #*rt# *9 *ther !ay# in *rder t* +ake the+ !*rk)H

Wh5 inner classes<


=t thi# p*int y*uve #een a l*t *9 #ynta; and #e+antic# de#cri3ing the !ay inner cla##e# !*rk, 3ut thi# d*e#nt an#!er the Due#ti*n *9 !hy they e;i#t) ,hy did Sun g* t* #* +uch tr*u3le t* add thi# 9unda+ental language 9eatureF Typically, the inner cla## inherit# 9r*+ a cla## *r i+ple+ent# an interface, and the c*de in the inner cla## +anipulate# the *uter cla## *34ect that it !a# created !ithin) S* y*u c*uld #ay that an inner cla## pr*vide# a kind *9 !ind*! int* the *uter cla##) = Due#ti*n that cut# t* the heart *9 inner cla##e# i# thi#1 i9 - 4u#t need a re9erence t* an interface, !hy d*nt - 4u#t +ake the *uter cla## i+ple+ent that interfaceF The an#!er i# I-9 that# all y*u need, then that# h*! y*u #h*uld d* it)J S* !hat i# it that di#tingui#he# an inner cla## i+ple+enting an interface 9r*+ an *uter cla## i+ple+enting the #a+e interfaceF The an#!er i# that y*u cant al!ay# have the c*nvenience *9 interface#R#*+eti+e# y*ure !*rking !ith i+ple+entati*n#) S* the +*#t c*+pelling rea#*n 9*r inner cla##e# i#1 Each inner class can inde"endentl4 inherit $rom an im"lementation. Thus6 the inner class is not limited 24 whether the outer class is alread4 inheriting $rom an im"lementation. ,ith*ut the a3ility that inner cla##e# pr*vide t* inheritRin e99ectR9r*+ +*re than *ne c*ncrete *r abstract cla##, #*+e de#ign and pr*gra++ing pr*3le+# !*uld 3e intracta3le) S* *ne !ay t* l**k at the inner cla## i# a# the c*+pleti*n *9 the #*luti*n *9 the +ultipleEinheritance pr*3le+)
' On the *ther hand, TU i# a +etaEcharacter t* the Uni; #hell and #* y*ull #*+eti+e# have

tr*u3le !hen li#ting the 6class 9ile#) Thi# i# a 3it #trange c*+ing 9r*+ Sun, a Uni;E3a#ed c*+pany) Ay gue## i# that they !erent c*n#idering thi# i##ue, 3ut in#tead th*ught y*ud naturally 9*cu# *n the #*urceEc*de 9ile#)

Cha"ter &* Inter$aces = Inner Classes

3#5

-nter9ace# #*lve part *9 the pr*3le+, 3ut inner cla##e# e99ectively all*! I+ultiple i+ple+entati*n inheritance)J That i#, inner cla##e# e99ectively all*! y*u t* inherit 9r*+ +*re than *ne n*nE interface) T* #ee thi# in +*re detail, c*n#ider a #ituati*n !here y*u have t!* inter9ace# that +u#t #*+eh*! 3e i+ple+ented !ithin a cla##) Becau#e *9 the 9le;i3ility *9 inter9ace#, y*u have t!* ch*ice#1 a #ingle cla## *r an inner cla##1 //: c0I:Gu ti5nterface#.Da*a // '.o .ay# that a c a## can // i!p e!ent !u tip e interface#. interface ) ;< interface B ;< c a## , i!p e!ent# )2 B ;< c a## / i!p e!ent# ) ; B !a%eB01 ; // )nony!ou# inner c a##: return ne. B01 ;<3 < < pu$ ic c a## Gu ti5nterface# ; #tatic *oid ta%e#)0) a1 ;< #tatic *oid ta%e#B0B $1 ;< pu$ ic #tatic *oid !ain0StringJK arg#1 ; , x 9 ne. ,013 / y 9 ne. /013 ta%e#)0x13 ta%e#)0y13 ta%e#B0x13 ta%e#B0y.!a%eB0113 < < ///:8 O9 c*ur#e, thi# a##u+e# that the #tructure *9 y*ur c*de +ake# l*gical #en#e either !ay) H*!ever, y*ull *rdinarily have #*+e kind *9 guidance 9r*+ the nature *9 the pr*3le+ a3*ut !hether t* u#e a #ingle cla## *r an

3#6

Thinking in C

www.ThinkingIn.!et

inner cla##) But !ith*ut any *ther c*n#traint#, in the a3*ve e;a+ple the appr*ach y*u take d*e#nt really +ake +uch di99erence 9r*+ an i+ple+entati*n #tandp*int) B*th *9 the+ !*rk) H*!ever, i9 y*u have abstract *r c*ncrete cla##e# in#tead *9 interface#, y*u are #uddenly li+ited t* u#ing inner cla##e# i9 y*ur cla## +u#t #*+eh*! i+ple+ent 3*th *9 the *ther#1 //: c0I:Gu ti5!p e!entation.Da*a // Vith concrete or a$#tract c a##e#2 inner // c a##e# are the on y .ay to produce the effect // of &!u tip e i!p e!entation inheritance.& c a## C ;< a$#tract c a## : ;< c a## b extend# C ; : !a%e:01 ; return ne. :01 ;<3 < < pu$ ic c a## Gu ti5!p e!entation ; #tatic *oid ta%e#C0C c1 ;< #tatic *oid ta%e#:0: d1 ;< pu$ ic #tatic *oid !ain0StringJK arg#1 ; b M 9 ne. b013 ta%e#C0M13 ta%e#:0M.!a%e:0113 < < ///:8 -9 y*u didnt need t* #*lve the I+ultiple i+ple+entati*n inheritanceJ pr*3le+, y*u c*uld c*nceiva3ly c*de ar*und everything el#e !ith*ut the need 9*r inner cla##e#) But !ith inner cla##e# y*u have the#e additi*nal 9eature#1 1. The inner cla## can have +ultiple in#tance#, each !ith it# *!n #tate in9*r+ati*n that i# independent *9 the in9*r+ati*n in the *uter cla## *34ect)

Cha"ter &* Inter$aces = Inner Classes

3##

2.

-n a #ingle *uter cla## y*u can have #everal inner cla##e#, each *9 !hich i+ple+ent the #a+e interface *r inherit 9r*+ the #a+e cla## in a di99erent !ay) =n e;a+ple *9 thi# !ill 3e #h*!n #h*rtly) The p*int *9 creati*n *9 the inner cla## *34ect i# n*t tied t* the creati*n *9 the *uter cla## *34ect) There i# n* p*tentially c*n9u#ing Ii#EaJ relati*n#hip !ith the inner cla##Q it# a #eparate entity)

3. .

=# an e;a+ple, i9 #e%uence6)ava did n*t u#e inner cla##e#, y*ud have t* #ay Ia #e%uence i# a #elector,J and y*ud *nly 3e a3le t* have *ne #elector in e;i#tence 9*r a particular #e%uence) =l#*, y*u can have a #ec*nd +eth*d, get*#elector( ), that pr*duce# a #elector that +*ve# 3ack!ard thr*ugh the #eDuence) Thi# kind *9 9le;i3ility i# *nly availa3le !ith inner cla##e#)

Closures I Call+ac*s
= closure i# a calla3le *34ect that retain# in9*r+ati*n 9r*+ the #c*pe in !hich it !a# created) 5r*+ thi# de9initi*n, y*u can #ee that an inner cla## i# an *34ectE*riented cl*#ure, 3ecau#e it d*e#nt 4u#t c*ntain each piece *9 in9*r+ati*n 9r*+ the *uter cla## *34ect GIthe #c*pe in !hich it !a# createdJH, 3ut it aut*+atically h*ld# a re9erence 3ack t* the !h*le *uter cla## *34ect, !here it ha# per+i##i*n t* +anipulate all the +e+3er#, even private *ne#) One *9 the +*#t c*+pelling argu+ent# +ade t* include #*+e kind *9 p*inter +echani#+ in "ava !a# t* all*! call2acks) ,ith a call3ack, #*+e *ther *34ect i# given a piece *9 in9*r+ati*n that all*!# it t* call 3ack int* the *riginating *34ect at #*+e later p*int) Thi# i# a very p*!er9ul c*ncept, a# y*u !ill #ee in Chapter# 0/ and 0.) -9 a call3ack i# i+ple+ented u#ing a p*inter, h*!ever, y*u +u#t rely *n the pr*gra++er t* 3ehave and n*t +i#u#e the p*inter) =# y*uve #een 3y n*!, "ava tend# t* 3e +*re care9ul than that, #* p*inter# !ere n*t included in the language) The cl*#ure pr*vided 3y the inner cla## i# a per9ect #*luti*nQ +*re 9le;i3le and 9ar #a9er than a p*inter) Here# a #i+ple e;a+ple1 //: c0I:Ca $ac%#.Da*a // O#ing inner c a##e# for ca $ac%#

3#&

Thinking in C

www.ThinkingIn.!et

interface 5ncre!enta$ e ; *oid incre!ent013 < // Nery #i!p e to Du#t i!p e!ent the interface: c a## Ca ee" i!p e!ent# 5ncre!enta$ e ; pri*ate int i 9 03 pu$ ic *oid incre!ent01 ; iRR3 Sy#te!.out.print n0i13 < < c a## Gy5ncre!ent ; pu$ ic *oid incre!ent01 ; Sy#te!.out.print n0&Other operation&13 < pu$ ic #tatic *oid f0Gy5ncre!ent !i1 ; !i.incre!ent013 < < // 5f your c a## !u#t i!p e!ent incre!ent01 in // #o!e other .ay2 you !u#t u#e an inner c a##: c a## Ca ee2 extend# Gy5ncre!ent ; pri*ate int i 9 03 pri*ate *oid incr01 ; iRR3 Sy#te!.out.print n0i13 < pri*ate c a## C o#ure i!p e!ent# 5ncre!enta$ e ; pu$ ic *oid incre!ent01 ; incr013 < < 5ncre!enta$ e getCa $ac%Reference01 ; return ne. C o#ure013 < < c a## Ca er ; pri*ate 5ncre!enta$ e ca $ac%Reference3

Cha"ter &* Inter$aces = Inner Classes

3#'

Ca ca

er05ncre!enta$ e c$h1 ; $ac%Reference 9 c$h3

< *oid go01 ; ca $ac%Reference.incre!ent013 < < pu$ ic c a## Ca $ac%# ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; Ca ee" c" 9 ne. Ca ee"013 Ca ee2 c2 9 ne. Ca ee2013 Gy5ncre!ent.f0c213 Ca er ca er" 9 ne. Ca er0c"13 Ca er ca er2 9 ne. Ca er0c2.getCa $ac%Reference0113 ca er".go013 ca er".go013 ca er2.go013 ca er2.go013 < < ///:8 Thi# e;a+ple al#* pr*vide# a 9urther di#tincti*n 3et!een i+ple+enting an inter9ace in an *uter cla## v#) d*ing #* in an inner cla##) Callee7 i# clearly the #i+pler #*luti*n in ter+# *9 the c*de) Callee8 inherit# 9r*+ .yBncrement !hich already ha# a di99erent increment( ) +eth*d !hich d*e# #*+ething unrelated t* that !hich i# e;pected 3y the Bncrementable inter9ace) ,hen .yBncrement i# inherited int* Callee8, increment( ) cant 3e *verridden 9*r u#e 3y Bncrementable, #* y*ure 9*rced t* pr*vide a #eparate i+ple+entati*n u#ing an inner cla##) =l#* n*te that !hen y*u create an inner cla## y*u d* n*t add t* *r +*di9y the inter9ace *9 the *uter cla##) *tice that everything e;cept getCallbac(*eference( ) in Callee8 i# private) T* all*! an4 c*nnecti*n t* the *ut#ide !*rld, the interface Bncrementable i# e##ential) Here y*u can #ee h*! interface# all*! 9*r a c*+plete #eparati*n *9 inter9ace 9r*+ i+ple+entati*n) The inner cla## Closure #i+ply i+ple+ent# Bncrementable t* pr*vide a h**k 3ack int* Callee8R3ut a #a9e h**k) ,h*ever get# the

3&(

Thinking in C

www.ThinkingIn.!et

Bncrementable re9erence can, *9 c*ur#e, *nly call increment( ) and ha# n* *ther a3ilitie# Gunlike a p*inter, !hich !*uld all*! y*u t* run !ildH) Caller take# an Bncrementable re9erence in it# c*n#truct*r Galth*ugh the capturing *9 the call3ack re9erence c*uld happen at any ti+eH and then, #*+eti+e latter, u#e# the re9erence t* Icall 3ackJ int* the Callee cla##) The value *9 the call3ack i# in it# 9le;i3ilityRy*u can dyna+ically decide !hat 9uncti*n# !ill 3e called at runEti+e) The 3ene9it *9 thi# !ill 3ec*+e +*re evident in Chapter 0/, !here call3ack# are u#ed every!here t* i+ple+ent graphical u#er inter9ace G>U-H 9uncti*nality)

Inner classes I control 0ra#ewor*s


= +*re c*ncrete e;a+ple *9 the u#e *9 inner cla##e# can 3e 9*und in #*+ething that - !ill re9er t* here a# a control $ramework) =n a""lication $ramework i# a cla## *r a #et *9 cla##e# that# de#igned t* #*lve a particular type *9 pr*3le+) T* apply an applicati*n 9ra+e!*rk, y*u inherit 9r*+ *ne *r +*re cla##e# and *verride #*+e *9 the +eth*d#) The c*de y*u !rite in the *verridden +eth*d# cu#t*+i7e# the general #*luti*n pr*vided 3y that applicati*n 9ra+e!*rk, in *rder t* #*lve y*ur #peci9ic pr*3le+) The c*ntr*l 9ra+e!*rk i# a particular type *9 applicati*n 9ra+e!*rk d*+inated 3y the need t* re#p*nd t* event#Q a #y#te+ that pri+arily re#p*nd# t* event# i# called an e-ent9dri-en s4stem) One *9 the +*#t i+p*rtant pr*3le+# in applicati*n pr*gra++ing i# the graphical u#er inter9ace G>U-H, !hich i# al+*#t entirely eventEdriven) =# y*u !ill #ee in Chapter 0/, the "ava S!ing li3rary i# a c*ntr*l 9ra+e!*rk that elegantly #*lve# the >U- pr*3le+ and that heavily u#e# inner cla##e#) T* #ee h*! inner cla##e# all*! the #i+ple creati*n and u#e *9 c*ntr*l 9ra+e!*rk#, c*n#ider a c*ntr*l 9ra+e!*rk !h*#e 4*3 i# t* e;ecute event# !henever th*#e event# are Iready)J =lth*ugh IreadyJ c*uld +ean anything, in thi# ca#e the de9ault !ill 3e 3a#ed *n cl*ck ti+e) ,hat 9*ll*!# i# a c*ntr*l 9ra+e!*rk that c*ntain# n* #peci9ic in9*r+ati*n a3*ut !hat it# c*ntr*lling) 5ir#t, here i# the inter9ace that de#cri3e# any c*ntr*l event) -t# an abstract cla## in#tead *9 an actual interface 3ecau#e the de9ault

Cha"ter &* Inter$aces = Inner Classes

3&1

3ehavi*r i# t* per9*r+ the c*ntr*l 3a#ed *n ti+e, #* #*+e *9 the i+ple+entati*n can 3e included here1 //: c0I:contro er:+*ent.Da*a // 'he co!!on !ethod# for any contro pac%age c0I.contro er3 e*ent.

a$#tract pu$ ic c a## +*ent ; pri*ate ong e*t'i!e3 pu$ ic +*ent0 ong e*ent'i!e1 ; e*t'i!e 9 e*ent'i!e3 < pu$ ic $oo ean ready01 ; return Sy#te!.current'i!eGi i#01 Z9 e*t'i!e3 < a$#tract pu$ ic *oid action013 a$#tract pu$ ic String de#cription013 < ///:8 The c*n#truct*r #i+ply capture# the ti+e !hen y*u !ant the &vent t* run, !hile ready( ) tell# y*u !hen it# ti+e t* run it) O9 c*ur#e, ready( ) c*uld 3e *verridden in a derived cla## t* 3a#e the &vent *n #*+ething *ther than ti+e) action( ) i# the +eth*d that# called !hen the &vent i# ready( ), and description( ) give# te;tual in9*r+ati*n a3*ut the &vent) The 9*ll*!ing 9ile c*ntain# the actual c*ntr*l 9ra+e!*rk that +anage# and 9ire# event#) The 9ir#t cla## i# really 4u#t a IhelperJ cla## !h*#e 4*3 i# t* h*ld &vent *34ect#) :*u can replace it !ith any appr*priate c*ntainer, and in Chapter 6 y*ull di#c*ver *ther c*ntainer# that !ill d* the trick !ith*ut reDuiring y*u t* !rite thi# e;tra c*de1 //: c0I:contro er:Contro er.Da*a // ) ong .ith +*ent2 the generic // fra!e.or% for a contro #y#te!#: pac%age c0I.contro er3 // 'hi# i# Du#t a .ay to ho d +*ent o$Dect#. c a## +*entSet ; pri*ate +*entJK e*ent# 9 ne. +*entJ"00K3 pri*ate int index 9 03

3&)

Thinking in C

www.ThinkingIn.!et

pri*ate int next 9 03 pu$ ic *oid add0+*ent e1 ; if0index Z9 e*ent#. ength1 return3 // 05n rea ife2 thro. exception1 e*ent#JindexRRK 9 e3 < pu$ ic +*ent getCext01 ; $oo ean ooped 9 fa #e3 int #tart 9 next3 do ; next 9 0next R "1 [ e*ent#. ength3 // See if it ha# ooped to the $eginning: if0#tart 99 next1 ooped 9 true3 // 5f it oop# pa#t #tart2 the i#t // i# e!pty: if00next 99 0#tart R "1 [ e*ent#. ength1 @@ ooped1 return nu 3 < .hi e0e*ent#JnextK 99 nu 13 return e*ent#JnextK3 < pu$ ic *oid re!o*eCurrent01 ; e*ent#JnextK 9 nu 3 < < pu$ ic c a## Contro er ; pri*ate +*entSet e# 9 ne. +*entSet013 pu$ ic *oid add+*ent0+*ent c1 ; e#.add0c13 < pu$ ic *oid run01 ; +*ent e3 .hi e00e 9 e#.getCext011 !9 nu 1 ; if0e.ready011 ; e.action013 Sy#te!.out.print n0e.de#cription0113 e#.re!o*eCurrent013 < < < < ///:8

Cha"ter &* Inter$aces = Inner Classes

3&3

&vent#et ar3itrarily h*ld# 0$$ &vent#) G-9 a IrealJ c*ntainer 9r*+ Chapter 6 i# u#ed here y*u d*nt need t* !*rry a3*ut it# +a;i+u+ #i7e, #ince it !ill re#i7e it#el9H) The index i# u#ed t* keep track *9 the ne;t availa3le #pace, and next i# u#ed !hen y*ure l**king 9*r the ne;t &vent in the li#t, t* #ee !hether y*uve l**ped ar*und) Thi# i# i+p*rtant during a call t* get,ext( ), 3ecau#e &vent *34ect# are re+*ved 9r*+ the li#t Gu#ing removeCurrent( )H *nce theyre run, #* get,ext( ) !ill enc*unter h*le# in the li#t a# it +*ve# thr*ugh it) *te that removeCurrent( ) d*e#nt 4u#t #et #*+e 9lag indicating that the *34ect i# n* l*nger in u#e) -n#tead, it #et# the re9erence t* null) Thi# i# i+p*rtant 3ecau#e i9 the gar3age c*llect*r #ee# a re9erence that# #till in u#e then it cant clean up the *34ect) -9 y*u think y*ur re9erence# +ight hang ar*und Ga# they !*uld hereH, then it# a g**d idea t* #et the+ t* null t* give the gar3age c*llect*r per+i##i*n t* clean the+ up) Controller i# !here the actual !*rk g*e# *n) -t u#e# an &vent#et t* h*ld it# &vent *34ect#, and add&vent( ) all*!# y*u t* add ne! event# t* thi# li#t) But the i+p*rtant +eth*d i# run( )) Thi# +eth*d l**p# thr*ugh the &vent#et, hunting 9*r an &vent *34ect that# ready( ) t* run) 5*r each *ne it 9ind# ready( ), it call# the action( ) +eth*d, print# *ut the description( ), and then re+*ve# the &vent 9r*+ the li#t) *te that #* 9ar in thi# de#ign y*u kn*! n*thing a3*ut e;actly what an &vent d*e#) =nd thi# i# the cru; *9 the de#ignQ h*! it I#eparate# the thing# that change 9r*+ the thing# that #tay the #a+e)J Or, t* u#e +y ter+, the Ivect*r *9 changeJ i# the di99erent acti*n# *9 the vari*u# kind# *9 &vent *34ect#, and y*u e;pre## di99erent acti*n# 3y creating di99erent &vent #u3cla##e# Gin Cesign /atterns parlance, the &vent #u3cla##e# repre#ent the Command /atternH) Thi# i# !here inner cla##e# c*+e int* play) They all*! t!* thing#1 1. T* create the entire i+ple+entati*n *9 a c*ntr*lE9ra+e!*rk applicati*n in a #ingle cla##, there3y encap#ulating everything that# uniDue a3*ut that i+ple+entati*n) -nner cla##e# are u#ed t* e;pre## the +any di99erent kind# *9 action( ) nece##ary t* #*lve the pr*3le+) -n additi*n, the 9*ll*!ing e;a+ple u#e# private inner cla##e# #* the i+ple+entati*n i# c*+pletely hidden and can 3e changed !ith i+punity)

3&4

Thinking in C

www.ThinkingIn.!et

2.

-nner cla##e# keep thi# i+ple+entati*n 9r*+ 3ec*+ing a!k!ard, #ince y*ure a3le t* ea#ily acce## any *9 the +e+3er# in the *uter cla##) ,ith*ut thi# a3ility the c*de +ight 3ec*+e unplea#ant en*ugh that y*ud end up #eeking an alternative)

C*n#ider a particular i+ple+entati*n *9 the c*ntr*l 9ra+e!*rk de#igned t* c*ntr*l greenh*u#e 9uncti*n#.) Each acti*n i# entirely di99erent1 turning light#, !ater, and ther+*#tat# *n and *99, ringing 3ell#, and re#tarting the #y#te+) But the c*ntr*l 9ra+e!*rk i# de#igned t* ea#ily i#*late thi# di99erent c*de) -nner cla##e# all*! y*u t* have +ultiple derived ver#i*n# *9 the #a+e 3a#e cla##, &vent, !ithin a #ingle cla##) 5*r each type *9 acti*n y*u inherit a ne! &vent inner cla##, and !rite the c*ntr*l c*de in#ide *9 action( )) =# i# typical !ith an applicati*n 9ra+e!*rk, the cla## reenhouseControls i# inherited 9r*+ Controller1 //: c0I:_reenhou#eContro #.Da*a // 'hi# produce# a #pecific app ication of the // contro #y#te!2 a in a #ing e c a##. 5nner // c a##e# a o. you to encap#u ate different // functiona ity for each type of e*ent. i!port c0I.contro er.=3 pu$ ic c a## _reenhou#eContro # extend# Contro er ; pri*ate $oo ean ight 9 fa #e3 pri*ate $oo ean .ater 9 fa #e3 pri*ate String ther!o#tat 9 &:ay&3 pri*ate c a## LightOn extend# +*ent ; pu$ ic LightOn0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // -ut hard.are contro code here to // phy#ica y turn on the ight. ight 9 true3 < pu$ ic String de#cription01 ;
. 5*r #*+e rea#*n thi# ha# al!ay# 3een a plea#ing pr*3le+ 9*r +e t* #*lveQ it ca+e 9r*+

+y earlier 3**k C++ Inside = 1ut, 3ut "ava all*!# a +uch +*re elegant #*luti*n)

Cha"ter &* Inter$aces = Inner Classes

3&5

return &Light i# on&3 < < pri*ate c a## LightOff extend# +*ent ; pu$ ic LightOff0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // -ut hard.are contro code here to // phy#ica y turn off the ight. ight 9 fa #e3 < pu$ ic String de#cription01 ; return &Light i# off&3 < < pri*ate c a## VaterOn extend# +*ent ; pu$ ic VaterOn0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // -ut hard.are contro code here .ater 9 true3 < pu$ ic String de#cription01 ; return &_reenhou#e .ater i# on&3 < < pri*ate c a## VaterOff extend# +*ent ; pu$ ic VaterOff0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // -ut hard.are contro code here .ater 9 fa #e3 < pu$ ic String de#cription01 ; return &_reenhou#e .ater i# off&3 < < pri*ate c a## 'her!o#tatCight extend# +*ent ;

3&6

Thinking in C

www.ThinkingIn.!et

pu$ ic 'her!o#tatCight0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // -ut hard.are contro code here ther!o#tat 9 &Cight&3 < pu$ ic String de#cription01 ; return &'her!o#tat on night #etting&3 < < pri*ate c a## 'her!o#tat:ay extend# +*ent ; pu$ ic 'her!o#tat:ay0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // -ut hard.are contro code here ther!o#tat 9 &:ay&3 < pu$ ic String de#cription01 ; return &'her!o#tat on day #etting&3 < < // )n exa!p e of an action01 that in#ert# a // ne. one of it#e f into the e*ent i#t: pri*ate int ring#3 pri*ate c a## Be extend# +*ent ; pu$ ic Be 0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; // Ring e*ery 2 #econd#2 'ring#' ti!e#: Sy#te!.out.print n0&Bing!&13 if066ring# Z 01 add+*ent0ne. Be 0 Sy#te!.current'i!eGi i#01 R 2000113 < pu$ ic String de#cription01 ; return &Ring $e &3 < <

Cha"ter &* Inter$aces = Inner Classes

3&#

pri*ate c a## Re#tart extend# +*ent ; pu$ ic Re#tart0 ong e*ent'i!e1 ; #uper0e*ent'i!e13 < pu$ ic *oid action01 ; ong t! 9 Sy#te!.current'i!eGi i#013 // 5n#tead of hard6.iring2 you cou d par#e // configuration infor!ation fro! a text // fi e here: ring# 9 P3 add+*ent0ne. 'her!o#tatCight0t!113 add+*ent0ne. LightOn0t! R "000113 add+*ent0ne. LightOff0t! R 2000113 add+*ent0ne. VaterOn0t! R T000113 add+*ent0ne. VaterOff0t! R I000113 add+*ent0ne. Be 0t! R >000113 add+*ent0ne. 'her!o#tat:ay0t! R "0000113 // Can e*en add a Re#tart o$Dect! add+*ent0ne. Re#tart0t! R 20000113 < pu$ ic String de#cription01 ; return &Re#tarting #y#te!&3 < < pu$ ic #tatic *oid !ain0StringJK arg#1 ; _reenhou#eContro # gc 9 ne. _reenhou#eContro #013 ong t! 9 Sy#te!.current'i!eGi i#013 gc.add+*ent0gc.ne. Re#tart0t!113 gc.run013 < < ///:8 *te that light, water, thermostat, and rings all 3el*ng t* the *uter cla## reenhouseControls, and yet the inner cla##e# can acce## th*#e 9ield# !ith*ut Duali9icati*n *r #pecial per+i##i*n) =l#*, +*#t *9 the action( ) +eth*d# inv*lve #*+e #*rt *9 hard!are c*ntr*l, !hich !*uld +*#t likely inv*lve call# t* n*nE"ava c*de) A*#t *9 the &vent cla##e# l**k #i+ilar, 3ut Bell and *estart are #pecial) Bell ring#, and i9 it ha#nt yet rung en*ugh ti+e# it add# a ne! Bell *34ect

3&&

Thinking in C

www.ThinkingIn.!et

t* the event li#t, #* it !ill ring again later) *tice h*! inner cla##e# almost l**k like +ultiple inheritance1 Bell ha# all the +eth*d# *9 &vent and it al#* appear# t* have all the +eth*d# *9 the *uter cla## reenhouseControls) *estart i# re#p*n#i3le 9*r initiali7ing the #y#te+, #* it add# all the appr*priate event#) O9 c*ur#e, a +*re 9le;i3le !ay t* acc*+pli#h thi# i# t* av*id hardEc*ding the event# and in#tead read the+ 9r*+ a 9ile) G=n e;erci#e in Chapter 00 a#k# y*u t* +*di9y thi# e;a+ple t* d* 4u#t that)H Since *estart( ) i# 4u#t an*ther &vent *34ect, y*u can al#* add a *estart *34ect !ithin *estart6action( ) #* that the #y#te+ regularly re#tart# it#el9) =nd all y*u need t* d* in main( ) i# create a reenhouseControls *34ect and add a *estart *34ect t* get it g*ing) 'hi# exa!p e #hou d !o*e you a ong .ay to.ard appreciating the *a ue of inner c a##e#2 e#pecia y .hen u#ed .ithin a contro fra!e.or%. Uo.e*er2 in Chapter "T you4 #ee ho. e egant y inner c a##e# are u#ed to de#cri$e the action# of a graphica u#er interface. By the ti!e you fini#h that chapter you #hou d $e fu y con*inced.

'u##ar5
-nter9ace# and inner cla##e# are +*re #*phi#ticated c*ncept# than !hat y*ull 9ind in +any OOP language#) 5*r e;a+ple, there# n*thing like the+ in C@@) T*gether, they #*lve the #a+e pr*3le+ that C@@ atte+pt# t* #*lve !ith it# +ultiple inheritance GA-H 9eature) H*!ever, A- in C@@ turn# *ut t* 3e rather di99icult t* u#e, !hile "ava inter9ace# and inner cla##e# are, 3y c*+pari#*n, +uch +*re acce##i3le) =lth*ugh the 9eature# the+#elve# are rea#*na3ly #traight9*r!ard, the u#e *9 the#e 9eature# i# a de#ign i##ue, +uch the #a+e a# p*ly+*rphi#+) Over ti+e, y*ull 3ec*+e 3etter at rec*gni7ing #ituati*n# !here y*u #h*uld u#e an inter9ace, *r an inner cla##, *r 3*th) But at thi# p*int in thi# 3**k y*u #h*uld at lea#t 3e c*+9*rta3le !ith the #ynta; and #e+antic#) =# y*u #ee the#e language 9eature# in u#e y*ull eventually internali7e the+)

Cha"ter &* Inter$aces = Inner Classes

3&'

%&ercises
S*luti*n# t* #elected e;erci#e# can 3e 9*und in the electr*nic d*cu+ent The Thinking in ,a-a 5nnotated @olution Duide, availa3le 9*r a #+all 9ee 9r*+ www.BruceEckel.com)

1. 2. 3. .

Pr*ve that the 9ield# in an interface are i+plicitly static and final) Create an interface c*ntaining three +eth*d#, in it# *!n pac(age) -+ple+ent the inter9ace in a di99erent pac(age) Pr*ve that all the +eth*d# in an interface are aut*+atically public) -n c4SD#andwich6)ava, create an inter9ace called :ast:ood G!ith appr*priate +eth*d#H and change #andwich #* that it al#* i+ple+ent# :ast:ood) Create three interface#, each !ith t!* +eth*d#) -nherit a ne! interface 9r*+ the three, adding a ne! +eth*d) Create a cla## 3y i+ple+enting the ne! interface and al#* inheriting 9r*+ a c*ncrete cla##) *! !rite 9*ur +eth*d#, each *9 !hich take# *ne *9 the 9*ur interface# a# an argu+ent) -n main( ), create an *34ect *9 y*ur cla## and pa## it t* each *9 the +eth*d#) A*di9y E;erci#e ' 3y creating an abstract cla## and inheriting that int* the derived cla##) A*di9y .usicY6)ava 3y adding a !layable interface) A*ve the play( ) declarati*n 9r*+ Bnstrument t* !layable) =dd !layable t* the derived cla##e# 3y including it in the implements li#t) Change tune( ) #* that it take# a !layable in#tead *9 an Bnstrument) Change E;erci#e . in Chapter % #* that *odent i# an interface) -n 'dventure6)ava, add an interface called CanClimb, 9*ll*!ing the 9*r+ *9 the *ther inter9ace#) ,rite a pr*gra+ that i+p*rt# and u#e# .onth86)ava)

!.

". C.

D. E. 1F.

3'(

Thinking in C

www.ThinkingIn.!et

11. 12.

5*ll*!ing the e;a+ple given in .onth86)ava, create an enu+erati*n *9 day# *9 the !eek) Create an interface !ith at lea#t *ne +eth*d, in it# *!n package) Create a cla## in a #eparate package) =dd a protected inner cla## that i+ple+ent# the interface) -n a third package, inherit 9r*+ y*ur cla## and, in#ide a +eth*d, return an *34ect *9 the protected inner cla##, upca#ting t* the interface during the return) Create an interface !ith at lea#t *ne +eth*d, and i+ple+ent that interface 3y de9ining an inner cla## !ithin a +eth*d, !hich return# a re9erence t* y*ur interface) Repeat E;erci#e 0/ 3ut de9ine the inner cla## !ithin a #c*pe !ithin a +eth*d) Repeat E;erci#e 0/ u#ing an an*ny+*u# inner cla##) Create a private inner cla## that i+ple+ent# a public interface) ,rite a +eth*d that return# a re9erence t* an in#tance *9 the private inner cla##, upca#t t* the interface) Sh*! that the inner cla## i# c*+pletely hidden 3y trying t* d*!nca#t t* it) Create a cla## !ith a n*nde9ault c*n#truct*r and n* de9ault c*n#truct*r) Create a #ec*nd cla## that ha# a +eth*d !hich return# a re9erence t* the 9ir#t cla##) Create the *34ect t* return 3y +aking an an*ny+*u# inner cla## that inherit# 9r*+ the 9ir#t cla##) Create a cla## !ith a private 9ield and a private +eth*d) Create an inner cla## !ith a +eth*d that +*di9ie# the *uter cla## 9ield and call# the *uter cla## +eth*d) -n a #ec*nd *uter cla## +eth*d, create an *34ect *9 the inner cla## and call it# +eth*d, then #h*! the e99ect *n the *uter cla## *34ect) Repeat E;erci#e 0( u#ing an an*ny+*u# inner cla##) Create a cla## c*ntaining a static inner cla##) -n main( ), create an in#tance *9 the inner cla##) Create an interface c*ntaining a static inner cla##) -+ple+ent thi# interface and create an in#tance *9 the inner cla##)

13.

1 . 1!. 1".

1C.

1D.

1E. 2F. 21.

Cha"ter &* Inter$aces = Inner Classes

3'1

22.

Create a cla## c*ntaining an inner cla## that it#el9 c*ntain# an inner cla##) Repeat thi# u#ing static inner cla##e#) *te the na+e# *9 the 6class 9ile# pr*duced 3y the c*+piler) Create a cla## !ith an inner cla##) -n a #eparate cla##, +ake an in#tance *9 the inner cla##) Create a cla## !ith an inner cla## that ha# a n*nde9ault c*n#truct*r) Create a #ec*nd cla## !ith an inner cla## that inherit# 9r*+ the 9ir#t inner cla##) Repair the pr*3le+ in =ind&rror6)ava) A*di9y #e%uence6)ava 3y adding a +eth*d get*#elector( ) that pr*duce# a di99erent i+ple+entati*n *9 the #elector interface that +*ve# 3ack!ard thr*ugh the #eDuence 9r*+ the end t* the 3eginning) Create an interface V !ith three +eth*d#) Create a cla## ' !ith a +eth*d that pr*duce# a re9erence t* a V 3y 3uilding an an*ny+*u# inner cla##) Create a #ec*nd cla## B that c*ntain# an array *9 V) B #h*uld have *ne +eth*d that accept# and #t*re# a re9erence t* a V in the array, a #ec*nd +eth*d that #et# a re9erence in the array G#peci9ied 3y the +eth*d argu+entH t* null and a third +eth*d that +*ve# thr*ugh the array and call# the +eth*d# in V) -n main( ), create a gr*up *9 ' *34ect# and a #ingle B) 5ill the B !ith V re9erence# pr*duced 3y the ' *34ect#) U#e the B t* call 3ack int* all the ' *34ect#) Re+*ve #*+e *9 the V re9erence# 9r*+ the B) -n reenhouseControls6)ava, add &vent inner cla##e# that turn 9an# *n and *99) Sh*! that an inner cla## ha# acce## t* the private ele+ent# *9 it# *uter cla##) ?eter+ine !hether the rever#e i# true)

23. 2 .

2!. 2".

2C.

2D. 2E.

3')

Thinking in C

www.ThinkingIn.!et

E, Collecting Bour O+/ects


-t# a 9airly #i+ple pr*gra+ that ha# *nly a 9i;ed Duantity *9 *34ect# !ith kn*!n li9eti+e#)
-n general, y*ur pr*gra+# !ill al!ay# 3e creating ne! *34ect# 3a#ed *n #*+e criteria that !ill 3e kn*!n *nly at the ti+e the pr*gra+ i# running) :*u !*nt kn*! until runEti+e the Duantity *r even the e;act type *9 the *34ect# y*u need) T* #*lve the general pr*gra++ing pr*3le+, y*u need t* 3e a3le t* create any nu+3er *9 *34ect#, anyti+e, any!here) S* y*u cant rely *n creating a na+ed re9erence t* h*ld each *ne *9 y*ur *34ect#1 GyO$Dect !yReference3 #ince y*ull never kn*! h*! +any *9 the#e y*ull actually need) T* #*lve thi# rather e##ential pr*3le+, C# ha# #everal !ay# t* h*ld *34ect# G*r rather, re9erence# t* *34ect#H) The 3uiltEin type i# the array, !hich ha# 3een di#cu##ed 3e9*re) =l#*, the C# Sy#te+)C*llecti*n# na+e#pace ha# a rea#*na3ly c*+plete #et *9 container classes Gal#* kn*!n a# collection

3'3

classesH) C*ntainer# pr*vide #*phi#ticated !ay# t* h*ld and +anipulate y*ur *34ect#) C*ntainer# *pen the d**r t* the !*rld *9 c*+puting !ith data #tructure#, !here a+a7ing re#ult# can 3e achieved 3y +anipulating the a3#tract ge*+etry *9 tree#, vect*r #pace#, and hyperplane#) ,hile data #tructure pr*gra++ing lie# *ut#ide *9 the !*rkaday !*rld *9 +*#t pr*gra++er#, it i# very i+p*rtant in #cienti9ic, graphic, and ga+e pr*gra++ing)

)rra5s
A*#t *9 the nece##ary intr*ducti*n t* array# !a# c*vered in Chapter #initiali7ati*n and cleanup#, !hich #h*!ed h*! y*u de9ine and initiali7e an array) H*lding *34ect# i# the 9*cu# *9 thi# chapter, and an array i# 4u#t *ne !ay t* h*ld *34ect#) But there are a nu+3er *9 *ther !ay# t* h*ld *34ect#, #* !hat +ake# an array #pecialF There are t!* i##ue# that di#tingui#h array# 9r*+ *ther type# *9 c*ntainer#1 e99iciency and type) The array i# the +*#t e99icient !ay that C# pr*vide# t* #t*re and rand*+ly acce## a #eDuence *9 *34ect# Gactually, *34ect re9erence#H) The array i# a #i+ple linear #eDuence, !hich +ake# ele+ent acce## 9a#t, 3ut y*u pay 9*r thi# #peed1 !hen y*u create an array *34ect, it# #i7e i# 9i;ed and cann*t 3e changed 9*r the li9eti+e *9 that array *34ect) :*u +ight #ugge#t creating an array *9 a particular #i7e and then, i9 y*u run *ut *9 #pace, creating a ne! *ne and +*ving all the re9erence# 9r*+ the *ld *ne t* the ne! *ne) Thi# i# the 3ehavi*r *9 the 'rrayList

3'4

cla##, !hich !ill 3e #tudied later in thi# chapter) H*!ever, 3ecau#e *9 the *verhead *9 thi# #i7e 9le;i3ility, an 'rrayList i# +ea#ura3ly le## e99icient than an array) The vector c*ntainer cla## in C@@ does kn*! the type *9 *34ect# it h*ld#, 3ut it ha# a di99erent dra!3ack !hen c*+pared !ith array# in C#1 the C@@ vector# operator<> d*e#nt d* 3*und# checking, #* y*u can run pa#t the end0) -n C#, y*u get 3*und# checking regardle## *9 !hether y*ure u#ing an array *r a c*ntainerRy*ull get an Bndex1ut1f*ange&xception i9 y*u e;ceed the 3*und#) =# y*ull learn in Chapter #E;cepti*n##, thi# type *9 e;cepti*n indicate# a pr*gra++er err*r, and thu# y*u d*nt need t* check 9*r it in y*ur c*de) =# an a#ide, the rea#*n the C@@ vector d*e#nt check 3*und# !ith every acce## i# #peedRin C# y*u have the per9*r+ance *verhead *9 3*und# checking all the ti+e 9*r 3*th array# and c*ntainer#) The *ther generic c*ntainer cla##e# that !ill 3e #tudied in thi# chapter, BCollection3 BList and B$ictionary, all deal !ith *34ect# a# i9 they had n* #peci9ic type) That i#, they treat the+ a# type ob)ect, the r**t cla## *9 all cla##e# in C#) Thi# !*rk# 9ine 9r*+ *ne #tandp*int1 y*u need t* 3uild *nly *ne c*ntainer, and any C# *34ect !ill g* int* that c*ntainer) Thi# i# the #ec*nd place !here an array i# #uperi*r t* the generic c*ntainer#1 !hen y*u create an array, y*u create it t* h*ld a #peci9ic type) Thi# +ean# that y*u get c*+pileEti+e type checking t* prevent y*u 9r*+ putting the !r*ng type in, *r +i#taking the type that y*ure e;tracting) O9 c*ur#e, C# !ill prevent y*u 9r*+ #ending an inappr*priate +e##age t* an *34ect, either at c*+pileEti+e *r at runEti+e) S* it# n*t +uch ri#kier *ne !ay *r the *ther, it# 4u#t nicer i9 the c*+piler p*int# it *ut t* y*u, 9a#ter at runE ti+e, and there# le## likelih**d that the end u#er !ill get #urpri#ed 3y an e;cepti*n) Typed generic cla##e# G#*+eti+e# called Ipara+eteri7ed type#J and #*+eti+e# 4u#t Igeneric#JH are n*t part *9 the initial ) ET 9ra+e!*rk 3ut !ill 3e) Unlike C@@# te+plate# *r "ava# pr*p*#ed e;ten#i*n#, Aicr*#*9t !i#he# t* i+ple+ent #upp*rt 9*r Ipara+etric p*ly+*rphi#+J !ithin the C*++*n Language Runti+e it#el9) ?*n Sy+e and =ndre! Nennedy *9 Aicr*#*9t# Ca+3ridge GEnglandH Re#earch La3 pu3li#hed paper# in
0 -t# p*##i3le, h*!ever, t* a#k h*! 3ig the vector i#, and the at( ) +eth*d does per9*r+

3*und# checking)

Cha"ter '* >olding Eour 123ects

3'5

Spring 2$$0 *n a pr*p*#ed #trategy and =nder# H4el#3erg hinted at C## Spring 2$$2 launch that i+ple+entati*n !a# !ell under !ay) 5*r the +*+ent, th*ugh, e99iciency and type checking #ugge#t u#ing an array i9 y*u can) H*!ever, !hen y*ure trying t* #*lve a +*re general pr*3le+ array# can 3e t** re#trictive) =9ter l**king at array#, the re#t *9 thi# chapter !ill 3e dev*ted t* the c*ntainer cla##e# pr*vided 3y C#)

)rra5s are 0irst;class o+/ects


Regardle## *9 !hat type *9 array y*ure !*rking !ith, the array identi9ier i# actually a re9erence t* a true *34ect that# created *n the heap) Thi# i# the *34ect that h*ld# the re9erence# t* the *ther *34ect#, and it can 3e created either i+plicitly, a# part *9 the array initiali7ati*n #ynta;, *r e;plicitly !ith a new e;pre##i*n) Part *9 the array *34ect i# the readE*nly Length pr*perty that tell# y*u h*! +any ele+ent# can 3e #t*red in that array *34ect) 5*r rectangular array#, the Length pr*perty tell# y*u the t*tal #i7e *9 the array, the *an( pr*perty tell# y*u the nu+3er *9 di+en#i*n# in the array, and the etLength(int) +eth*d !ill tell y*u h*! +any ele+ent# are in the given rank) The 9*ll*!ing e;a+ple #h*!# the vari*u# !ay# that an array can 3e initiali7ed, and h*! the array re9erence# can 3e a##igned t* di99erent array *34ect#) -t al#* #h*!# that array# *9 *34ect# and array# *9 pri+itive# are al+*#t identical in their u#e) The *nly di99erence i# that array# *9 *34ect# h*ld re9erence#, !hile array# *9 pri+itive# h*ld the pri+itive value# directly) //:c0>:)rraySiMe.c# // 5nitia iMation @ re6a##ign!ent of array#. c a## Vee$ e ;< // ) #!a !ythica creature

pu$ ic c a## )rraySiMe ; pu$ ic #tatic *oid Gain01 ; // )rray# of o$Dect#: Vee$ eJK a3 // Cu reference Vee$ eJK $ 9 ne. Vee$ eJPK3 // Cu reference# Vee$ eJ2K c 9 ne. Vee$ eJ22 TK3 //Rectangu ar array

3'6

Thinking in C

www.ThinkingIn.!et

Vee$ eJK d 9 ne. Vee$ eJEK3 for0int index 9 03 index W d.Length3 indexRR1 dJindexK 9 ne. Vee$ e013 // )ggregate initia iMation: Vee$ eJK e 9 ; ne. Vee$ e012 ne. Vee$ e012 ne. Vee$ e01 <3 // :yna!ic aggregate initia iMation: a 9 ne. Vee$ eJK ; ne. Vee$ e012 ne. Vee$ e01 <3 // S7uare dyna!ic aggregate initia iMation: c 9 ne. Vee$ eJ2K ; ; ne. Vee$ e012 ne. Vee$ e012 ne. Vee$ e01 <2 ; ne. Vee$ e012 ne. Vee$ e012 ne. Vee$ e01 < <3 Sy#te!.Con#o e.VriteLine0&a.Length9& R a.Length13 Sy#te!.Con#o e.VriteLine0&$.Length 9 & R $.Length13 Sy#te!.Con#o e.VriteLine0&c.Length 9 & R c.Length13 for0int ran% 9 03 ran% W c.Ran%3 ran%RR1; Sy#te!.Con#o e.VriteLine0 &c.LengthJ;0<K 9 ;"<&2 ran%2 c._etLength0ran%113 < // 'he reference# in#ide the array are // auto!atica y initia iMed to nu : for0int index 9 03 index W $.Length3 indexRR1 Sy#te!.Con#o e.VriteLine0&$J& R index R &K9& R $JindexK13 Sy#te!.Con#o e.VriteLine0&d.Length 9 & R d.Length13 Sy#te!.Con#o e.VriteLine0&d.Length 9 & R d.Length13 a 9 d3 Sy#te!.Con#o e.VriteLine0&a.Length 9 & R a.Length13 // )rray# of pri!iti*e#:

Cha"ter '* >olding Eour 123ects

3'#

intJK f3 // Cu reference intJK g 9 ne. intJPK3 intJK h 9 ne. intJEK3 for0int index 9 03 index W h.Length3 indexRR1 hJindexK 9 index=index3 intJK i 9 ; ""2 EF2 >T <3 // Co!pi e error: O#e of una##igned oca *aria$ e 'f' //!Sy#te!.Con#o e.VriteLine0&f.Length9& R f.Length13 Sy#te!.Con#o e.VriteLine0&g.Length 9 & R g.Length13 // 'he pri!iti*e# in#ide the array are // auto!atica y initia iMed to Mero: for0int index 9 03 index W g.Length3 indexRR1 Sy#te!.Con#o e.VriteLine0&gJ& R index R &K9& R gJindexK13 Sy#te!.Con#o e.VriteLine0&h.Length 9 & R h.Length13 Sy#te!.Con#o e.VriteLine0&i.Length 9 & R i.Length13 f 9 i3 Sy#te!.Con#o e.VriteLine0&f.Length 9 & R f.Length13 f 9 ne. intJK ; "2 2 <3 Sy#te!.Con#o e.VriteLine0&f.Length 9 & R f.Length13 < < ///:8 Here# the *utput 9r*+ the pr*gra+1 a.Length92 $.Length 9 P c.Length 9 ? c.LengthJ0K 9 2 c.LengthJ"K 9 T $J0K9 $J"K9 $J2K9 $JTK9 $JEK9

3'&

Thinking in C

www.ThinkingIn.!et

d.Length 9 E d.Length 9 E a.Length 9 E g.Length 9 P gJ0K90 gJ"K90 gJ2K90 gJTK90 gJEK90 h.Length 9 E i.Length 9 T f.Length 9 T f.Length 9 2 The array a i# initially 4u#t a null re9erence, and the c*+piler prevent# y*u 9r*+ d*ing anything !ith thi# re9erence until y*uve pr*perly initiali7ed it) The array b i# initiali7ed t* p*int t* an array *9 =eeble re9erence#, 3ut n* actual =eeble *34ect# are ever placed in that array) H*!ever, y*u can #till a#k !hat the #i7e *9 the array i#, #ince b i# p*inting t* a legiti+ate *34ect) Thi# 3ring# up a #light dra!3ack1 y*u cant 9ind *ut h*! +any ele+ent# are actually in the array, #ince Length tell# y*u *nly h*! +any ele+ent# can 3e placed in the arrayQ that i#, the #i7e *9 the array *34ect, n*t the nu+3er *9 ele+ent# it actually h*ld#) H*!ever, !hen an array *34ect i# created it# re9erence# are aut*+atically initiali7ed t* null, #* y*u can #ee !hether a particular array #l*t ha# an *34ect in it 3y checking t* #ee !hether it# null) Si+ilarly, an array *9 pri+itive# i# aut*+atically initiali7ed t* 7er* 9*r nu+eric type#, (char)4 9*r char, and false 9*r bool) =rray c #h*!# the creati*n *9 the array *34ect 9*ll*!ed 3y the a##ign+ent *9 =eeble *34ect# t* all the #l*t# in the array) =rray d #h*!# the Iaggregate initiali7ati*nJ #ynta; that cau#e# the array *34ect t* 3e created Gi+plicitly !ith new *n the heap, 4u#t like 9*r array cH and initiali7ed !ith =eeble *34ect#, all in *ne #tate+ent) The ne;t array initiali7ati*n c*uld 3e th*ught *9 a# a Idyna+ic aggregate initiali7ati*n)J The aggregate initiali7ati*n u#ed 3y d +u#t 3e u#ed at the p*int *9 d# de9initi*n, 3ut !ith the #ec*nd #ynta; y*u can create and initiali7e an array *34ect any!here) 5*r e;a+ple, #upp*#e "ide() i# a +eth*d that take# an array *9 =eeble *34ect#) :*u c*uld call it 3y #aying1

Cha"ter '* >olding Eour 123ects

3''

Uide0d13 3ut y*u can al#* dyna+ically create the array y*u !ant t* pa## a# the argu+ent1 Uide0ne. Vee$ eJK ; ne. Vee$ e012 ne. Vee$ e01 <13 -n #*+e #ituati*n# thi# ne! #ynta; pr*vide# a +*re c*nvenient !ay t* !rite c*de) Rectangular array# are initiali7ed u#ing ne#ted array#) =lth*ugh a rectangular array i# c*ntigu*u# in +e+*ry, C## c*+piler !ill n*t all*! y*u t* ign*re the di+en#i*n#Q y*u cann*t ca#t a 9lat array int* a rectangular array *r initiali7e a rectangular array in a I9latJ +anner) The e;pre##i*n1 a 9 d3 #h*!# h*! y*u can take a re9erence that# attached t* *ne array *34ect and a##ign it t* an*ther array *34ect, 4u#t a# y*u can d* !ith any *ther type *9 *34ect re9erence) *! 3*th a and d are p*inting t* the #a+e array *34ect *n the heap) The #ec*nd part *9 'rray#iTe6cs #h*!# that pri+itive array# !*rk 4u#t like *34ect array# e%ce"t that pri+itive array# h*ld the pri+itive value# directly)

-he Array class


-n #ystem6Collections, y*ull 9ind the 'rray cla##, !hich ha# a variety *9 intere#ting pr*pertie# and +eth*d#) 'rray i# de9ined a# i+ple+enting BCloneable, BList, BCollection, and B&numerable) Thi# i# actually a pretty #l*ppy declarati*n, a# BList i# declared a# e;tending BCollection and B&numerable, !hile BCollection i# it#el9 declared a# e;tending B&numerable G5igure #HK

4((

Thinking in C

www.ThinkingIn.!et

IEnumerable ICloneable

ICollection

IList

Array

The 'rray cla## ha# #*+e pr*pertie# inherited 9r*+ BCollection that are the #a+e 9*r all in#tance#1 Bs:ixed#iTe i# al!ay# true, Bs*ead1nly and Bs#ynchroniTed are al!ay# false6

)rra5s 'tatic @ethods


The 'rray cla## ha# #everal u#e9ul #tatic +eth*d#, !hich are illu#trated in thi# pr*gra+1 //:c0>:)rrayStatic#.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 c a## Vee$ e ; #tring na!e3 interna #tring Ca!e; get ; return na!e3< #et ; na!e 9 *a ue3< < interna Vee$ e0#tring na!e1 ; thi#.Ca!e 9 na!e3

Cha"ter '* >olding Eour 123ects

4(1

< < c a## )rrayStatic# ; #tatic #tringJK dayLi#t 9 ne. #tringJK; &#unday&2 &!onday&2 &tue#day&2 &.edne#day&2 &thur#day&2 &friday&2 &#aturday& <3 #tatic #tringJ2K fa!ou#Coup e# 9 ne. #tringJ2K; ; &_eorge&2 &Gartha&<2 ; &Capo ean&2 &`o#ephine&<2 ; &Ve#t ey&2&Buttercup&< <3 #tatic Vee$ eJK .ee$ eLi#t 9 ne. Vee$ eJK; ne. Vee$ e0&-i ot&12 ne. Vee$ e0&Hirefighter&1 <3 pu$ ic #tatic *oid Gain01 ; //Copying array# Vee$ eJK ne.Li#t 9 ne. Vee$ eJ.ee$ eLi#t.LengthK3 )rray.Copy0.ee$ eLi#t2 ne.Li#t2 .ee$ eLi#t.Length13 ne.Li#tJ0K 9 ne. Vee$ e0&Cur#e&13 $oo ne.Reference# 9 ne.Li#tJ0K !9 .ee$ eLi#tJ0K3 Sy#te!.Con#o e.VriteLine0&Ce. reference# 99 R ne.Reference#13 //Copying a rectangu ar array .or%# #tringJ2K ne.S7uare)rray 9 ne. #tringJfa!ou#Coup e#._etLength0012 fa!ou#Coup e#._etLength0"1K3 )rray.Copy0fa!ou#Coup e#2 ne.S7uare)rray2 fa!ou#Coup e#.Length13 //5n6p ace #orting #tringJK #orted:ay# 9 ne. #tringJdayLi#t.LengthK3 )rray.Copy0dayLi#t2 #orted:ay#2 dayLi#t.Length13 )rray.Sort0#orted:ay#13

&

4()

Thinking in C

www.ThinkingIn.!et

for 0int i 9 03 i W #orted:ay#.Length3 iRR1 ; Sy#te!.Con#o e.VriteLine0&#orted:ay#J;0<K 9 ;"<&2 i2 #orted:ay#JiK13 < //Binary #earch of #orted "6: )rray int tue#day5ndex 9 )rray.BinarySearch0#orted:ay#2 &tue#day&13 Sy#te!.Con#o e.VriteLine0&dayLi#tJ;0<K 99 ^&tue#day^&&2 tue#day5ndex13 //! int george5ndex 9 )rray.BinarySearch0fa!ou#Coup e#2 &_eorge&<3 W6 Co!pi e error //Re*er#e )rray.Re*er#e0#orted:ay#13 for 0int i 9 03 i W #orted:ay#.Length3 iRR1 ; Sy#te!.Con#o e.VriteLine0&Re*er#ed #orted:ay#J;0<K 9 ;"<&2 i2 #orted:ay#JiK13 < //Quic% y era#ing an array #ection2 e*en if !u tidi!en#iona )rray.C ear0fa!ou#Coup e#2 22 T13 for 0int x 9 03 x W fa!ou#Coup e#._etLength0013 xRR1 for 0int y 9 03 y W fa!ou#Coup e#._etLength0"13 yRR1 Sy#te!.Con#o e.VriteLine0&Ha!ou#Coup e#J;0<2;"<K 9 ;2<&2 x2 y2 fa!ou#Coup e#Jx2yK13 < <///:8 =9ter declaring a ,ee3le cla## Gthi# ti+e !ith a a+e pr*perty t* +ake the+ ea#ier t* di#tingui#hH, the 'rray#tatics cla## declare# #everal #tatic array# P dayList and weebleList, !hich are 3*th *neEdi+en#i*nal, and the #Duare famousCouples array) 'rray6CopyGH pr*vide# a 9a#t !ay t* c*py an array G*r a p*rti*n *9 itH) The ne! array c*ntain# all ne! re9erence#, #* changing a value in y*ur ne! li#t !ill n*t change the value in y*ur *riginal, a# !*uld 3e the ca#e i9 y*u did1

Cha"ter '* >olding Eour 123ects

4(3

Vee$ eJK ne.Li#t 9 .ee$ eLi#t3 ne.Li#tJ0K 9 ne. Vee$ e0&Cur#e&13 'rray6Copy() !*rk# !ith +ultidi+en#i*nal array#, t**) The pr*gra+ u#e# the etLength(int) +eth*d t* all*cate #u99icient #t*rage 9*r the new#%uare'rray, 3ut then u#e# the famousCouples6Length pr*perty t* #peci9y the #i7e *9 the c*py) =lth*ugh Copy() #ee+# t* I9lattenJ +ultidi+en#i*nal array#, u#ing array# *9 di99erent rank !ill thr*! a runti+e *an(&xception) The #tatic +eth*d 'rray6#ort() d*e# an inEplace #*rt *9 the array# c*ntent# and Binary#earch() pr*vide# an e99icient #earch *n a #*rted array) 'rray6*everse() i# #el9Ee;planat*ry, 3ut 'rray6Clear() ha# the perhap# #urpri#ing 3ehavi*r *9 #licing acr*## +ultidi+en#i*nal array#) -n the pr*gra+, 'rray6Clear(famousCouples, 8, 9) treat# the +ultidi+en#i*nal famousCouples array a# a 9lat array, #etting t* null the value# *9 indice# Z0,$\, Z0,0\, and Z2,$\)

)rra5 ele#ent co#$arisons


H*! d*e# 'rray6#ort() !*rkF = pr*3le+ !ith !riting generic #*rting c*de i# that #*rting +u#t per9*r+ c*+pari#*n# 3a#ed *n the actual type *9 the *34ect) O9 c*ur#e, *ne appr*ach i# t* !rite a di99erent #*rting +eth*d 9*r every di99erent type, 3ut y*u #h*uld 3e a3le t* rec*gni7e that thi# d*e# n*t pr*duce c*de that i# ea#ily reu#ed 9*r ne! type#) = pri+ary g*al *9 pr*gra++ing de#ign i# t* I#eparate thing# that change 9r*+ thing# that #tay the #a+e,J and here, the c*de that #tay# the #a+e i# the general #*rt alg*rith+, 3ut the thing that change# 9r*+ *ne u#e t* the ne;t i# the !ay *34ect# are c*+pared) S* in#tead *9 hardE!iring the c*+pari#*n c*de int* +any di99erent #*rt r*utine#, the techniDue *9 the call2ack i# u#ed) ,ith a call3ack, the part *9 the c*de that varie# 9r*+ ca#e t* ca#e i# encap#ulated in#ide it# *!n cla##, and the part *9 the c*de that# al!ay# the #a+e !ill call 3ack t* the c*de that change#) That !ay y*u can +ake di99erent *34ect# t* e;pre## di99erent !ay# *9 c*+pari#*n and 9eed the+ t* the #a+e #*rting c*de)

4(4

Thinking in C

www.ThinkingIn.!et

-n C#, c*+pari#*n# are d*ne 3y calling 3ack t* the Compare+o() +eth*d *9 the BComparable inter9ace) Thi# +eth*d take# an*ther ob)ect a# an argu+ent, and pr*duce# a negative value i9 the current *34ect i# le## than the argu+ent, 7er* i9 the argu+ent i# eDual, and a p*#itive value i9 the current *34ect i# greater than the argu+ent) Here# a cla## that i+ple+ent# BComparable and de+*n#trate# the c*+para3ility 3y u#ing 'rray6#ort( )1 //:c0>:Co!p'ype.c# // 5!p e!enting 5Co!para$ e in a c a##. u#ing Sy#te!3 pu$ ic c a## Co!p'ype: 5Co!para$ e ; int i3 int D3 pu$ ic Co!p'ype0int n"2 int n21 ; i 9 n"3 D 9 n23 < pu$ ic o*erride #tring 'oString01 ; return &Ji 9 & R i R &2 D 9 & R D R &K&3 < pu$ ic int Co!pare'o0O$Dect r*1 ; int r*i 9 00Co!p'ype1r*1.i3 return 0i W r*i Y 6" : 0i 99 r*i Y 0 : "113 < pri*ate #tatic Rando! r 9 ne. Rando!013 pri*ate #tatic *oid )rray-rint0String #2 )rray a1; Sy#te!.Con#o e.Vrite0#13 foreach0O$Dect o in a1; Sy#te!.Con#o e.Vrite0o R &2&13 < Sy#te!.Con#o e.VriteLine013 < pu$ ic #tatic *oid Gain01 ; Co!p'ypeJK a 9 ne. Co!p'ypeJ"0K3

Cha"ter '* >olding Eour 123ects

4(5

for0int i 9 03 i W "03 iRR1; aJiK 9 ne. Co!p'ype0r.Cext0"0012 r.Cext0"00113 < )rray-rint0&Before #orting2 a 9 &2 a13 )rray.Sort0a13 )rray-rint0&)fter #orting2 a 9 &2 a13 < < ///:8 ,hen y*u de9ine the c*+pari#*n 9uncti*n, y*u are re#p*n#i3le 9*r deciding !hat it +ean# t* c*+pare *ne *9 y*ur *34ect# t* an*ther) Here, *nly the i value# are u#ed in the c*+pari#*n, and the ) value# are ign*red) The .ain() +eth*d create# a 3unch *9 Comp+ype *34ect# that are initiali7ed !ith rand*+ value# and then #*rted) -9 Comparable hadnt 3een i+ple+ented, then y*ud get an -nvalidOperati*nE;cepti*n thr*!n at runti+e !hen y*u tried t* call 'rray6#ort( ))

What< (o +u++les<
-n the n*tE#*Edi#tant pa#t, the #*rt and #earch +eth*d# u#ed in a pr*gra+ !ere a +atter *9 c*n#tant de3ate and angui#h) -n the g**d *ld day#, even the +*#t trivial data#et# had a g**d chance *9 3eing larger than R=A G*r Ic*reJ a# !e u#ed t* #ayH and reDuired inter+ediate read# and !rite# t* #t*rage device# that c*uld take, ye#, #ec*nd# t* acce## G*r, i9 the tape# needed t* 3e #!apped, +inute#H) S* there !a# an en*r+*u# a+*unt *9 energy put int* !*rrying a3*ut internal GinE+e+*ryH ver#u# e;ternal #*rt#, the #ta3ility *9 #*rt#, the i+p*rtance *9 +aintaining the input tape until the *utput tape !a# veri9ied, the I*perat*r di#+*unt ti+e,J and #* 9*rth) *!aday#, 66^ *9 the ti+e y*u can ign*re the particular# *9 #*rting and #earching) -n *rder t* get a decent idea *9 #*rting #peed, thi# pr*gra+ reDuire# an array *9 0,$$$,$$$ ele+ent#, and #till it e;ecute# in a +atter *9 #ec*nd#1 //:c0>:Ha#tSort.c# u#ing Sy#te!3

4(6

Thinking in C

www.ThinkingIn.!et

c a## Sorta$ e : 5Co!para$ e ; int i3 interna Sorta$ e0int i1 ; thi#.i 9 i3 < pu$ ic int Co!pare'o0O$Dect o1 ; try ; Sorta$ e # 9 0Sorta$ e1 o3 return i 9 #.i3 < catch 05n*a idCa#t+xception1 ; thro. ne. )rgu!ent+xception013 < < < c a## Sorting'e#ter ; #tatic 'i!eSpan 'i!edSort05Co!para$ eJK #1; :ate'i!e #tart 9 :ate'i!e.Co.3 )rray.Sort0#13 'i!eSpan duration 9 :ate'i!e.Co. 6 #tart3 return duration3 < pu$ ic #tatic *oid Gain01 ; for 0int ti!e# 9 03 ti!e# W "03 ti!e#RR1 ; Sorta$ eJK # 9 ne. Sorta$ eJ"000000K3 for 0int i 9 03 i W #.Length3 iRR1 ; #JiK 9 ne. Sorta$ e0i13 < Sy#te!.Con#o e.VriteLine0&'i!e to #ort a ready #orted array: & R 'i!edSort0#113 Rando! rand 9 ne. Rando!013 for 0int i 9 03 i W #.Length3 iRR1 ; #JiK 9 ne. Sorta$ e0rand.Cext0113 < Sy#te!.Con#o e.VriteLine0&'i!e to #ort !ixed up array: & R 'i!edSort0#113 < < <///:8

Cha"ter '* >olding Eour 123ects

4(#

The re#ult# #h*! that #ort() !*rk# 9a#ter *n an already #*rted array, !hich indicate# that 3ehind the #cene#, it# pr*3a3ly u#ing a +erge #*rt in#tead *9 MuickS*rt) But the #*rting alg*rith+ i# certainly le## i+p*rtant than the 9act that a c*+puter that c*#t# le## than a th*u#and d*llar# can per9*r+ an inE+e+*ry #*rt *9 a +illi*nEite+ arrayK A**re# La! ha# +ade anachr*ni#tic an entire 9ield *9 kn*!ledge and de3ate that #ee+ed, n*t that l*ng ag*, 9unda+ental t* c*+puter pr*gra++ing) Thi# i# an i+p*rtant le##*n 9*r th*#e !h* !i#h t* have l*ng career# in pr*gra++ing1 never c*n9u#e the +a#tery *9 t*day# 9act# !ith preparati*n 9*r t*+*rr*!# change#) ,ithin a decade, !e !ill have +ultiEtera3yte #t*rage *n the de#kt*p, trivial acce## t* di#tri3uted tera9l*p pr*ce##ing, and pr*3a3ly #peciali7ed acce## t* Duantu+ c*+puter# *9 #igni9icant capa3ility) Eventually, alth*ugh - d*u3t !ithin a decade, there !ill 3e 3reakthr*ugh# in u#er inter9ace# and !ell a3and*n the key3*ard and the +*nit*r 9*r v*ice and ge#ture input and Iaug+ented realityJ gla##e#) =l+*#t all the pr*gra++ing 9act# that h*ld t*day !ill 3e a# u#ele## a# the kn*!ledge *9 h*! t* d* an *#cillating #*rt !ith cri##Ecr*## di#tri3uti*n) = pr*gra++er +u#t never #tand #till)

>nsa0e )rra5s
?e#pite the preceding di#cu##i*n *9 the #teady +arch *9 technical *3#*le#cence, the 9act# *n the gr*und *9ten agitate t*!ard# thr*!ing a!ay the 3ene9it# *9 #a9ety and a3#tracti*n and getting cl*#er t* the hard!are in *rder t* 3**#t per9*r+ance) O9ten, the c*rrect #*luti*n in thi# ca#e !ill 3e t* +*ve *ut *9 C# alt*gether and int* C@@, a language !hich !ill c*ntinue 9*r #*+e ti+e t* 3e the 3e#t 9*r the creati*n *9 device driver# and *ther cl*#eEt*EtheE+etal c*+p*nent#) H*!ever, +anipulating array# can #*+eti+e# intr*duce 3*ttleneck# in higherElevel applicati*n#, #uch a# +ulti+edia applicati*n#) -n #uch #ituati*n#, un#a9e c*de +ay 3e !*rth!hile) The 3a#ic i+petu# 9*r u#ing un#a9e array# i# that y*u !i#h t* +anipulate the array a# a c*ntigu*u# 3l*ck *9 +e+*ry, 9*reg*ing 3*und# checking) ,avelet tran#9*r+# are 9a#cinating and their utility ha# hardly 3een #cratched) The #i+ple#t tran#9*r+ i# pr*3a3ly the t!*Edi+en#i*nal Haar tran#9*r+ *n a +atri; *9 d*u3le#) The Haar tran#9*r+ c*nvert# a li#t *9

4(&

Thinking in C

www.ThinkingIn.!et

value# int* the li#t# average and di99erence#, #* the li#t c2, &] i# tran#9*r+ed int* c/, 0] XX cG2 @ &H < 2, G2 @ &H < 2 P 2H]) = t!*E di+en#i*nal tran#9*r+ 4u#t tran#9*r+# the r*!# and then the c*lu+n#, #* cc2, &],c',.]] 3ec*+e# cc&)2', )%'],c0)2', E$)2']]1

,avelet# have +any intere#ting characteri#tic#, including 3eing the 3a#i# 9*r #*+e e;cellent c*+pre##i*n r*utine#, 3ut are e;pen#ive t* c*+pute 9*r array# that are typical *9 +ulti+edia applicati*n#, e#pecially 3ecau#e t* 3e u#e9ul they are u#ually c*+puted l*g2GA- Gdi+en#i*n #i7eHH ti+e# per arrayK The 9*ll*!ing pr*gra+ d*e# #uch a tran#9*r+ in t!* di99erent !ay#, *ne a #a9e +eth*d that u#e# typical C# c*de and the *ther u#ing un#a9e c*de) //:c0>:Ha#tBit!apper".c# u#ing Sy#te!3 u#ing Sy#te!.5O3 na!e#pace Ha#tBit!apper; pu$ ic interface 'ran#for!; *oid UoriMonta 'ran#for!0dou$ eJ2K !atrix13 *oid Nertica 'ran#for!0dou$ eJ2K !atrix13 < pu$ ic c a## Va*e et ; pu$ ic *oid 'ran#for!2:0dou$ eJ2K !atrix2 'ran#for! t1 ; int !in:i!en#ion 9 !atrix._etLength0013 if 0!atrix._etLength0"1 W !in:i!en#ion1 !in:i!en#ion 9 !atrix._etLength0"13

Cha"ter '* >olding Eour 123ects

4('

int e*e # 9 0int1 Gath.H oor0Gath.Log0!in:i!en#ion2 2113 'ran#for!2:0!atrix2 e*e #2 t13 < pu$ ic *oid 'ran#for!2:0dou$ eJ2K !atrix2 int #tep#2 'ran#for! tStrategy1 ; for 0int i 9 03 i W #tep#3 iRR1 ; tStrategy.UoriMonta 'ran#for!0!atrix13 tStrategy.Nertica 'ran#for!0!atrix13 < < pu$ ic *oid 'e#tSpeed0'ran#for! t1 ; Rando! rand 9 ne. Rando!013 dou$ eJ2K !atrix 9 ne. dou$ eJ200022000K3 for 0int i 9 03 i W !atrix._etLength0013 iRR1 for 0int D 9 03 D W !atrix._etLength0"13 DRR1 ; !atrixJi2DK 9 rand.Cext:ou$ e013 < :ate'i!e #tart 9 :ate'i!e.Co.3 thi#.'ran#for!2:0!atrix2 t13 'i!eSpan dur 9 :ate'i!e.Co. 6 #tart3 Sy#te!.Con#o e.VriteLine0&'ran#for!ation .ith ;0< too% ;"< &2 t._et'ype01.Ca!e2 dur13 < pu$ ic #tatic *oid Gain01 ; Va*e et . 9 ne. Va*e et013 for 0int i 9 03 i W "03 iRR1 ; //_et thing# right fir#t ..'e#tSpeed0ne. Safe'ran#for!0113 ..'e#tSpeed0ne. On#afe'ran#for!0113 < < <

41(

Thinking in C

www.ThinkingIn.!et

interna c a## Safe'ran#for! : 'ran#for! ; pri*ate *oid 'ran#for!0dou$ eJK array1 ; int ha fLength 9 array.Length ZZ "3 dou$ eJK a*g 9 ne. dou$ eJha fLengthK3 dou$ eJK diff 9 ne. dou$ eJha fLengthK3 for 0int pair 9 03 pair W ha fLength3 pairRR1 ; dou$ e fir#t 9 arrayJpair = 2K3 dou$ e next 9 arrayJpair = 2 R "K3 a*gJpairK 9 0fir#t R next1 / 23 diffJpairK 9 a*gJpairK 6 fir#t3 < for 0int pair 9 03 pair W ha fLength3 pairRR1 ; arrayJpairK 9 a*gJpairK3 arrayJpair R ha fLengthK 9 diffJpairK3 < < pu$ ic *oid UoriMonta 'ran#for!0dou$ eJ2K !atrix1 ; int height 9 !atrix._etLength0013 int .idth 9 !atrix._etLength0"13 dou$ eJK ro. 9 ne. dou$ eJ.idthK3 for 0int i 9 03 i W height3 iRR1 ; for 0int D 9 03 D W .idth3 DRR1 ; ro.JDK 9 !atrixJi2 DK3 < 'ran#for!0ro.13 for 0int D 9 03 D W .idth3 DRR1 ; !atrixJi2DK 9 ro.JDK3 < < < pu$ ic *oid Nertica 'ran#for!0dou$ eJ2K !atrix1 ; int height 9 !atrix._etLength0013 int ength 9 !atrix._etLength0"13 dou$ eJK co :ata 9 ne. dou$ eJheightK3 for 0int co 9 03 co W ength3 co RR1 ;

Cha"ter '* >olding Eour 123ects

411

for 0int ro. 9 03 ro. W height3 ro.RR1 ; co :ataJro.K 9 !atrixJro.2 co K3 < 'ran#for!0co :ata13 for 0int ro. 9 03 ro. W height3 ro.RR1 ; !atrixJro.2 co K 9 co :ataJro.K3 < < < < <///:8

Get things rightP


The cardinal rule *9 per9*r+ance pr*gra++ing i# t* 9ir#t get the #y#te+ *perating pr*perly and then !*rry a3*ut per9*r+ance) The #ec*nd rule i# t* al!ay# u#e a pr*9iler t* +ea#ure !here y*ur pr*3le+# are, never g* !ith a gue##) -n an *34ectE*riented de#ign, a9ter di#c*vering a h*t#p*t, y*u #h*uld al!ay# 3reak the pr*3le+ *ut int* an a3#tract data type Gan inter9aceH i9 it i# n*t already) Thi# !ill all*! y*u t* #!itch 3et!een di99erent i+ple+entati*n# *ver ti+e, c*n9ir+ing that y*ur per9*r+ance !*rk i# acc*+pli#hing #*+ething and that it i# n*t diverging 9r*+ y*ur c*rrect I#a9eJ !*rk) -n thi# ca#e, the ,avelet cla## u#e# an inter9ace called Tran#9*r+ t* per9*r+ the actual !*rk1
Transform Wavelet void HorizontalTransform(double[, ] matri ! void "erticalTransform(double[, ] matri !

The +ransform inter9ace c*ntain# t!* +eth*d#, each *9 !hich take# a rectangular array a# a para+eter and per9*r+# an inEplace tran#9*r+ati*nQ "oriTontal+ransform() c*nvert# a r*! *9 value# int* a r*! c*ntaining the average# and di99erence# *9 the r*!, and Hertical+ransform() per9*r+# a #i+ilar tran#9*r+ati*n *n the c*lu+n# *9 the array)

41)

Thinking in C

www.ThinkingIn.!et

The =avelet cla## c*ntain# t!* +ransform8$() +eth*d#, the 9ir#t *9 !hich take# a rectangular array and a +ransform) The nu+3er *9 #tep# reDuired t* per9*r+ a 9ull !avelet tran#9*r+ i# calculated 3y 9ir#t deter+ining the +ini+u+ di+en#i*n *9 the pa##edEin +atri; and then u#ing the .ath6Log() 9uncti*n t* deter+ine the 3a#eE2 +agnitude *9 that di+en#i*n) .ath6:loor() r*und# that +agnitude d*!n and the re#ult i# ca#t t* the integer nu+3er *9 #tep# that !ill 3e applied t* the +atri;) GThu#, an array !ith a +ini+u+ di+en#i*n *9 & !*uld have 2 #tep#, an array !ith 0$2& !*uld have 6)H The c*n#truct*r then call# the #ec*nd c*n#truct*r, !hich take# the #a+e para+eter# a# the 9ir#t plu# the nu+3er *9 ti+e# t* apply the !avelet Gthi# i# a #eparate c*n#truct*r 3ecau#e during de3ugging a #ingle !avelet #tep i# +uch ea#ier t* c*+prehend than a 9ully pr*ce##ed *ne, a# 5igure # #h*!#H

Cha"ter '* >olding Eour 123ects

413

The +ransform8$() +eth*d iterate# steps ti+e# *ver the +atri;, 9ir#t per9*r+ing a h*ri7*ntal tran#9*r+ and then per9*r+ing a vertical tran#9*r+) =lternating 3et!een h*ri7*ntal and vertical tran#9*r+# i# called the nonstandard wa-elet decom"osition) The standard decom"osition per9*r+# steps h*ri7*ntal tran#9*r+# and then per9*r+# steps vertical tran#9*r+#) ,ith graphic# any!ay, the n*n#tandard dec*+p*#iti*n all*!# 9*r ea#ier appreciati*n *9 the !avelet 3ehavi*rQ in 5igure #, the upperEle9t Duadrant i# a hal9Ere#*luti*n duplicate *9 the *riginal, the upperEright a +ap *9 0Epi;el h*ri7*ntal 9eature#, the l*!erE le9t a #i+ilar +ap *9 vertical 9eature#, and the l*!erEright a c*+plete +ap *9 0Epi;el 9eature#) ,hen the re#ult i# tran#9*r+ed again and again, the re#ult ha# +any intere#ting 9eature#, including 3eing highly c*+pre##i3le !ith 3*th l*##le## and l*##y techniDue#)

414

Thinking in C

www.ThinkingIn.!et

The +est#peed() +eth*d in =avelet create# a &,$$$,$$$Eele+ent #Duare array, 9ill# it !ith rand*+ d*u3le#, and then calculate# and print# the ti+e nece##ary t* per9*r+ a 9ull !avelet tran#9*r+ *n the re#ult) The .ain() +eth*d call# thi# +est#peed() +eth*d 0$ ti+e# in *rder t* en#ure that any tran#ient *perating #y#te+ event# d*nt #ke! the re#ult#) Thi# 9ir#t ver#i*n *9 the c*de call# +est#peed() !ith a #afe+ransform P get thing# right and then get the+ 9a#t) The #afe+ransform cla## ha# a private +ransform() +eth*d !hich take# a *neEdi+en#i*nal array *9 d*u3le#) -t create# t!* array#, avg and diff *9 hal9 the !idth *9 the *riginal) The 9ir#t l**p in +ransform() +*ve# acr*## the #*urce array, reading value pair#) -t calculate# and placed the#e pair# average and di99erence in the avg and diff array#) =9ter thi# l**p 9ini#hed, the value# in avg are c*pied t* the 9ir#t hal9 *9 the input array and the value# in diff t* the #ec*nd hal9) =9ter +ransform() 9ini#he#, the input array n*! c*ntain# the value# *9 a *neE#tep, *neE di+en#i*nal Haar tran#9*r+ati*n) G *te that the tran#9*r+ i# 9ully rever#i3le EE the *riginal data can 3e re#t*red 3y 9ir#t adding and then #u3tracting a diff value t* a c*rre#p*nding avg value)H #afe+ransform6"oriTontal+ransform() deter+ine# the height *9 the pa##edEin +atri; and, c*pie# the value# *9 each r*! int* a *neE di+en#i*nal array *9 d*u3le# called row) Then the c*de call# the previ*u#ly de#cri3ed +ransform() +eth*d and c*pie# the re#ult 3ack int* the *riginal t!*Edi+en#i*nal +atri;) ,hen "oriTontal+ransform() i# 9ini#hed, the input +atri; a# a !h*le n*! c*ntain# a *neE#tep, h*ri7*ntal Haar tran#9*r+ati*n) #afe+ransform6Hertical+ransform() u#e# a #i+ilar #et *9 l**p# a# "oriTontal+ransform(), 3ut in#tead *9 c*pying r*!# 9r*+ the input +atri;, it c*pie# the value# in a c*lu+n int* a d*u3le array called col$ata, tran#9*r+# that !ith +ransform(), and c*pie# the re#ult 3ack int* the input +atri;) ,hen thi# 9ini#hed, c*ntr*l return# t* =avelet6+ransform8$(), and *ne #tep *9 the !avelet dec*+p*#iti*n ha# 3een per9*r+ed)

Cha"ter '* >olding Eour 123ects

415

P -hen Get -he# 7ast


Running thi# thr*ugh a pr*9iler G- u#e -ntel# vTuneH #h*!# that a l*t *9 ti+e i# #pent in the "oriTontal+ransform() and Hertical+ransform() +eth*d# in additi*n t* the +ransform() +eth*d it#el9) S*, let# try t* i+pr*ve all three 3y u#ing un#a9e c*de1 //:c0>:On#afe'ran#for!.c# interna c a## On#afe'ran#for! : 'ran#for! ; un#afe pri*ate *oid 'ran#for!0dou$ e= array2 int ength1 ; //Sy#te!.Con#o e.VriteLine0&On#afe'ran#for!0;0<2 ;"<&2 =array2 ength13 dou$ e= pOrigina )rray 9 array3 int ha fLength 9 ength ZZ "3 dou$ eJK a*g 9 ne. dou$ eJha fLengthK3 dou$ eJK diff 9 ne. dou$ eJha fLengthK3 for 0int pair 9 03 pair W ha fLength3 pairRR1 ; dou$ e fir#t 9 =array3 RRarray3 dou$ e next 9 =array3 RRarray3 a*gJpairK 9 0fir#t R next1 / 23 diffJpairK 9 a*gJpairK 6 fir#t3 < for 0int pair 9 03 pair W ha fLength3 pairRR1 ; pOrigina )rrayJpairK 9 a*gJpairK3 pOrigina )rrayJpair R ha fLengthK 9 diffJpairK3 < < un#afe pu$ ic *oid UoriMonta 'ran#for!0dou$ eJ2K !atrix1 ; int height 9 !atrix._etLength0013 int .idth 9 !atrix._etLength0"13 fixed0dou$ e= pGatrix 9 !atrix1 ; dou$ e= pOff#et 9 pGatrix3

416

Thinking in C

www.ThinkingIn.!et

for 0int ro. 9 03 ro. W height3 ro.RR1 ; 'ran#for!0pOff#et2 .idth13 pOff#et R9 .idth3 < < < un#afe pu$ ic *oid Nertica 'ran#for!0dou$ eJ2K !atrix1 ; fixed0dou$ e= pGatrix 9 !atrix1 ; int height 9 !atrix._etLength0013 int ength 9 !atrix._etLength0"13 dou$ eJK co :ata 9 ne. dou$ eJheightK3 for 0int co 9 03 co W ength3 co RR1 ; for 0int ro. 9 03 ro. W height3 ro.RR1 ; co :ataJro.K 9 pGatrixJco R ength = ro.K3 < fixed0dou$ e= pCo :ata 9 co :ata1 ; 'ran#for!0pCo :ata2 height13 < for 0int ro. 9 03 ro. W height3 ro.RR1 ; pGatrixJco R ength = ro.K 9 co :ataJro.K3 < < < < <///:8 5ir#t, n*tice that Vnsafe+ransform ha# the #a+e #tructure a# #afe+ransform, a private +ransform() 9uncti*n in additi*n t* the pu3lic +eth*d# !hich i+ple+ent +ransform) Thi# i# 3y n* +ean# nece##ary, 3ut it# a g**d #tarting place 9*r *pti+i7ati*n) Vnsafe+ransform6+ransform() ha# a #ignature unlike any C# #ignature di#cu##ed 3e9*re1 unsafe private void +ransform(double;

Cha"ter '* >olding Eour 123ects

41#

array, int length)F ,hen a +eth*d i# declared un#a9e, C# all*!# a ne! type *9 varia3le, called a p*inter) = p*inter c*ntain# a +e+*ry addre## at !hich a value *9 the #peci9ied type i# l*cated) S* the varia3le array c*ntain# n*t a d*u3le value #uch a# $)2 *r 2/&)2(, 3ut a +e+*ry l*cati*n #*+eplace in the runti+e, the c*ntent# *9 !hich are interpreted a# a d*u3le) =dding 0 t* array d*e# n*t change it t* 0)2 *r 2/')2( 3ut rather change# the +e+*ry l*cati*n t* p*int t* the ne;t l*cati*n in +e+*ry that# 3ig en*ugh t* h*ld a double) Such Ip*inter arith+eticJ i# +arginally +*re e99icient than u#ing a C# array, 3ut even #+all di99erence# add up !hen applied t* a &,$$$,$$$ ite+ arrayK The 9ir#t line in Vnsafe+ransform6+ransform() initiali7e# an*ther p*inter varia3le p1riginal'rray !ith the *riginal value in array, !h*#e value i# g*ing t* change) The declarati*n *9 the avg and diff array# and the 9ir#t l**p are identical !ith !hat !a# d*ne in #afe+ransform6+ransform(), e;cept that thi# ti+e !e u#e the value *9 the pa##edEin length varia3le t* calculate the value *9 halfLength Gin #afe+ransform6+ransform(), !e u#ed the Length pr*perty *9 the pa##edEin array, 3ut p*inter# d*nt have #uch a pr*perty, #* !e need the e;tra para+eter) The ne;t line#, th*ugh, are Duite di99erent1 dou$ e fir#t 9 =array3 RRarray3 dou$ e next 9 =array3 RRarray3 ,hen applied t* a p*inter varia3le, the b *perat*r retrieve# the value that i# #t*red at that addre## Gthe +ne+*nic i# I#tar X #t*redJH) S* the first d*u3le i# a##igned the value *9 the d*u3le at array# addre## value) Then, !e u#e p*inter arith+etic *n array #* that it #kip# *ver a d*u3le# !*rth *9 +e+*ry, read the value there a# a d*u3le and a##ign it t* next and incre+ent array again) The value# *9 avg and diff are calculated 4u#t a# they !ere in #afe+ransform6+ransform()) S* the 3ig di99erence in thi# l**p i# that in#tead *9 inde;ing in t* an array *9 double# *9 a certain length, !eve incre+ented a p*inter t* double# length ti+e#, and interpreted the +e+*ry *9 !here !e !ere p*inting at a# a #erie# *9 double#) There# 3een n* 3*und# *r type checking *n the value *9 *ur array p*inter, #* i9 thi# +eth*d !ere called !ith either

41&

Thinking in C

www.ThinkingIn.!et

array #et inc*rrectly *r !ith a !r*ng length, thi# l**p !*uld 3lithely read !hatever it happened t* 3e p*inting at) Such a #ituati*n +ight 3e hard t* track d*!n, 3ut the 9inal l**p in Vnsafe6+ransform() !*uld pr*3a3ly n*t g* undetected) = 9eature *9 p*inter# i# that y*u can u#e array n*tati*n t* indicate an *99#et in +e+*ry) Thu#, in thi# l**p, !e !rite 3ack int* the regi*n *9 +e+*ry at p1riginal'rray large en*ugh t* c*ntain length d*u3le#) ,riting int* an invalid regi*n *9 +e+*ry i# a pretty #ure !ay t* cau#e a cra#h) S* it 3eh**ve# u# t* +ake #ure that Vnsafe6+ransform() i# *nly called pr*perly) Vnsafe6"oriTontal+ransform() take# a t!*Edi+en#i*nal rectangular array *9 d*u3le# called matrix) Be9*re calling Vnsafe6+ransform(), !hich take# a p*inter t* a d*u3le, the matrix +u#t 3e IpinnedJ in +e+*ry) The ) ET gar3age c*llect*r i# n*r+ally 9ree t* +*ve *34ect# a3*ut, 3ecau#e the gar3age c*llect*r ha# the nece##ary data t* deter+ine every re9erence t* that *34ect Gindeed, tracking th*#e re9erence# i# the very e##ence *9 gar3age c*llecti*nKH) But !hen a p*inter i# inv*lved, it# n*t #a9e t* +*ve re9erence#Q in *ur ca#e, the l**p# in +ransform 3*th read and !rite a large 3l*ck *9 +e+*ry 3a#ed *n the *riginal pa##edEin addre##) The line fixed(double; p.atrix I matrix) pin# the rectangular array matrix in +e+*ry and initiali7e# a p*inter t* the 3eginning *9 that +e+*ry) P*inter# initiali7ed in a fixed declarati*n are readE*nly and 9*r the purp*#e# *9 p*inter arith+etic, !e need the ne;t line t* declare an*ther p*inter varia3le p1ffset and initiali7e it t* the value *9 p.atrix) *tice that unlike #afe+ransform6"oriTontal+ransform(), !e d* n*t have a te+p*rary *neEdi+en#i*nal row array !hich !e l*ad 3e9*re calling +ransform() and c*py 9r*+ a9ter) -n#tead, the +ain l**p in "oriTontal+ransform() call# +ransform() !ith it# p*inter *9 p1ffset and it# length #et t* the previ*u#ly calculated !idth *9 the input matrix) Then, !e u#e p*inter arith+etic t* 4u+p width !*rth *9 double# in +e+*ry) -n thi# !ay, !e are e;pl*iting the 9act that !e kn*! that a rectangular array i#, 3ehindEtheE#cene#, a c*ntigu*u# chunk *9

Cha"ter '* >olding Eour 123ects

41'

+e+*ry) The line p1ffset CI widthF i# #igni9icantly 9a#ter than the ( line# *9 #a9e c*de it replace#) -n Vnsafe+ransform6Hertical+ransform(), th*ugh, n* #i+ilar #h*rtcut c*+e# t* +ind and the c*de i# virtually identical t* that in #afe+ransform6Hertical+ransform() e;cept that !e #till need t* pin matrix in *rder t* get the p.atrix p*inter t* pa## t* +ransform()) -9 !e g* 3ack t* ,avelet)AainGH and unc*++ent the line that call# +est#peed() !ith a new Vnsafe+ransform(), !ere al+*#t ready t* g*) H*!ever, the C# c*+piler reDuire# a #pecial 9lag in *rder t* c*+pile #*urce that c*ntain# un#a9e c*de) On the c*++andEline, thi# 9lag i# <un#a9e , !hile in Ci#ual Studi* ) ET, the *pti*n i# 9*und 3y rightEclicking *n the Pr*4ect in the S*luti*n E;pl*rer and ch**#ing Pr*pertie# < C*n9igurati*n Pr*pertie# < Build and #etting I=ll*! un#a9e c*de 3l*ck#J t* true) On +y +achine#, Vnsafe+ransform run# a3*ut '$^ 9a#ter than #afe+ransform in de3ugging +*de, and i# a3*ut 2$^ #uperi*r !hen *pti+i7ati*n# are turned *n) Hardly the #tu99 *9 legend#, 3ut in a c*re alg*rith+, perhap# !*rth the e99*rt) There# *nly *ne pr*3le+) Thi# +anaged c*de i+ple+entati*n run# &$^ 9a#ter than Vnsafe+ransformK Can y*u rea#*n !hyF1 //:c0>:5n- ace.c# interna c a## 5n- ace : 'ran#for! ; int ength3 int height3 int ha fLength3 int ha fUeight3 //Ua f the ength of onger di!en#ion dou$ eJK diff 9 nu 3 pri*ate *oid LaMy5nit0dou$ eJ2K !atrix1 ; height 9 !atrix._etLength0013 ength 9 !atrix._etLength0"13 ha fLength 9 ength ZZ "3 ha fUeight 9 height ZZ "3 if 0ha fUeight W ha fLength1 ; diff 9 ne. dou$ eJha fLengthK3

4)(

Thinking in C

www.ThinkingIn.!et

< e #e ; diff 9 ne. dou$ eJha fUeightK3 < < pu$ ic *oid UoriMonta 'ran#for!0dou$ eJ2 K !atrix1 ; if 0diff 99 nu 1 ; LaMy5nit0!atrix13 < for 0int i 9 03 i W height3 iRR1 ; U'ran#for!0!atrix2 i13 < < pu$ ic *oid Nertica 'ran#for!0dou$ eJ2 K !atrix1 ; if 0diff 99 nu 1 ; LaMy5nit0!atrix13 < for 0int co 9 03 co W ength3 co RR1 ; N'ran#for!0!atrix2 co 13 < < pri*ate *oid U'ran#for!0dou$ eJ2K !atrix2 int ro.1 ; for 0int pair 9 03 pair W ha fLength3 pairRR1 ; dou$ e fir#t 9 !atrixJro.2 pair = 2K3 dou$ e next 9 !atrixJro.2 pair = 2 R "K3 dou$ e a*g 9 0fir#t R next1 / 23 !atrixJro.2 pair = 2K 9 a*g3 diffJpairK 9 a*g 6 fir#t3 < for 0int pair 9 03 pair W ha fLength3 pairRR1 ;

Cha"ter '* >olding Eour 123ects

4)1

!atrixJro.2 pair R ha fLengthK 9 diffJpairK3 < < pri*ate *oid N'ran#for!0dou$ eJ2K !atrix2 int co 1 ; for 0int pair 9 03 pair W ha fUeight3 pairRR1 ; dou$ e fir#t 9 !atrixJpair = 22 co K3 dou$ e next 9 !atrixJpair = 2 R "2 co K3 dou$ e a*g 9 0fir#t R next1 / 23 !atrixJpair = 22 co K 9 a*g3 diffJpairK 9 a*g 6 fir#t3 < for 0int pair 9 03 pair W ha fUeight3 pairRR1 ; !atrixJpair R ha fUeight2 co K 9 diffJpairK3 < < <///:8 Bn!lace re+*ve# l**p# and all*cati*n# *9 te+p*rary *34ect# Glike the avg and diff array#H at the c*#t *9 clarity) -n #afe+ransform, the Haar alg*rith+ *9 repeated averaging and di99erencing i# pretty ea#y t* 9*ll*! 4u#t 9r*+ the c*deQ - dare#ay that a 9ir#tEti+e reader *9 Bn!lace +ight n*t intuit, 9*r in#tance, that the c*ntent# *9 the diff array are #trictly 9*r te+p*rary #t*rage) *tice that 3*th "oriTontal+ransform() and Hertical+ransform() check t* #ee i9 diff i# null and call LaTyBnit() i9 it i# n*t) S*+e +ight #ay I,ell, !e kn*! that "oriTontal+ransform() i# called 9ir#t, #* the check in Hertical+ransform() i# #uper9lu*u#)J But i9 !e !ere t* re+*ve the check 9r*+ Hertical+ransform(), !e !*uld 3e changing the de#ign c*ntract *9 the +ransform() inter9ace t* include I:*u +u#t call "oriTontal+ransform() 3e9*re calling Hertical+ransform())J Changing a de#ign c*ntract i# n*t the end *9 the !*rld, 3ut it #h*uld al!ay# 3e given #*+e th*ught) ,hen a c*ntract reDuire# that +eth*d '()

4))

Thinking in C

www.ThinkingIn.!et

3e called 3e9*re +eth*d B(), the t!* +eth*d# are #aid t* 3e I#eDuence c*upled)J SeDuence c*upling i# u#ually accepta3le Gunlike, #ay, Iinternal data c*uplingJ !here *ne cla## directly !rite# t* an*ther cla### varia3le# !ith*ut u#ing pr*pertie# *r +eth*d# t* acce## the varia3le#H) >iven that the check in Hertical+ransformGH i# n*t !ithin a l**p, changing the c*ntract d*e#nt #ee+ !*rth !hat !ill certainly 3e an un+ea#ura3ly #+all di99erence in per9*r+ance)

)rra5 su##ar5
T* #u++ari7e !hat y*uve #een #* 9ar, the 9ir#t and ea#ie#t ch*ice t* h*ld a gr*up *9 *34ect# *9 a kn*!n #i7e i# an array) =rray# are al#* the natural data #tructure t* u#e i9 the !ay y*u !i#h t* acce## the data i# 3y a #i+ple inde;, *r i9 the data i# naturally IrectangularJ in it# 9*r+) -n the re+ainder *9 thi# chapter !ell l**k at the +*re general ca#e, !hen y*u d*nt kn*! at the ti+e y*ure !riting the pr*gra+ h*! +any *34ect# y*ure g*ing t* need, *r i9 y*u need a +*re #*phi#ticated !ay t* #t*re y*ur *34ect#) C# pr*vide# a li3rary *9 collection classes t* #*lve thi# pr*3le+, the 3a#ic type# *9 !hich are BList and B$ictionary) :*u can #*lve a #urpri#ing nu+3er *9 pr*3le+# u#ing the#e t**l#K =+*ng their *ther characteri#tic#, the C# c*llecti*n cla##e# !ill aut*+atically re#i7e the+#elve#) S*, unlike array#, y*u can put in any nu+3er *9 *34ect# and y*u d*nt need t* !*rry a3*ut h*! 3ig t* +ake the c*ntainer !hile y*ure !riting the pr*gra+)

Introduction to data structures


C*ntainer cla##e# are *ne *9 the +*#t p*!er9ul t**l# 9*r ra! devel*p+ent 3ecau#e they pr*vide an entry int* the !*rld *9 data #tructure pr*gra++ing) =n intere#ting 9act *9 pr*gra++ing i# that the harde#t challenge# *9ten 3*il d*!n t* #electing a data #tructure and applying a hand9ul *9 #i+ple *perati*n# t* it) O34ect *rientati*n +ake# it trivial t* create data #tructure# that !*rk !ith a3#tract data type# Gi)e), a c*llecti*n cla## i# !ritten t* !*rk !ith type ob)ect and there3y !*rk# !ith everythingH)

Cha"ter '* >olding Eour 123ects

4)3

The ) ET Sy#te+)C*llecti*n# na+e#pace take# the i##ue *9 Ih*lding y*ur *34ect#J and divide# it int* t!* di#tinct c*ncept#1 0) BList1 a gr*up *9 individual ele+ent#, *9ten !ith #*+e rule applied t* the+) =n BList +u#t h*ld the ele+ent# in a particular #eDuence) , and a #et cann*t have any duplicate ele+ent#) G *te that the ) ET 5ra+e!*rk d*e# n*t #upply either a set, !hich i# a C*llecti*n !ith*ut duplicate#, n*r a 2ag, !hich i# an und*rdered C*llecti*n)H 2) B$ictionary1 a gr*up *9 keyEvalue *34ect pair# Gal#* called .a"sH) Strictly #peaking, an B$ictionary c*ntain# $ictionary&ntry #tructure#, !hich the+#elve# c*ntain the t!* re9erence# Gin the Eey and Halue pr*pertie#H) The Eey pr*perty cann*t 3e null and +u#t 3e uniDue, !hile the Halue entry +ay 3e null *r +ay p*int t* a previ*u#ly re9erenced *34ect) :*u can acce## any *9 the#e part# *9 the B$ictionary #tructure P y*u can get the $ictionary&ntry value#, the #et *9 Eey# *r the c*llecti*n *9 Halue#) ?icti*narie#, like array#, can ea#ily 3e e;panded t* +ultiple di+en#i*n# !ith*ut adding ne! c*ncept#1 y*u #i+ply +ake an B$ictionary !h*#e value# are *9 type B$ictionary Gand the value# *9 those dicti*narie# can 3e dicti*narie#, etc)H

Queues and 'tac*s


5*r #cheduling pr*3le+# and *ther pr*gra+# that need t* deal !ith ele+ent# in *rder, 3ut !hich !hen d*ne di#card *r handE*99 the ele+ent# t* *ther c*+p*nent#, y*ull !ant t* c*n#ide a Mueue *r a Stack) = Dueue i# a data #tructure !hich !*rk# like a line in a 3ankQ the 9ir#t t* arrive i# the 9ir#t t* 3e #erved) = #tack i# *9ten c*+pared t* a ca9eteria plateEdi#pen#er P the la#t *34ect t* 3e added i# the 9ir#t t* 3e acce##ed) Thi# e;a+ple u#e# thi# +etaph*r t* #h*! the 3a#ic 9uncti*n# *9 a Dueue and a #tack1 //:c0>:Queue)ndStac%.c# //:e!on#trate ti!e6of6arri*a u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 data #tructure#

4)4

Thinking in C

www.ThinkingIn.!et

c a## Cu#to!er; #tring na!e3 pu$ ic #tring Ca!e; get; return na!e3 < < - ate:i#pen#er p3 interna Cu#to!er0String na!e2 - ate:i#pen#er p1; thi#.na!e 9 na!e3 thi#.p 9 p3 < interna *oid _et- ate01; #tring p ate 9 p._et- ate013 Sy#te!.Con#o e.VriteLine0 na!e R & got & R p ate13 < < c a## - ate:i#pen#er; Stac% di#pen#er 9 ne. Stac%013 interna *oid Hi 0int i'o-u#h1; for0int i 9 03 i W i'o-u#h3 iRR1; #tring p 9 &- ate (& R i3 Sy#te!.Con#o e.VriteLine0&Loading & R p13 di#pen#er.-u#h0p13 < < interna #tring _et- ate01; return 0#tring1 di#pen#er.-op013 < < c a## 'e er; Queue ine 9 ne. Queue013 interna *oid +nterLine0Cu#to!er c1; ine.+n7ueue0c13 < interna *oid Chec%out01; Cu#to!er c 9 0Cu#to!er1 ine.:e7ueue013

Cha"ter '* >olding Eour 123ects

4)5

Sy#te!.Con#o e.VriteLine0 &Chec%ing out: & R c.Ca!e13 < < c a## Cafeteria; - ate:i#pen#er pd 9 ne. - ate:i#pen#er013 'e er t 9 ne. 'e er013 pu$ ic #tatic *oid Gain01; ne. Cafeteria013 < pu$ ic Cafeteria01; pd.Hi 0E13 Cu#to!erJK c 9 ne. Cu#to!erJEK3 for0int i 9 03 i W E3 iRR1; cJiK 9 ne. Cu#to!er0&Cu#to!er (& R i2 pd13 cJiK._et- ate013 < for0int i 9 03 i W E3 iRR1; t.+nterLine0cJiK13 < for0int i 9 03 i W E3 iRR1; t.Chec%out013 < < <///:8 5ir#t, the c*de #peci9ie# that it !ill 3e u#ing type# 9r*+ the Sy#te+ and Sy#te+)C*llecti*n na+e#pace#) Then, the Customer cla## ha# a na+e and a re9erence t* a !late$ispenser *34ect) The#e re9erence# are pa##ed in the Customer c*n#truct*r) 5inally, Customer6 et!late() retrieve# a plate 9r*+ the !late$ispenser and print# *ut the na+e *9 the cu#t*+er and the identi9ier *9 the plate) The !late$ispenser *34ect c*ntain# an internal re9erence t* a #tac() ,hen !late$ispenser6:ill() i# called, a uniDue #tring i# created and #tac(6!ush() place# it *n the t*p G*r 9r*ntH *9 the #tack) Si+ilarly, !late$ispenser6 et!late() u#e# #tac(6!op() t* get the *34ect at the #tack# t*p)

4)6

Thinking in C

www.ThinkingIn.!et

The +eller cla## ha# a re9erence t* a _ueue *34ect) +eller6&nterLine() call# _ueue6&n%ueue() and +eller6Chec(out() call# _ueue6$e%ueue()) Since the *nly *34ect# placed in the Dueue are *9 type Customer, it# #a9e 9*r the re9erence returned 3y _ueue6$e%ueue() t* 3e ca#t t* a Customer, and the na+e printed t* the C*n#*le) 5inally, the Cafeteria cla## 3ring# it all t*gether) -t c*ntain# a !late$ispenser and a +eller) The c*n#truct*r 9ill# the plate di#pen#er and create# #*+e cu#t*+er#, !h* get plate#, get in line 9*r the teller, and check *ut) The *utput l**k# like thi#1 Loading - ate (0 Loading - ate (" Loading - ate (2 Loading - ate (T Cu#to!er (0 got - ate (T Cu#to!er (" got - ate (2 Cu#to!er (2 got - ate (" Cu#to!er (T got - ate (0 Chec%ing out: Cu#to!er (0 Chec%ing out: Cu#to!er (" Chec%ing out: Cu#to!er (2 Chec%ing out: Cu#to!er (T =# y*u can #ee, the *rder in !hich the plate# are di#pen#ed i# the rever#e *9 the *rder in !hich they !ere placed in the !late$ispenser# #tac() ,hat happen# i9 y*u call !op() *r $e%ueue() *n an e+pty c*llecti*nF -n 3*th #ituati*n# y*ull get an Bnvalid1peration&xception !ith an e;plicit +e##age that the #tack *r Dueue i# e+pty) Stack# and Dueue# are 4u#t the thing 9*r #cheduling pr*3le+#, 3ut i9 y*u need t* ch**#e acce## *n +*re than a ti+eE*9Earrival 3a#i#, y*ull need an*ther data #tructure)

)rra5List
-9 a nu+eric inde; i# all y*u need, the 9ir#t thing that y*ull c*n#ider i# an =rray, *9 c*ur#e) But i9 y*u d*nt kn*! the e;act nu+3er *9 *34ect# that y*ull need t* #t*re, c*n#ider =rrayLi#t)

Cha"ter '* >olding Eour 123ects

4)#

Like the *ther c*llecti*n cla##e#, =rrayLi#t ha# #*+e very handy #tatic +eth*d# y*u can u#e !hen y*u !ant t* en#ure certain characteri#tic# *9 the underlying c*llecti*n) The #tatic +eth*d# 'rrayList6:ixed#iTe() and 'rrayList6*ead1nly() return their 'rrayList argu+ent# !rapped in #peciali7ed handle# that en9*rce the#e re#tricti*n#) H*!ever, care +u#t 3e taken t* di#card any re9erence# t* the *riginal argu+ent t* the#e +eth*d#, 3ecau#e the inner =rrayLi#t can get ar*und the re#tricti*n#, a# thi# e;a+ple #h*!#1 //:c0>:)rrayLi#tStatic#.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 pu$ ic c a## )rrayLi#tStatic#; pu$ ic #tatic *oid Gain01; )rrayLi#t a 9 ne. )rrayLi#t013 Rando! rand 9 ne. Rando!013 int i'o)dd 9 P0 R rand.Cext0P013 for0int i 9 03 i W i'o)dd3 iRR1; #tring # 9 &String (& R i3 a .)dd0#13 < )rrayLi#t noGore 9 )rrayLi#t.HixedSiMe0a 13 try; noGore.)dd0&'hi# .on't .or%&13 <catch0+xception ex1; Sy#te!.Con#o e.VriteLine0ex13 < )rrayLi#t untoucha$ e 9 )rrayLi#t.ReadOn y0a 13 try; untoucha$ eJ0K 9 &'hi# .on't .or%&3 <catch0+xception ex1; Sy#te!.Con#o e.VriteLine0ex13 < //But re#triction# do not app y to origina a J0K 9 &Godified&3 Sy#te!.Con#o e.VriteLine0 &Ontoucha$ eJ0K 9 & R untoucha$ eJ0K13 int origina Count 9 noGore.Count3 Sy#te!.Con#o e.VriteLine0

4)&

Thinking in C

www.ThinkingIn.!et

&SiMe of noGore ;0< !9 ;"<&2 origina Count2 noGore.Count13 < <///:8 ,hile the *perati*n# *n the !rapped array# !ill rai#e ,ot#upported&xceptions G!hich are caught and printed t* the c*n#*leH, a change t* the *riginal al =rrayLi#t i# re9lected in Vntouchable and the #i7e *9 no.ore can 3e increa#edK =n*ther intere#ting #tatic +eth*d *9 =rrayLi#t i# #ynchroniTed, !hich !ill 3e di#cu##ed in Chapter #threading#)

3it)rra5
= Bit'rray i# u#ed i9 y*u !ant t* e99iciently #t*re a l*t *9 *nE*99 *r trueE 9al#e in9*r+ati*n) -t# e99icient *nly 9r*+ the #tandp*int *9 #i7eQ i9 y*ure l**king 9*r e99icient acce##, it i# #lightly #l*!er than u#ing an array *9 #*+e native type) = n*r+al c*ntainer e;pand# a# y*u add +*re ele+ent#, 3ut !ith Bit'rray, y*u +u#t #et the Length pr*perty t* 3e #u99icient t* h*ld a# +any a# y*u need) The c*n#truct*r t* Bit'rray take# an integer !hich #peci9ie# the initial capacity Gthere are al#* c*n#truct*r# !hich c*py 9r*+ an e;i#ting Bit'rray, 9r*+ an array *9 3**l#, *r 9r*+ the 3itEvalue# *9 an array *9 3yte# *r int#H) The 9*ll*!ing e;a+ple #h*!# h*! the Bit'rray !*rk#1 //:c0>:Bit#.c# // :e!on#tration of BitSet. u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 pu$ ic c a## Bit# ; #tatic *oid -rintBit)rray0Bit)rray $1 ; Sy#te!.Con#o e.VriteLine0&$it#: & R $13 #tring $$it# 9 &&3 for 0int D 9 03 D W $.Length 3 DRR1 $$it# R9 0$JDK Y &"& : &0&13 Sy#te!.Con#o e.VriteLine0 &$it pattern: & R $$it#13

Cha"ter '* >olding Eour 123ects

4)'

< pu$ ic #tatic *oid Gain01 ; Rando! rand 9 ne. Rando!013 // 'a%e the LSB of Cext01: $yte $t 9 0$yte1rand.Cext013 Bit)rray $$ 9 ne. Bit)rray0I13 for 0int i 9 F3 i Z903 i661 if 000" WW i1 @ $t1 !9 01 $$.Set0i2 true13 e #e $$.Set0i2 fa #e13 Sy#te!.Con#o e.VriteLine0&$yte *a ue: & R $t13 -rintBit)rray0$$13 #hort #t 9 0#hort1rand.Cext013 Bit)rray $# 9 ne. Bit)rray0"?13 for 0int i 9 "P3 i Z903 i661 if 000" WW i1 @ #t1 !9 01 $#.Set0i2 true13 e #e $#.Set0i2 fa #e13 Sy#te!.Con#o e.VriteLine0&#hort *a ue: & R #t13 -rintBit)rray0$#13 int it 9 rand.Cext013 Bit)rray $i 9 ne. Bit)rray0T213 for 0int i 9 T"3 i Z903 i661 if 000" WW i1 @ it1 !9 01 $i.Set0i2 true13 e #e $i.Set0i2 fa #e13 Sy#te!.Con#o e.VriteLine0&int *a ue: & R it13 -rintBit)rray0$i13 // 'e#t Bit)rray# that gro.: Bit)rray $"2F 9 ne. Bit)rray0?E13 //! Vou d thro. )rgu!entOutOfRange+xception //! $"2F.Set0"2F2 true13 //Gu#t !anua y expand the Length $"2F.Length 9 "2I3 $"2F.Set0"2F2 true13

43(

Thinking in C

www.ThinkingIn.!et

Sy#te!.Con#o e.VriteLine0 &#et $it "2F: & R $"2F13 < < ///:8

4ictionaries
?icti*narie# all*! y*u t* rapidly l**k up a value 3a#ed *n a uniDue n*nE nu+eric key and are a+*ng the +*#t handy *9 the c*llecti*n cla##e#)

9ashta+le
The "ashtable i# #* c*++*nly u#ed that +any pr*gra++er# u#e the phra#e interchangea3ly !ith the c*ncept *9 a dicti*naryK The Ha#hta3le, th*ugh, i# an i+ple+entati*n *9 B$ictionary that ha# all type# *9 intere#ting i+ple+entati*n detail#) Be9*re !e get t* th*#e, here# a #i+ple e;a+ple *9 u#ing a "ashtable1 //:c0>:Si!p eUa#h.c# u#ing Sy#te!.Co ection#3 pu$ ic c a## Larry#-et# ; #tatic 5:ictionary Hi 05:ictionary d1 ; d.)dd0&dog&2 &Cheyenne&13 // Con6uni7ue %ey cau#e# exception //! d.)dd0&dog&2 &Bette&13 d.)dd0&cat&2 &Uarry&13 d.)dd0&go dfi#h&2 nu 13 return d3 < pu$ ic #tatic *oid Gain01 ; 5:ictionary pet# 9 ne. Ua#hta$ e013 Hi 0pet#13 foreach0:ictionary+ntry pet in pet#1; Sy#te!.Con#o e.VriteLine0 &Larry ha# a ;0< na!ed ;"<&2 pet.aey2 pet.Na ue13 < < < ///:8

Cha"ter '* >olding Eour 123ects

431

pr*duce# *utput *91 Larry ha# a dog na!ed Cheyenne Larry ha# a go dfi#h na!ed Larry ha# a cat na!ed Uarry *te that atte+pting t* add a n*nEuniDue key t* a "ashtable rai#e# an 'rgument&xception6 Thi# d*e# n*t +ean that *ne cann*t change the value *9 a Ha#hta3le at a given key, th*ugh1 //:c0>:ChangeUa#hta$ eNa ue.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 c a## ChangeUa#hta$ eNa ue; pu$ ic #tatic *oid Gain01; Ua#hta$ e h 9 ne. Ua#hta$ e013 h.)dd0&Hoo&2&Bar&13 O$Dect o 9 hJ&Hoo&K3 hJ&Hoo&K 9 &Godified&3 Sy#te!.Con#o e.VriteLine0&Na ue i#: & R hJ&Hoo&K13 hJ&BaM&K 9 &BoMo&3 < <///:8 Thi# e;a+ple #h*!# the u#e *9 C## custom inde%ers) = cu#t*+ inde;er all*!# *ne t* acce## an B$ictionary u#ing n*r+al array n*tati*n) =lth*ugh here !e u#e *nly string# a# the key#, the key# in an B$ictionary can 3e *9 any type and can 3e +i;ed and +atch a# nece##ary) =9ter I5**J i# #et a# the key t* the IBarJ value, array n*tati*n can 3e u#ed t* acce## the value, 9*r 3*th reading and !riting) =# #h*!n in the la#t line *9 .ain(), the #a+e array n*tati*n can 3e u#ed t* add ne! keyEvalue pair# t* the Ha#hta3le) The +*#t intere#ting Ha#hta3le i+ple+entati*n detail ha# t* d* !ith the calculati*n *9 the ha#hc*de, a uniDue integer !hich I#*+eh*!J identi9ie# the key# uniDue value) The ha#hc*de i# returned 3y ob)ect6 et"ashCode(), a +eth*d that need# t* 3e 9a#t and t* return integer# that are I#pread *utJ a# +uch a# p*##i3le) =dditi*nally, the +eth*d +u#t al!ay# return the #a+e value 9*r a given *34ect, #* y*u cant

43)

Thinking in C

www.ThinkingIn.!et

3a#e y*ur ha#hc*de *n thing# like #y#te+ ti+e) -n thi# e;a+ple, the ha#hc*de and the related ob)ect6&%uals() +eth*d are u#ed t* e;pre## the idea that the #*le deter+inant *9 a circle# identity i# it# center and radiu# 1 //:c0>:O*erridingUa#h.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 c a## Circ e; int x2 y2 radiu#3 interna Circ e0int x2 int y2 int radiu#1; thi#.x 9 x3 thi#.y 9 y3 thi#.radiu# 9 radiu#3 < interna Circ e0int top,2 int top/2 int o.er,2 int o.er/1; thi#.x 9 top, R 0 o.er, 6 top,1 / 23 thi#.y 9 top/ R 0 o.er/ 6 top/1 / 23 thi#.radiu# 9 0 o.er, 6 top,1 / 23 < pu$ ic o*erride int _etUa#hCode01; Sy#te!.Con#o e.VriteLine0 &Returning ;0<&2 x R y R radiu#13 return x R y R radiu#3 < pu$ ic o*erride $oo +7ua #0O$Dect o1; if0o i# Circ e1; Circ e that 9 0Circ e1 o3 Sy#te!.Con#o e.VriteLine0 &Co!paring ;0<2;"<2;2< .ith & R &;T<2;E<2;P<&2 x2 y2 radiu#2 that.x2 that.y2 that.radiu#13 return 0thi#.x 99 that.x1 @@ 0thi#.y 99 that.y1 @@ 0thi#.radiu# 99 that.radiu#13 < return fa #e3

Cha"ter '* >olding Eour 123ects

433

< pu$ ic #tatic *oid Gain01; Circ e c 9 ne. Circ e0"P2 "P2 P13 Circ e un i%e 9 ne. Circ e0"P2 "P2 ?13 Circ e #o!e.hatLi%e 9 ne. Circ e0T02 "2 E13 5:ictionary d 9 ne. Ua#hta$ e013 d.)dd0c2 &) circ e&13 d.)dd0un i%e2 &)nother circ e&13 try; Circ e i%e 9 ne. Circ e0"02 "02 202 2013 d.)dd0 i%e2 &`u#t i%e c&13 <catch0+xception ex1; Sy#te!.Con#o e.VriteLine0ex13 < < <///:8 ,hen a Circle i# added t* a "ashtable, the Ha#hta3le call# 3ack t* Circle6 et"ashCode() !hich return# the #u+ *9 the center c**rdinate# and radiu# *9 the circle) Thi# i# n* pr*3le+ 9*r the 9ir#t t!* circle#, c and unli(e, 3ecau#e they have di99erent ha#hc*de#) Circle somewhatLi(e th*ugh, cau#e# !hat i# called a Iha#h c*lli#i*nJ P the #a+e ha#hc*de i# returned 9*r t!* di99erent *34ect# Gin thi# ca#e, 3*th circle# ele+ent# add up t* /'H) ,hen a ha#h c*lli#i*n take# place, "ashtable cau#e# ob)ect6&%uals() t* #ee i9 the *34ect# are, in 9act, the #a+e *34ect) Becau#e the#e t!* circle# have di99erent center# and radii, they can 3*th 3e added t* the "ashtable) Ha#h c*lli#i*n# #eri*u#ly inter9ere !ith the e99iciency *9 the "ashtable, #* 9reDuent c*lli#i*n# #h*uld +ake y*u revi#it y*ur ha#hc*de alg*rith+) -n the try 3l*ck, !e create an*ther ne! Circle, thi# ti+e u#ing an alternate c*n#truct*r) ,hen it# added t* the "ashtable, thi# ti+e there# an*ther c*lli#i*n, 3ut thi# ti+e Circle6&%uals() reveal# that ye#, c and li(e are l*gically eDuivalent and there9*re "ashtable thr*!# an 'rgument&xception)

List4ictionar5
-9 y*u have *nly a d*7en *r 9e!er *34ect# t* #t*re in y*ur ?icti*nary, List$ictionary !ill have 3etter per9*r+ance than a "ashtable) On the

434

Thinking in C

www.ThinkingIn.!et

*ther hand, *n larger a+*unt# *9 *34ect#, List$ictionary ha# +uch, much !*r#e per9*r+ance and the per9*r+ance *9 a c*llecti*n cla## !ith a #+all nu+3er *9 ele+ent# i# unlikely t* 3e a h*t#p*t in an applicati*n) -t# n*t i+p*##i3le, th*ughK S* i9 y*uve g*t a dicti*nary !ith a #+all a+*unt *9 *34ect# and it# 3uried in the central l**p in y*ur applicati*n, List$ictionary +ight c*+e in handy) Other!i#e, g* !ith "ashtable)

'ortedList
S*+eti+e#, y*u need t* acce## a C*llecti*n in t!* di99erent !ay#1 keyE 3a#ed l**kup 9*r *ne purp*#e, and inde;E3a#ed l**kup 9*r an*ther) The S*rtedLi#t pr*vide# thi# dualE+*de capa3ility1 //:c0>:Sho.SortedLi#t.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 c a## Sho.SortedLi#t; SortedLi#t !onthLi#t 9 ne. SortedLi#t013 Sho.SortedLi#t01; !onthLi#t.)dd0&`anuary&2 T"13 !onthLi#t.)dd0&He$ruary&22I.2P13 !onthLi#t.)dd0&Garch&2 T"13 !onthLi#t.)dd0&)pri &2 T013 !onthLi#t.)dd0&Gay&2 T"13 !onthLi#t.)dd0&`une&2 T013 !onthLi#t.)dd0&`u y&2 T"13 !onthLi#t.)dd0&)ugu#t&2 T"13 !onthLi#t.)dd0&Septe!$er&2T013 !onthLi#t.)dd0&Octo$er&2T"13 !onthLi#t.)dd0&Co*e!$er&2T013 !onthLi#t.)dd0&:ece!$er&2T"13 Sy#te!.Con#o e.VriteLine0 &`une ha# ;0< day#&2 !onthLi#tJ&`une&K13 Sy#te!.Con#o e.VriteLine0 &'he eighth !onth ha# ;0< day#&2 !onthLi#t._etBy5ndex0F113 < pu$ ic #tatic *oid Gain01;

Cha"ter '* >olding Eour 123ects

435

Sho.SortedLi#t ## 9 ne. Sho.SortedLi#t013 < <///:8 The #ortedList can 3e acce##ed u#ing any *34ect *9 the key type, in thi# ca#e string#) Or, etByBndexGH can 3e u#ed t* retrieve a value 3a#ed *n a nu+eric inde;)

'tring s$ecialists
String# are certainly the +*#t u#ed type 9*r key# and value#, and the ) ET 5ra+e!*rk pr*vide# a nu+3er *9 #peciali7ed c*llecti*n# that !*rk e;clu#ively !ith #tring#) The#e c*llecti*n# can 3e 9*und in the #ystem6Collections6#pecialiTed na+e#pace)

One Re5. @ulti$le 8alues


The ,ameHalueCollection #erve# 9*r th*#e #ituati*n# !hen y*u !ant t* a##*ciate a #ingle key string !ith +ultiple string value#1 //:c0>:Gonth#.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#.Specia iMed3 c a## Gonth#; pu$ ic #tatic *oid Gain01; Ca!eNa ueCo ection !onth# 9 ne. Ca!eNa ueCo ection013 !onth#.)dd0&Vinter&2 &`anuary&13 !onth#.)dd0&Vinter&2 &He$ruary&13 !onth#.)dd0&.inter&2 &:ece!$er&13 !onth#.)dd0&Spring&2 &Garch&13 !onth#.)dd0&Spring&2 &)pri &13 !onth#.)dd0&Spring&2 &Gay&13 foreach0#tring %ey in !onth#.) aey#1; Sy#te!.Con#o e.VriteLine0&aey: & R %ey13 Sy#te!.Con#o e.VriteLine0&CSN: & R !onth#J%eyK13 foreach0O$Dect *a ue in !onth#._etNa ue#0%ey11; Sy#te!.Con#o e.VriteLine0 &^tNa ue: & R *a ue13

436

Thinking in C

www.ThinkingIn.!et

< < < <///:8 The *utput *9 the pr*gra+ i# #h*!n here1 aey: Vinter CSN: `anuary2He$ruary2:ece!$er Na ue: `anuary Na ue: He$ruary Na ue: :ece!$er aey: Spring CSN: Garch2)pri 2Gay Na ue: Garch Na ue: )pri Na ue: Gay -n a rather #trange de#ign deci#i*n, the cu#t*+ inde;er and the et() +eth*d return the value# a# a #ingle c*++aE#eparated #tring rather than a# an array) -9 y*u !ant t* acce## the value# a# a #tring array, y*u have t* u#e the etHalues() +eth*d)

Custo#i:ing 9ashcode Providers


*te that in the previ*u# A*nth# pr*gra+, the I?ece+3erJ value !a# added 9*r the key I!interJ a# *pp*#ed t* I"anuaryJ and I5e3ruaryJ !hich u#ed the key I,interJ) -n the di#cu##i*n *9 "ashtable, !e #h*!ed h*! a cla## c*uld *verride it# et"ashCode() and &%uals() +eth*d# t* c*ntr*l place+ent in a "ashtable) Even +*re cu#t*+i7ati*n i# p*##i3le 3y changing the #trategy that the "ashtable *r ,ameHalueCollection u#e# t* calculate eDualityQ thi# can 3e d*ne 3y creating the dicti*nary !ith a cu#t*+ B"ashCode!rovider and BComparer) By de9ault, ,ameHalueCollection u#e# a CaseBnsensitive"ashcode!rovider and CaseBnsensitiveComparer t* deter+ine !hat 9it# int* !hat #l*t) Thi# pr*gra+ de+*n#trate# the creati*n *9 a cu#t*+ BComparer and B"ashCode!rovider t* create a ha#hta3le !hich #t*re# *nly the la#t even *r *dd integer added Gn*te that thi# i# certainly Ithe +*#t c*+plicated thing that c*uld p*##i3ly !*rkJH1 //:c0>:+*enOdd.c#

Cha"ter '* >olding Eour 123ects

43#

u#ing Sy#te!3 u#ing Sy#te!.Co

ection#3

c a## +*enOddCo!parer : 5Co!parer; pu$ ic int Co!pare0O$Dect x2 O$Dect y1; //On y co!pare integer# if 0x i# 5ntT2 99 fa #e SS y i# 5ntT2 99 fa #e1; thro. ne. )rgu!ent+xception0 &Can't co!pare non65ntT2'#&13 < //On$ox input# int xNa ue 9 0int1 x3 int yNa ue 9 0int1 y3 if 0xNa ue [ 2 99 yNa ue [ 21 ; return 03 < return 6"3 < < c a## +*enOddUa#hCode-ro*ider : 5Ua#hCode-ro*ider; pu$ ic int _etUa#hCode0O$Dect intO$D1; //On y ha#h integer# if0intO$D i# 5ntT2 99 fa #e1; thro. ne. )rgu!ent+xception0 &Can't ha#h non65ntT2'#&13 < //On$ox input int x 9 0int1 intO$D3 return x [ 23 < < c a## +*enOdd; #tatic +*enOddCo!parer c 9 ne. +*enOddCo!parer013 #tatic +*enOddUa#hCode-ro*ider p 9 ne. +*enOddUa#hCode-ro*ider013 //Ua#hta$ e %ey# #tatic readon y int +N+CXa+/ 9 23

43&

Thinking in C

www.ThinkingIn.!et

#tatic readon y int O::Xa+/ 9 T3 //Cu#to! 5Co!parer @ 5Ua#hCode-ro*ider #trategie# Ua#hta$ e e*enOdd 9 ne. Ua#hta$ e0p2 c13 pu$ ic *oid 'e#t01; e*enOddJ+N+CXa+/K 9 23 e*enOddJO::Xa+/K 9 T3 e*enOddJ+N+CXa+/K 9 E3 Sy#te!.Con#o e.VriteLine0 &'he a#t e*en nu!$er added .a#: & R e*enOddJ+N+CXa+/K13 Sy#te!.Con#o e.VriteLine0 &'he a#t odd nu!$er added .a#: & R e*enOddJO::Xa+/K13 < pu$ ic #tatic *oid Gain01; +*enOdd eo 9 ne. +*enOdd013 eo.'e#t013 < <

'tring s$ecialists, 'tringCollection and 'tring4ictionar5


-9 y*u *nly !ant t* #t*re #tring#, #tringCollection and #tring$ictionary are +arginally +*re e99icient than their generic c*unterpart#) = #tringCollection i+ple+ent# BList and #tring$ictionary naturally i+ple+ent# B$ictionary) B*th the key# and value# in #tring$ictionary +u#t 3e #tring#, and the key# are ca#eE in#en#itive and #t*red in l*!erEca#e 9*r+) Here# a dra+atically a3ridged dicti*nary pr*gra+1 //:c0>:Ve$#ter#)$ridged.c# u#ing Sy#te!3

Cha"ter '* >olding Eour 123ects

43'

u#ing Sy#te!.Co

ection#.Specia iMed3

c a## Ve$#ter#)$ridged; #tatic String:ictionary #d 9 ne. String:ictionary013 #tatic Ve$#ter#)$ridged01; #dJ&aa!&K 9 &) !ea#ure of i7uid# a!ong the :utch&3 #dJ&Mythu!&K 9 &Ga t $e*erage $re.ed $y ancient +gyptian#&3 < pu$ ic #tatic *oid Gain0#tringJK arg#1; foreach0#tring arg in arg#1; if0#d.Contain#aey0arg11; Sy#te!.Con#o e.VriteLine0#dJargK13 <e #e; Sy#te!.Con#o e.VriteLine0 &5 don't %no. that .ord&13 < < < < The pr*gra+ iterate# *ver the c*++andEline argu+ent# and either return# the de9initi*n *r ad+it# de9eat) Becau#e the #tring$ictionary i# ca#eEin#en#itive, thi# pr*gra+ i# highly u#e9ul even !hen the C=PS LOCN key *n the key3*ard i# le9t turned *n)

Container disadvantage, un*nown t5$e


=#ide 9r*+ #tringCollection and #tring$ictionary, ) ET# c*llecti*n cla##e# have the Idi#advantageJ *9 *3#curing type in9*r+ati*n !hen y*u put an *34ect int* a c*ntainer) Thi# happen# 3ecau#e the pr*gra++er *9 that c*ntainer cla## had n* idea !hat #peci9ic type y*u !anted t* put in the c*ntainer, and +aking the c*ntainer h*ld *nly y*ur type !*uld prevent it 9r*+ 3eing a generalEpurp*#e t**l) S* in#tead, the c*ntainer

44(

Thinking in C

www.ThinkingIn.!et

h*ld# re9erence# t* ob)ect, !hich i# the r**t *9 all the cla##e# #* it h*ld# any type) Thi# i# a great #*luti*n, e;cept1 0) Since the type in9*r+ati*n i# *3#cured !hen y*u put an *34ect re9erence int* a c*ntainer, there# n* re#tricti*n *n the type *9 *34ect that can 3e put int* y*ur c*ntainer, even i9 y*u +ean it t* h*ld *nly, #ay, cat#) S*+e*ne c*uld 4u#t a# ea#ily put a d*g int* the c*ntainer) 2) Since the type in9*r+ati*n i# *3#cured, the *nly thing the c*ntainer kn*!# that it h*ld# i# a re9erence t* an ob)ect) :*u +u#t per9*r+ a ca#t t* the c*rrect type 3e9*re y*u u#e it) On the up #ide, C# !*nt let y*u misuse the *34ect# that y*u put int* a c*ntainer) -9 y*u thr*! a d*g int* a c*ntainer *9 cat# and then try t* treat everything in the c*ntainer a# a cat, y*ull get a runEti+e e;cepti*n !hen y*u pull the d*g re9erence *ut *9 the cat c*ntainer and try t* ca#t it t* a cat) Here# an e;a+ple u#ing the 3a#ic !*rkh*r#e c*ntainer, 'rrayList) 5ir#t, Cat and $og cla##e# are created1 //: c0>:Cat.c# na!e#pace pet#; pu$ ic c a## Cat ; pri*ate int catCu!$er3 interna Cat0int i1 ; catCu!$er 9 i3< interna *oid -rint01 ; Sy#te!.Con#o e.VriteLine0 &Cat (& R catCu!$er13 < < < ///:8 //: c0>::og.c# na!e#pace pet#; pu$ ic c a## :og ; pri*ate int dogCu!$er3 interna :og0int i1 ; dogCu!$er 9 i3< interna *oid -rint01 ; Sy#te!.Con#o e.VriteLine0 &:og (& R dogCu!$er13

Cha"ter '* >olding Eour 123ects

441

< < < ///:8 Cat# and $og# are placed int* the c*ntainer, then pulled *ut1 //: c0>:Cat#)nd:og#.c# // Co!pi e .ith: c#c Cat.c# :og.c# Cat#)nd:og#.c# // Si!p e container exa!p e. u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 na!e#pace pet#; pu$ ic c a## Cat#)nd:og# ; pu$ ic #tatic *oid Gain01 ; )rrayLi#t cat# 9 ne. )rrayLi#t013 for 0int i 9 03 i W F3 iRR1 cat#.)dd0ne. Cat0i113 // Cot a pro$ e! to add a dog to cat#: cat#.)dd0ne. :og0F113 for 0int i 9 03 i W cat#.Count3 iRR1 00Cat1cat#JiK1.-rint013 // :og i# detected on y at run6ti!e < < <///:8 The cla##e# Cat and $og are di#tinctRthey have n*thing in c*++*n e;cept that they are ob)ect#) G-9 y*u d*nt e;plicitly #ay !hat cla## y*ure inheriting 9r*+, y*u aut*+atically inherit 9r*+ ob)ect)H Since 'rrayList h*ld# ob)ect#, y*u can n*t *nly put Cat *34ect# int* thi# c*ntainer u#ing the 'rrayList +eth*d 'dd( ), 3ut y*u can al#* add $og *34ect# !ith*ut c*+plaint at either c*+pileEti+e *r runEti+e) ,hen y*u g* t* 9etch *ut !hat y*u think are Cat *34ect# u#ing the 'rrayList inde;er, y*u get 3ack a re9erence t* an ob)ect) Since the intent !a# that cats #h*uld *nly c*ntain 9eline#, there i# n* check +ade 3e9*re ca#ting the returned value t* a Cat) Since !e !ant t* call the !rint() +eth*d *9 Cat, !e have t* 9*rce the evaluati*n *9 the ca#t t* happen 9ir#t, #* !e #urr*und the e;pre##i*n in parenthe#e# 3e9*re calling !rint( )) =t runE

44)

Thinking in C

www.ThinkingIn.!et

ti+e, th*ugh, !hen the l**p trie# t* ca#t the $og *34ect t* a Cat, it thr*!# a ClassCast&xception) Thi# i# +*re than 4u#t an ann*yance) -t# #*+ething that can create di99icultEt*E9ind 3ug#) -9 *ne part G*r #everal part#H *9 a pr*gra+ in#ert# *34ect# int* a c*ntainer, and y*u di#c*ver *nly in a #eparate part *9 the pr*gra+ thr*ugh an e;cepti*n that a 3ad *34ect !a# placed in the c*ntainer, then y*u +u#t 9ind *ut !here the 3ad in#ert *ccurred) On the up#ide, it# c*nvenient t* #tart !ith #*+e #tandardi7ed c*ntainer cla##e# 9*r pr*gra++ing, de#pite the #carcity and a!k!ardne##)

>sing Collection"ase to #a*e t5$e;conscious collections


=# +enti*ned at the 3eginning *9 the chapter, the ) ET runti+e !ill eventually natively #upp*rt typed c*llecti*n#) -n the +eanti+e, there# CollectionBase, an a3#tract BList that can 3e u#ed a# the 3a#i# 9*r !riting a #tr*ngly typed c*llecti*n) T* i+ple+ent a typed BList, *ne #tart# 3y creating a ne! type that inherit# 9r*+ C*llecti*nBa#e) Then, *ne ha# t* i+ple+ent BCollection6Copy+o(), BList6'dd(), BList6Contains(), BList6Bndex1f(), BList6Bnsert(), and BList6*emove() !ith typeE #peci9ic #ignature#) The c*de i# #traight9*r!ardQ the CollectionBase6List pr*perty i# initiali7ed in the 3a#eEcla## c*n#truct*r and all y*ur c*de ha# t* d* i# pa## y*ur #tr*nglyEtyped argu+ent# *n t* CollectionBase6List# ob)ectEaccepting +eth*d# and ca#ting the List# ob)ectEreturning +eth*d# t* 3e +*re #tr*ngly typed1 //:c0>:CatLi#t.c# //)n IList that contain# on y Cat# u#ing Sy#te!3 u#ing Sy#te!.Co na!e#pace pet#; c a## CatLi#t : Co ectionBa#e ; pu$ ic Cat thi#Jint indexK; get; return0Cat1 Li#tJindexK3< #et; Li#tJindexK 9 *a ue3< ection#3

Cha"ter '* >olding Eour 123ects

443

< pu$ ic int )dd0Cat fe ine1; return Li#t.)dd0fe ine13 < pu$ ic *oid 5n#ert0int index2 Cat fe ine1; Li#t.5n#ert0index2 fe ine13 < pu$ ic int 5ndexOf0Cat fe ine1; return Li#t.5ndexOf0fe ine13 < pu$ ic $oo Contain#0Cat fe ine1; return Li#t.Contain#0fe ine13 < pu$ ic *oid Re!o*e0Cat fe ine1; Li#t.Re!o*e0fe ine13 < pu$ ic *oid Copy'o0CatJK array2 int index1; Li#t.Copy'o0array2 index13 < pu$ ic #tatic *oid Gain01; CatLi#t c 9 ne. CatLi#t013 for 0int i 9 03 i W T3 iRR1 ; c .)dd0ne. Cat0i113 < //! Can't )dd0dog13 //! c .)dd0ne. :og0E113 < < <///:8 *te that i9 CatList had inherited directly 9r*+ 'rrayList, the +eth*d# that take re9erence# t* Cat#, #uch a# 'dd(Cat) !*uld #i+ply *verl*ad Gn*t *verrideH the ob)ectEaccepting +eth*d# Ge)g), 'dd( ob)ect) !*uld #till 3e availa3leH) Thu#, the CatList 3ec*+e# a surrogate t* the 'rrayList, per9*r+ing #*+e activitie# 3e9*re pa##ing *n the

444

Thinking in C

www.ThinkingIn.!et

re#p*n#i3ility G#ee Thinking in /atterns with ,a-a, d*!nl*ada3le at www.BruceEckel.comH) Becau#e a CatList !ill accept *nly a Cat, the line1 c .add0ne. :og0E113 !ill generate an err*r +e##age at com"ile9time) Thi# appr*ach, !hile +*re tedi*u# 9r*+ a c*ding #tandp*int, !ill tell y*u i++ediately i9 y*ure u#ing a type i+pr*perly) *te that n* ca#t i# nece##ary !hen u#ing it# al!ay# a Cat) et( ) *r the cu#t*+ inde;er R

I%nu#erators
-n any c*ntainer cla##, y*u +u#t have a !ay t* put thing# in and a !ay t* get thing# *ut) =9ter all, that# the pri+ary 4*3 *9 a c*ntainerRt* h*ld thing#) -n the 'rrayList, 'dd( ) and et( ) are *ne #et *9 !ay# t* in#ert and retrieve *34ect#) 'rrayList i# Duite 9le;i3leRy*u can #elect anything at any ti+e, and #elect +ultiple ele+ent# at *nce u#ing di99erent inde;e#) -9 y*u !ant t* #tart thinking at a higher level, there# a dra!3ack1 y*u need t* kn*! the e;act type *9 the c*ntainer in *rder t* u#e it) Thi# +ight n*t #ee+ 3ad at 9ir#t, 3ut !hat i9 y*u #tart *ut u#ing an 'rrayList, and later *n in y*ur pr*gra+ y*u decide that 3ecau#e *9 the !ay y*u are u#ing the c*ntainer, y*ud like t* #!itch y*ur c*de t* u#e a typed c*llecti*n de#cending 9r*+ CollectionBaseF Or #upp*#e y*ud like t* !rite a piece *9 generic c*de that d*e#nt kn*! *r care !hat type *9 c*ntainer it# !*rking !ith, #* that it c*uld 3e u#ed *n di99erent type# *9 c*ntainer# !ith*ut re!riting that c*deF The c*ncept *9 an enumerator G*r iteratorH can 3e u#ed t* achieve thi# a3#tracti*n) =n enu+erat*r i# an *34ect !h*#e 4*3 i# t* +*ve thr*ugh a #eDuence *9 *34ect# and #elect each *34ect in that #eDuence !ith*ut the client pr*gra++er kn*!ing *r caring a3*ut the underlying #tructure *9 that #eDuence) -n additi*n, an enu+erat*r i# u#ually !hat# called a IlightE !eightJ *34ect1 *ne that# cheap t* create) 5*r that rea#*n, y*ull *9ten

Cha"ter '* >olding Eour 123ects

445

9ind #ee+ingly #trange c*n#traint# 9*r enu+erat*r#Q 9*r e;a+ple, #*+e iterat*r# can +*ve in *nly *ne directi*n) The ) ET B&numerator inter9ace i# an e;a+ple *9 the#e kind# *9 c*n#traint#) There# n*t +uch y*u can d* !ith *ne e;cept1 0) =#k a c*llecti*n G*r any *ther type that i+ple+ent# -Enu+era3leH t* hand y*u an B&numerator u#ing a +eth*d called et&numerator( )) Thi# B&numerator !ill 3e ready t* +*ve t* the 9ir#t ele+ent in the #eDuence *n y*ur 9ir#t call t* it# .ove,ext( ) +eth*d) 2) >et the current *34ect in the #eDuence !ith the Current pr*perty) /) =tte+pt t* +*ve t* the ne;t *34ect in #eDuence !ith the .ove,ext() +eth*d) -9 the enu+erat*r ha# reached the end *9 the #eDuence, thi# +eth*d return# false) &) Re#et t* it# initial #tate, !hich i# "rior t* the 9ir#t ele+ent Ge)g), y*u +u#t call .ove,ext() *nce 3e9*re reading the Current pr*pertyH) That# all) -t# a #i+ple i+ple+entati*n *9 an iterat*r, 3ut #till p*!er9ul) T* #ee h*! it !*rk#, let# revi#it the Cats'nd$ogs6cs pr*gra+ 9r*+ earlier in thi# chapter) -n the 9*ll*!ing +*di9ied ver#i*n, !eve re+*ved the errant d*g and u#e an B&numerator t* iterate *ver the li#t# c*ntent#1 //: c0>:Cat#)nd:og#2.c# // O#ing an exp icit 5+nu!erator u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 na!e#pace pet#; pu$ ic c a## Cat#)nd:og# ; pu$ ic #tatic *oid Gain01 ; )rrayLi#t cat# 9 ne. )rrayLi#t013 for 0int i 9 03 i W F3 iRR1 cat#.)dd0ne. Cat0i113 5+nu!erator e 9 cat#._et+nu!erator013 .hi e0e.Go*eCext01 !9 fa #e1; O$Dect c 9 e.Current3 00Cat1 c1.-rint013

446

Thinking in C

www.ThinkingIn.!et

< < < <///:8 :*u can #ee that the la#t 9e! line# n*! u#e an B&numerator t* #tep thr*ugh the #eDuence in#tead *9 a for l**p) ,ith the B&numerator, y*u d*nt need t* !*rry a3*ut the nu+3er *9 ele+ent# in the c*ntainer) Behind the #cene#, C## foreach() 3l*ck# d* an even 3etter 4*3 *9 iterating *ver an B&numerable type, #ince the foreach atte+pt# t* ca#t the ob)ect re9erence returned 9r*+ the enu+erat*r t* a #peci9ic type) -t d*e#nt +ake a l*t *9 #en#e t* u#e an B&numerator !hen y*u can u#e1 foreach0Cat c in cat#1; c.-rint013 <

Custo# Inde&ers
Previ*u#ly, !e #a! h*! B$ictionary type# all*! *ne t* u#e inde; n*tati*n t* acce## keyEvalue pair# u#ing n*nEnu+eric indice#) Thi# i# d*ne 3y u#ing *perat*r *verl*ading t* create a cu#t*+ inde;er) The typeE#a9e CatList c*llecti*n #h*!n in the di#cu##i*n *9 CollectionBase #h*!ed a cu#t*+ inde;er that t**k a nu+eric inde;, 3ut returned a Cat in#tead *9 an ob)ect re9erence) :*u can +anipulate 3*th inde; and return type# in a cu#t*+ inde;er, 4u#t a# !ith any *ther C# +eth*d) 5*r in#tance, i+agine a Aa7e !hich c*n#i#t# *9 R**+# c*nnected 3y C*rrid*r# in the R**+# !all#) -n #uch a #ituati*n, it +ight +ake #en#e t* have the C*rrid*r# 3e inde;ed 3y directi*n in the r**+1 //:c0>:Roo!.c# u#ing Sy#te!3 u#ing Sy#te!.Co

ection#3

na!e#pace La$yrinth; enu! :irection ; north2 #outh2 ea#t2 .e#t

Cha"ter '* >olding Eour 123ects

44#

<3 c a## Roo! ; #tatic int counter 9 03 protected #tring na!e3 interna #tring Ca!e; get; return na!e3< < pu$ ic o*erride #tring 'oString01; return thi#.Ca!e3 < interna Roo!01; na!e 9 &Roo! (:& R counterRR3 < CorridorJK c 9 ne. CorridorJ +nu!._etNa ue#0typeof0:irection11.LengthK3 pu$ ic Corridor thi#J:irection dK; get ; return cJ0int1 dK3< #et ; cJ0int1 dK 9 *a ue3< < < c a## RegenSpot : Roo! ; interna RegenSpot01 : $a#e01; na!e 9 &Regen Spot&3 < < c a## -o.erOp : Roo! ; interna -o.erOp01 : $a#e01; na!e 9 &-o.er Op&3 < < <///:8 5ir#t, !e declare a $irection enu+erati*n c*rre#p*nding t* the cardinal p*int#) Then !e declare a R**+ cla## !ith an internal #tatic c*unter u#ed t* give each r**+ a uniDue na+e) The na+e i# +ade int* a pr*perty and i# al#* u#ed t* *verride the +o#tring() +eth*d t* 3e a little +*re #peci9ic a# t* the e;act r**+ !ere dealing !ith)

44&

Thinking in C

www.ThinkingIn.!et

Every *oom ha# an array called c that !ill h*ld re9erence# t* it# *ut3*und Corridors) =lth*ugh it !*uld 3e #h*rter t* 4u#t declare thi# array a# #i7e & G#ince !e kn*! that# h*! +any $irection# there areH, in#tead !e deter+ine the length *9 $irection 3y 9ir#t u#ing the #tatic +eth*d &num6 etHalues(), pa##ing it the $irection enu+erati*n# type, and then u#ing the Length pr*perty *9 the re#ulting array Gthi# !ay, !e c*uld acc*++*date *ctag*nal r**+# 3y #i+ply adding value# #uch a# ,orth=est t* $irectionH) The cu#t*+ inde;er i# ne;t and l**k# like thi#1 pu$ ic Corridor thi#J:irection dK; get ; return cJ0int1 dK3< #et ; cJ0int1 dK 9 *a ue3< < The 9ir#t line 3egin# !ith !hat l**k# like a n*r+al declarati*n *9 a pu3lic Pr*perty *9 type Corridor, 3ut the this<+ype t> that end# the line indicate# that it i# an cu#t*+er inde;er, in thi# ca#e *ne that take# a $irection value a# it# key and return# a Corridor) Since enu+# are value type# that de9ault t* 3eing repre#ented 3y integer c*n#tant# that #tart !ith 7er*, !e can #a9ely u#e the ca#t t* int t* create a nu+eric inde; t* the c array *9 Corridor#) Like a Pr*perty, a cu#t*+ inde;er# set +eth*d ha# a hidden para+eter called value) That 9ini#he# up the *oom cla##, 3ut !e declare t!* additi*nal type# t* inherit 9r*+ it P a *egen#pot and a !owerVp) They each di99er 9r*+ the 3a#e cla## #*lely in the !ay they #et up their ,ame pr*perty) The Corridor cla## re9erenced in *oom ha# *ne duty P +aintain re9erence# t* t!* di99erent *ooms and #upply a +raverse() 9uncti*n !hich return# !hichever *9 the t!* r**+# i#nt pa##ed in a# an argu+ent1 //:c0>:Corridor.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 na!e#pace La$yrinth; c a## Corridor ; Roo! x2 y3

Cha"ter '* >olding Eour 123ects

44'

interna Corridor0 Roo! x2 :irection xVa Roo! y2 :irection yVa thi#.x 9 x3 thi#.y 9 y3 xJxVa K 9 thi#3 yJyVa K 9 thi#3 <

2 1;

pu$ ic Roo! 'ra*er#e0 Roo! origin2 :irection .a 1; Sy#te!.Con#o e.VriteLine0 &Lea*ing ;0< $y it# ;"< corridor&2 origin2 .a 13 if 0origin 99 x1 return y3 e #e return x3 < pu$ ic Roo! 'ra*er#e0Roo! origin1; Sy#te!.Con#o e.VriteLine0 &Retreating fro! & R origin13 if 0origin 99 x1 return y3 e #e return x3 < < <///:8 The Corridor() c*n#truct*r u#e# *oom# cu#t*+ inde;er# Ge)g), x<x=all> I thisFH) *te that there# n* pr*3le+ in re9erring t* this in#ide a c*n#truct*r)

45(

Thinking in C

www.ThinkingIn.!et

Custo# %nu#erators I 4ata 'tructures


-n the previ*u# e;a+ple, a9ter a c*rrid*r i# created, the Corridor c*ntain# a re9erence t* 3*th *oom#, and 3*th *oom# c*ntain a re9erence t* the Corridor1

,hile !e called the+ r**+# and c*rrid*r#, !hat !eve really g*t here i# a non9directed gra"h) Here, IgraphJ i# 3eing u#ed in it# +athe+atical #en#e *9 Ia #et C *9 Certice# and a #et E *9 Edge# that c*nnect ele+ent# in C)J ,hat !eve de#igned in In*nEdirectedJ 3ecau#e *ur Corridor# can 3e traver#ed in either directi*n) = l*t *9 very intere#ting pr*3le+# can 3e +apped int* graph the*ry G*99 the t*p *9 the head, pr*3le+# #uch a#1 !inning a ga+e *9 che##, h*! 3e#t t* pack a c*ntainer, the +*#t e99icient !ay t* #chedule a 3unch *9 4*3#, and every*ne# 9av*rite, !hich i# the cheape#t r*ute 9*r a traveling #ale#per#*n t* vi#it a 3unch *9 citie#H) ,riting a cu#t*+ enu+erat*r G*r perhap# +*re than *ne, t* try *ut di99erent alg*rith+#H i# an elegant !ay t* traver#e a c*+ple; graph) -n thi# e;a+ple, !e create a #i+ple Aa7e that c*n#i#t# *9 *ne *egen#pot and *ne !owerVp, and #everal n*r+al r**+# Gthe na+e# are taken 9r*+ vide*ga+e# 9*r !hich *ne can pr*gra+ I3*t#J P 4u#t think *9 the+ a# the #tart and #t*p p*int#H1 //:c0>:GaMe.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 na!e#pace La$yrinth; c a## GaMe :5+nu!era$ e ; Roo!JK roo!#3 Roo! regenRoo!3

Cha"ter '* >olding Eour 123ects

451

interna Roo! RegenSpot; get ; return regenRoo!3< < GaMe01; regenRoo! 9 ne. RegenSpot013 roo!# 9 ne. Roo!JK; ne. Roo!012 ne. Roo!012 ne. Roo!012 regenRoo!2 ne. Roo!012 ne. Roo!012 ne. -o.erOp01 <3 ne. Corridor0roo!#J0K2 :irection.ea#t2 roo!#JEK2 :irection.north13 ne. Corridor0roo!#J0K2 :irection.#outh2 roo!#J"K2 :irection.north13 ne. Corridor0roo!#J"K2 :irection.#outh2 roo!#JTK2 :irection.north13 ne. Corridor0roo!#J2K2 :irection.ea#t2 roo!#JTK2 :irection..e#t13 ne. Corridor0roo!#JTK2 :irection.ea#t2 roo!#JEK2 :irection..e#t13 ne. Corridor0roo!#JTK2 :irection.#outh2 roo!#JPK2 :irection.#outh13 ne. Corridor0roo!#JPK2 :irection.#outh2 roo!#J?K2 :irection.north13 < pu$ ic #tatic *oid Gain01; GaMe ! 9 ne. GaMe013 foreach0Roo! r in !1; Sy#te!.Con#o e.VriteLine0 &Roo!Runner in & R r.Ca!e13 < < pu$ ic 5+nu!erator _et+nu!erator01; return ne. :epthHir#t0thi#13 < < <///:8

45)

Thinking in C

www.ThinkingIn.!et

Cla## .aTe i# declared t* i+ple+ent the B&numerable inter9ace, !hich !ell u#e t* return a cu#t*+i7ed enu+erat*r !hich run# the +a7e) *te that 9*r *ur purp*#e#, !e d*nt care i9 the enu+erat*r vi#it# every verte; *n the graph Gevery r**+ in the +a7eHQ a# a +atter *9 9act, !ere pr*3a3ly +*#t intere#ted in an enu+erat*r !hich vi#it# a# 9e! vertice# a# p*##i3leK Thi# i# a di99erent intenti*n 9r*+ the generic enu+erat*r# *9 the ) ET c*llecti*n cla##e#, !hich *9 c*ur#e do need t* vi#it every ele+ent in the data #tructure) The .aTe c*ntain# an array rooms and a re9erence t* the #tarting *egen*oom) The +a7e# dyna+ic #tructure i# 3uilt in the .aTe() c*n#truct*r and c*n#i#t# *9 % *oom# and % Corridor#) The .ain() +eth*d c*n#truct# a .aTe and then u#e# a foreach 3l*ck t* #h*! the traver#al *9 the +a7e) Behind the #cene#, the foreach 3l*ck deter+ine# that .aTe i# an B&numerable type and #ilently call# et&numerator()) .aTe# i+ple+entati*n *9 B&numerable6 et&numerator() i# the 9inal +eth*d in .aTe) = ne! *34ect *9 type $epth:irst Gdi#cu##ed #h*rtlyH i# created !ith a re9erence t* the current .aTe) There are #everal di99erent !ay# t* traver#e a +a7e) -t i# pr*3a3le that !hen !riting a pr*gra+ t* run +a7e#, y*u !*uld !ant t* try #everal di99erent alg*rith+#, *ne that ru#hed headl*ng d*!n the 9ir#t une;pl*red c*rrid*r, an*ther that +eth*dically e;pl*red all the r*ute# 9r*+ a #ingle r**+, etc) H*!ever, each *9 the#e alg*rith+# ha# a l*t *9 thing# in c*++*n1 they +u#t all i+ple+ent the B&numerator inter9ace, they all have re9erence# t* the .aTe and a current *oom, they all 3egin at the regen #p*t and end at the p*!er up) Really, the *nly !ay they di99er i# in their i+ple+entati*n *9 B&numerator6.ove,ext() !hen theyre Il*#tJ in the +a7e) Thi# i# a 4*3 9*r the ITe+plate Aeth*dJ pattern1 //:c0>:Roo!Runner.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 na!e#pace La$yrinth; a$#tract c a## Roo!Runner:5+nu!erator ; GaMe !3 protected Roo!Runner0GaMe !1;

Cha"ter '* >olding Eour 123ects

453

thi#.! 9 !3 < protected Roo! currentRoo! 9 nu pu$ ic O$Dect Current; get ; return currentRoo!3< < pu$ ic *irtua *oid Re#et01; currentRoo! 9 nu 3 < pu$ ic $oo Go*eCext01; if 0currentRoo! 99 nu 1 ; Sy#te!.Con#o e.VriteLine0 &;0< #tarting the !aMe&2 thi#._et'ype0113 currentRoo! 9 !.RegenSpot3 return true3 < if 0currentRoo! i# -o.erOp1 ; Sy#te!.Con#o e.VriteLine0 &;0< ha# found -o.erOp!&2 thi#._et'ype0113 return fa #e3 < return thi#.ConcreteGo*eCext013 < protected a$#tract $oo < <///:8 Here, an abstract cla## called *oom*unner i+ple+ent# the +eth*d# *9 the B&numerator inter9ace, 3ut leave# *ne tiny 3it t* it# #u3cla##e# t* i+ple+ent) The R**+RunnerGH c*n#truct*r 4u#t #t*re# a re9erence t* the .aTe that create# it and initiali7e# the current*oom Ge;p*#ed t* the *ut#ide !*rld a# B&numerator# Current Pr*pertyH t* null) *eset() al#* #et# the ConcreteGo*eCext013 3

454

Thinking in C

www.ThinkingIn.!et

current*oom t* null P re+e+3er that B&numerator6.ove,ext() i# al!ay# called *nce 2e$ore the 9ir#t read *9 the Current pr*perty) The 9ir#t ti+e *oom*unner6.ove,ext() i# called, current*oom !ill 3e null) Becau#e *oom*unner i# an a3#tract type that +ay 3e i+ple+ented 3y +any di99erent #u3type#, *ur c*n#*le +e##age can u#e this6 et+ype() t* deter+ine the e;act runti+e type *9 *oom*unner) GThe trick at the r**t *9 the Ite+plate +eth*dJ pattern)H =9ter printing a +e##age t* the #creen ann*uncing the *oom*unner# readine## t* #tart traver#ing the .aTe, the current r**+ i# #et t* the .aTe# *egen#pot and the +eth*d return# true t* indicate that the B&numerator i# at the 3eginning *9 the data #tructure) Si+ilarly, i9 the current*oom i# *9 type !owerVp, the +a7e running i#, 3y *ur de9initi*n, c*+plete and .ove,ext() return# 9al#e) -9, h*!ever, the currentR**+ i# neither null n*r a P*!erUp r**+, e;ecuti*n g*e# t* this6Concrete.ove,ext()) Thi# i# the te+plate +eth*d) "u#t a# this6 et+ype() !ill return the e;act runti+e type, this6Concrete.ove,ext() !ill e;ecute the Concrete.ove,ext() +eth*d *9 the runti+e type) 5*r thi# t* !*rk, *9 c*ur#e, *oom*unner6Concrete.ove,ext() +u#t 3e declared a# virtual *r, a# in thi# ca#e, abstract) .aTe6 et&numerator() returned an *34ect *9 type $epth:irst, !hich i+ple+ent# *oom*unner# te+plate +eth*d Concrete.ove,ext()1 //:c0>::epthHir#t.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 na!e#pace La$yrinth; c a## :epthHir#t : Roo!Runner ; pu$ ic :epthHir#t0GaMe !1 : $a#e0!1;< )rrayLi#t *i#itedCorridor# 9 ne. )rrayLi#t013 Corridor a#tCorridor 9 nu 3 protected o*erride $oo ConcreteGo*eCext01; foreach0:irection d in +nu!._etNa ue#0typeof0:irection111;

Cha"ter '* >olding Eour 123ects

455

if 0currentRoo!JdK !9 nu 1 ; Corridor c 9 currentRoo!JdK3 if 0*i#itedCorridor#.Contain#0c1 99 fa #e1 ; *i#itedCorridor#.)dd0c13 a#tCorridor 9 c3 currentRoo! 9 c.'ra*er#e0currentRoo!2 d13 return true3 < < < //Co un*i#ited corridor#! Retreat! a#tCorridor.'ra*er#e0currentRoo!13 return true3 < < <///:8 ?epth5ir#t inherit# 9r*+ Ba#eRunner, a# it# cla## declarati*n and c*n#truct*r #h*!) Thi# particular +a7e runner e##entially g*e# d*!n the 9ir#t c*rrid*r it #ee# that it ha#nt yet g*ne thr*ugh) -9 there are n*ne it ha#nt 3een d*!n, it 3acktrack# t* the previ*u# r**+) UhE*h P !hat i9 it 3acktrack# int* a r**+ and that r**+ d*e#nt have any unvi#ited c*rrid*r#F L**k# like a de9ectK But *n *ur +a7e, the ?epth5ir#t !*rk# like a cha+p1

456

Thinking in C

www.ThinkingIn.!et

'orting and searching Lists


Utility +eth*d# #*rt and #earch in List# have the #a+e na+e# and #ignature# a# th*#e 9*r array# *9 *34ect#, 3ut are in#tance +eth*d# *9 BList in#tead *9 'rray) Here# an e;a+ple1 //: c0>:Li#tSortSearch.c# // Sorting and #earching 5Li#t# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 pu$ ic c a## Li#tSortSearch ; pri*ate #tatic *oid Hi 0)rrayLi#t i#t1;

Cha"ter '* >olding Eour 123ects

45#

for 0int i 9 03 i W 2P3 iRR1 ; char c 9 0char1 0')' R i13 i#t.)dd0c13 < < pri*ate #tatic *oid -rint0)rrayLi#t i#t1; foreach0O$Dect o in i#t1; Sy#te!.Con#o e.Vrite0o R &2 &13 < Sy#te!.Con#o e.VriteLine013 < pri*ate #tatic *oid Shuff e0)rrayLi#t int en 9 i#t.Count3 for 0int i 9 03 i W en3 iRR1 ; int % 9 rand.Cext0 en13 O$Dect te!p 9 i#tJiK3 i#tJiK 9 i#tJ%K3 i#tJ%K 9 te!p3 < < #tatic Rando! rand 9 ne. Rando!013 pu$ ic #tatic *oid Gain01 ; )rrayLi#t i#t 9 ne. )rrayLi#t013 Hi 0 i#t13 -rint0 i#t13 Shuff e0 i#t13 Sy#te!.Con#o e.VriteLine0&)fter #huff ing: &13 -rint0 i#t13 i#t.Re*er#e013 Sy#te!.Con#o e.VriteLine0&Re*er#ed: &13 -rint0 i#t13 i#t.Sort013 Sy#te!.Con#o e.VriteLine0&)fter #orting: &13 -rint0 i#t13 O$Dect %ey 9 i#tJ"2K3 int index 9 i#t.BinarySearch0%ey13 Sy#te!.Con#o e.VriteLine0 i#t1;

45&

Thinking in C

www.ThinkingIn.!et

&Location of ;0< i# ;"<2 i#tJ;2<K 9 ;T<&2 %ey2 index2 index2 i#tJindexK13 < < ///:8 The u#e *9 the#e +eth*d# i# identical t* the static *ne# in 'rray, 3ut are in#tance +eth*d# *9 'rrayList) Thi# pr*gra+ al#* c*ntain# an i+ple+entati*n *9 ?*nald Nnuth# #hu99ling alg*rith+ t* rand*+i7e the *rder *9 a List)

7ro# Collections to )rra5s


The -C*llecti*n inter9ace #peci9ie# that all c*llecti*n# +u#t 3e a3le t* c*py their c*ntent# int* an array) The de#tinati*n array +u#t 3e a *neE di+en#i*nal array !ith 7er*E3a#ed inde;ing) The c*pying pr*cedure +ay in#ert *34ect# int* the array #tarting at an ar3itrary inde;, a##u+ing *9 c*ur#e that the inde; i# 7er* *r p*#itive and that the de#tinati*n array i# pr*perly initiali7ed) C*pying an =rrayLi#t t* an array i# #i+ple1 //:c0>:Li#t'o)rray.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 c a## Li#t'o)rray; pu$ ic #tatic *oid Gain01; 5Li#t i#t 9 ne. )rrayLi#t013 Rando! r 9 ne. Rando!013 int i'o)dd 9 "0 R r.Cext0"013 for0int i 9 03 i W i'o)dd3 iRR1; i#t.)dd0r.Cext0"00113 < int indexHorCopyStart 9 r.Cext0"013 intJK array 9 ne. intJ indexHorCopyStart R i#t.CountK3 i#t.Copy'o0array2 indexHorCopyStart13 for0int i 9 03 i W array.Length3 iRR1; Sy#te!.Con#o e.VriteLine0 &arrayJ;0<K 9 ;"<&2 i2 arrayJiK13

Cha"ter '* >olding Eour 123ects

45'

< < <///:8 =9ter initiali7ing an 'rrayList, !e u#e a rand*+ nu+3er generat*r t* ch**#e t* add 3et!een 0$ and 06 ite+#) ,e l**p, u#ing list6'dd() t* add rand*+ nu+3er# 3et!een $ and 66) Then, !e ch**#e a rand*+ nu+3er t* indicate !here in the array !e !i#h t* 3egin c*pying) ,e then declare and initiali7e the array, !hich +u#t 3e #i7ed t* acc*++*date index:orCopy#tart e+pty integer# G#ince it# an array *9 int#, the#e !ill 3e initiali7ed t* $H and list6Count integer# 9r*+ the 'rrayList) The Copy+o() +eth*d take# t!* para+eter# P the re9erence t* the de#tinati*n array and the #tarting inde; 9*r the c*py) ,e then l**p *ver the array, *utputting the c*ntent#) Since integer# are value type#, +*di9ying value# in the de#tinati*n array !ill n*t 3e re9lected in the 'rrayList list) H*!ever, re9erence type# !*uld naturally have the #a+e I#hall*! c*pyJ i##ue# that are di#cu##ed in #re9 t* #hall*! c*py di#cu##i*n)# Since B$ictionary inherit# 9r*+ BCollection, i+ple+enting type# +u#t #upp*rt Copy+o()) The re#ult# are an array *9 $ictionary&ntry ite+#1 //:c0>::ictionary'o)rray.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 c a## :ictionary'o)rray; pu$ ic #tatic *oid Gain01; 5:ictionary dict 9 ne. Ua#hta$ e013 Rando! r 9 ne. Rando!013 int iaey# 9 T R r.Cext0T13 for0int i 9 03 i W iaey#3 iRR1; dict.)dd0i2 r.Cext0"00113 < :ictionary+ntryJK a 9 ne. :ictionary+ntryJdict.CountK3 dict.Copy'o0a2 013 for0int i 9 03 i W a.Length3 iRR1; :ictionary+ntry de 9 aJiK3 Sy#te!.Con#o e.VriteLine0

46(

Thinking in C

www.ThinkingIn.!et

&aJ;0<K: .aey 9 ;"< .Na ue 9 ;2<&2 i2 de.aey2 de.Na ue13 < < <///:8 = typical run l**k# like1 aJ0K: .aey 9 E .Na ue 9 "" aJ"K: .aey 9 T .Na ue 9 P aJ2K: .aey 9 2 .Na ue 9 ? aJTK: .aey 9 " .Na ue 9 >T aJEK: .aey 9 0 .Na ue 9 E :*ull n*te that the re#ulting array i# n*t #*rted *n the value *9 the key, !hich +ight 3e de#ira3le, 3ecau#e B$ictionary d*e#nt reDuire key# t* 3e BComparable) H*!ever, they *9ten are and, i9 #*, it !*uld pr*3a3ly 3e nice i9 the re#ulting array !ere *rdered 3y key) Thi# pr*gra+ de+*n#trate# a techniDue t* get thi# re#ult1 //:c0>::ictionary'oSorted)rray.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 c a## :ictionary'o)rray; pu$ ic #tatic *oid Gain01; 5:ictionary dict 9 ne. Ua#hta$ e013 Rando! r 9 ne. Rando!013 int iaey# 9 T R r.Cext0T13 for0int i 9 03 i W iaey#3 iRR1; dict.)dd0i2 i13 < //Hir#t2 get array of %ey# 5Co ection %eyCo 9 dict.aey#3 5Co!para$ eJK %ey)rray 9 ne. 5Co!para$ eJ%eyCo .CountK3 //Vou d thro. exception if %ey# not 5Co!para$ e %eyCo .Copy'o0%ey)rray2 013 //Second2 get array of *a ue# 5Co ection *a Co 9 dict.Na ue#3 O$DectJK *a )rray 9 ne. O$DectJ*a Co .CountK3

Cha"ter '* >olding Eour 123ects

461

*a Co .Copy'o0*a )rray2 013 )rray.Sort0%ey)rray2 *a )rray13 //5n#tantiate de#tination array :ictionary+ntryJK a 9 ne. :ictionary+ntryJ%eyCo .CountK3 //Retrie*e and #et in %ey6#orted order for0int i 9 03 i W a.Length3 iRR1; aJiK 9 ne. :ictionary+ntry013 aJiK.aey 9 %ey)rrayJiK3 aJiK.Na ue 9 *a )rrayJiK3 < //Output re#u t# for0int i 9 03 i W a.Length3 iRR1; :ictionary+ntry de 9 aJiK3 Sy#te!.Con#o e.VriteLine0 &aJ;0<K: .aey 9 ;"< .Na ue 9 ;2<&2 i2 de.aey2 de.Na ue13 < < <///:8 The pr*gra+ #tart# *99 #i+ilarly t* the previ*u# e;a+ple#, !ith a 9e! keyE value pair# 3eing in#erted int* a "ashtable) -n#tead *9 directly c*pying t* the de#tinati*n array, th*ugh, !e retrieve the BCollection *9 key#) BCollection d*e#nt have any #*rting capa3ilitie#, #* !e u#e Copy+o() t* +*ve the key# int* an BComparable<> array) -9 any *9 *ur key# did not i+ple+ent BComparable, thi# !*uld thr*! an BnvalidCast&xception) The ne;t #tep i# t* c*py the value# 9r*+ the "ashtable int* an*ther array, thi# ti+e *9 type ob)ect<>) ,e then u#e 'rray6#ort('rray, 'rray), !hich #*rt# 2oth it# input array# 3a#ed *n the c*+pari#*n# in the 9ir#t array, !hich in *ur ca#e i# the key array) -n general, *ne #h*uld av*id a #ituati*n !here *ne change# the #tate *9 *ne *34ect G#uch a# the array *9 value#H 3a#ed *n l*gic internal t* an*ther *34ect G#uch a# the #*rting *9 the array *9 key#HQ a #ituati*n that# called logical cohesion) ,e c*uld av*id u#ing 'rray6#ort('rray, 'rray) 3y #*rting (ey'rray and then u#ing a foreach( ob)ect (ey in (ey'rray) l**p t* retrieve the value# 9r*+ the

46)

Thinking in C

www.ThinkingIn.!et

Ha#hta3le, 3ut in thi# ca#e that# cl*#ing the 3arn d**r a9ter the h*r#e# have 9led P the ) ET 5ra+e!*rk d*e# n*t have an B$ictionary !hich +aintain# it# *34ect# in key *rder, !hich !*uld 3e the 3e#t #*luti*n 9*r the general de#ire t* +*ve 3et!een an B$ictionary and a #*rted array) -n keeping !ith it# #ingular nature, ,ameHalueCollection6Copy+o() d*e# n*t act like "ashtable6Copy+o()) ,here "ashtable6Copy+o() create# an array *9 $ictionary&ntry *34ect# that c*ntain 3*th the key and value, ,ameHalueCollection# Copy+o() +eth*d create# an array *9 string# !hich repre#ent the value# in a c*++aE#eparated 9*r+at, !ith n* re9erence t* the key#) -t# di99icult t* i+agine the utility *9 thi# 9*r+at) Thi# e;a+ple 3uild# a +*re rea#*na3le array 9r*+ a a+eCalueC*llecti*n1 //:c0>:CNa Co 'o)rray.c# u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 u#ing Sy#te!.Co ection#.Specia iMed3 c a## Ca!eNa ueCo ection+ntry : 5Co!para$ e; #tring %ey3 pu$ ic #tring aey; get ; return %ey3 < < #tringJK *a ue#3 pu$ ic #tringJK Na ue#; get ; return *a ue#3 < < pu$ ic Ca!eNa ueCo ection+ntry0 #tring %ey2 #tringJK *a ue#1; thi#.%ey 9 %ey3 thi#.*a ue# 9 *a ue#3 < pu$ ic int Co!pare'o0O$Dect o1; if0o i# Ca!eNa ueCo ection+ntry1; Ca!eNa ueCo ection+ntry that 9

Cha"ter '* >olding Eour 123ects

463

0Ca!eNa ueCo ection+ntry1 o3 return thi#.aey.Co!pare'o0that.aey13 < thro. ne. )rgu!ent+xception013 < pu$ ic #tatic Ca!eNa ueCo ection+ntryJK Hro!Ca!eNa ueCo ection0Ca!eNa ueCo ection #rc1; #tringJK %ey# 9 #rc.) aey#3 Ca!eNa ueCo ection+ntryJK re#u t# 9 ne. Ca!eNa ueCo ection+ntryJ%ey#.LengthK3 for0int i 9 03 i W %ey#.Length3 iRR1; #tring %ey 9 %ey#JiK3 #tringJK *a # 9 #rc._etNa ue#0%ey13 Ca!eNa ueCo ection+ntry entry 9 ne. Ca!eNa ueCo ection+ntry0%ey2 *a #13 re#u t#JiK 9 entry3 < return re#u t#3 < < c a## CNa Co 'o)rray; pu$ ic #tatic *oid Gain01; Ca!eNa ueCo ection dict 9 ne. Ca!eNa ueCo ection013 Rando! r 9 ne. Rando!013 int iaey# 9 T R r.Cext0T13 for0int i 9 03 i W iaey#3 iRR1; int iNa #'o)dd 9 P R r.Cext0P13 for0int D 9 03 D W iNa #'o)dd3 DRR1; dict.)dd0i.'oString012 r.Cext0"001.'oString0113 < < Ca!eNa ueCo ection+ntryJK a 9 Ca!eNa ueCo ection+ntry. Hro!Ca!eNa ueCo ection0dict13

464

Thinking in C

www.ThinkingIn.!et

)rray.Sort0a13 for0int i 9 03 i W a.Length3 iRR1; Sy#te!.Con#o e.VriteLine0 &aJ;0<K.aey 9 ;"<&2 i2 aJiK.aey13 foreach0#tring * in aJiK.Na ue#1; Sy#te!.Con#o e.VriteLine0 &^t Na ue: & R *13 < < < <///:8 ,e de9ine a ne! type, ,ameHalueCollection&ntry !hich c*rre#p*nd# t* the $ictionary&ntry *9 "ashtable) Like that type, *ur ne! type ha# a Eey and a Halue pr*perty, 3ut the#e are *9 type string and string<> re#pectively) Becau#e !e kn*! that the Eey i# al!ay# g*ing t* 3e a string, !e can declare ,ameHalueCollection&ntry t* i+ple+ent BComparable and i+ple+ent that #i+ply 3y c*+paring Eey pr*pertie# Gi9 the para+eter t* Compare+o() i# n*t a ,ameHalueCollection&ntry, !e thr*! an 'rgument&xceptionH) The #tatic :rom,ameHalueCollection() +eth*d i# !here !e c*nvert a ,ameHalueCollection int* an array *9 ,ameHalueCollection&ntry#) 5ir#t, !e get a string<> *9 key# 9r*+ the 'llEeys pr*perty *9 the input para+eter Gi9 !e had u#ed the Eeys pr*perty, !e !*uld have received the #a+e data, 3ut in an ob)ect arrayH) The Length pr*pery *9 the (eys all*!# u# t* #i7e the results array) The etHalues() +eth*d *9 ,ameHalueCollection return# a string array, !hich al*ng !ith the string key, i# !hat !e need t* in#tantiate a #ingle ,ameHalueCollection&ntry) Thi# entry i# added t* the results !hich are returned !hen the l**p end#) Cla## ,HalCol+o'rray de+*n#trate# the u#e *9 thi# ne! cla## !eve !ritten) = ,ameHalueCollection i# created and each entry i# 9illed !ith a rand*+ nu+3er *9 #tring#) = ,ameHalueCollection&ntry array called a i# generated u#ing the #tatic 9uncti*n 4u#t di#cu##ed) Since !e i+ple+ented BComparable in ,ameHalueCollection&ntry, !e can u#e 'rray6#ort() t* #*rt the re#ult# 3y the Eey string#) 5*r each ,ameHalueCollection&ntry, !e *utput the Eey, retrieve the string<>

Cha"ter '* >olding Eour 123ects

465

Halues, and *utput the+ t* the c*n#*le) ,e c*uld, *9 c*ur#e, #*rt the Halues a# !ell, i9 that !a# de#ired)

Persistent 4ata With )4O.(%,hile c*llecti*n cla##e# and data #tructure# re+ain i+p*rtant t* inE +e+*ry +anipulati*n *9 data, *99line #t*rage i# d*+inated 3y thirdEparty vend*r# #upp*rting the relati*nal +*del *9 data #t*rage) O9 c*ur#e, Oracle# ep*ny+*u# pr*duct d*+inate# the highEend +arket, !hile Aicr*#*9t# SML Server and -BA# ?B2 are a3le c*+petit*r# 9*r enterpri#e data) There are hundred# *9 data3a#e# appr*priate 9*r #+aller pr*4ect#, the +*#t !ellEdi#tri3uted *9 !hich i# Aicr*#*9t# =cce##) Aean!hile, the #ucce## *9 the ,e3 +ade +any pe*ple c*+9*rta3le !ith the c*ncept that I4u#tJ te;tE3a#ed #trea+# +arked !ith hu+anEreada3le tag# !ere #u99iciently p*!er9ul t* create a l*t *9 endEu#er value) E;ten#i3le Aarkup Language GBALH ha# e;pl*ded in p*pularity in the ne! +illenniu+ and i# rapidly 3ec*+ing the pre9erred inE+e+*ry repre#entati*n *9 relati*nal data) Thi# !ill 3e di#cu##ed in depth in chapter #BAL#, 3ut #*+e di#cu##i*n *9 BAL i# relevant t* any di#cu##i*n *9 =ctive ?ata O34ect# 9*r ) ET G=?O) ETH) Like graphic# pr*gra++ing, the c*+plete ga+ut *9 data3a#e pr*gra++ing detail# cann*t 3e adeDuately c*vered in le## than an entire 3**k) H*!ever, al#* like graphic# pr*gra++ing, +*#t pr*gra++er# d* n*t need t* kn*! +*re than the 3a#ic#) -n the ca#e *9 data3a#e pr*gra++ing, 66^ *9 the !*rk 3*il# d*!n t* 3eing a3le t* Create, Read, Update, and ?elete data P the 9uncti*n# kn*!n a# ICRU?)J Thi# #ecti*n trie# t* deliver the minimum a+*unt *9 in9*r+ati*n y*u need t* 3e a3le t* u#e =?O) ET in a pr*9e##i*nal #etting) =lth*ugh CRU? +ay encap#ulate +any pr*gra++er# intent 9*r =?O) ET, there# an*ther I?J that i# 9unda+ental t* =?O) ET P I?i#c*nnected)J -r*nically, the +*re the ,*rld ,ide ,e3 3ec*+e# truly u3iDuit*u#, the +*re di99icult it i# t* create #*luti*n# 3a#ed *n c*ntinu*u# c*nnecti*n#) The client #*9t!are that i# running in a !idely di#tri3uted

466

Thinking in C

www.ThinkingIn.!et

applicati*n, i)e), an applicati*n that i# running *ver the -nternet, #i+ply cann*t 3e c*unted *n t* g* thr*ugh an *rderly, ti+ely li9ecycle *9 Ic*nnect, gain e;clu#ive acce## t* data, c*nduct tran#acti*n#, and di#c*nnect)J Si+ilarly, alth*ugh c*ntinu*u# net!*rk acce## +ay 3e the rule in c*rp*rate #etting#, the c*+ing year# are g*ing t* #ee an e;pl*#i*n in applicati*n# 9*r +*3ile device#, #uch a# handheld# and teleph*ne#, !hich have +etered c*#t#Q ec*n*+ic# dictate that #uch applicati*n# cann*t 3e c*n#tantly c*nnected) =?O) ET #eparate# the ta#k# *9 actually acce##ing the data #t*re 9r*+ the ta#k# *9 +anipulating the re#ulting #et *9 data) The 9*r+er *3vi*u#ly reDuire a c*nnecti*n t* the #t*re !hile the latter d* n*t) Thi# #eparati*n# *9 c*ncern# help# !hen c*nverting data 9r*+ *ne data #t*re t* an*ther G#uch a# c*nverting data 3et!een relati*nal ta3le data and BALH a# !ell a# +aking it +uch ea#ier t* pr*gra+ !idelyEdi#tri3uted data3a#e applicati*n#) H*!ever, thi# +*del increa#e# the p*##i3ility that t!* u#er# !ill +ake inc*+pati3le +*di9icati*n# t* related data P theyll 3*th re#erve the la#t #eat *n the 9light, *ne !ill +ark an i##ue a# re#*lved !hile the *ther !ill e;pand the #c*pe *9 the inve#tigati*n, etc) S* even a +ini+al intr*ducti*n t* =?O) ET reDuire# #*+e di#cu##i*n *9 the i##ue# *9 c*ncurrency vi*lati*n#)

Getting a handle on data with 4ata'et


The $ata#et cla## i# the r**t *9 a relati*nal vie! *9 data) = $ata#et ha# $ata+able#, !hich have $ataColumn# that de9ine the type# in $ata*ow#) The relati*nal data3a#e +*del !a# intr*duced 3y E)5) C*dd in the early 06%$#) The c*ncept *9 ta3le# #t*ring data in r*!# in #tr*nglyE typed c*lu+n# +ay #ee+ t* 3e the very de9initi*n *9 !hat a data3a#e i#, 3ut C*dd# 9*r+ali7ati*n *9 the#e c*ncept# and *ther# #uch #uch a# normali;ation Ga pr*ce## 3y !hich redundant data i# eli+inated and there3y en#uring the c*rrectne## and c*n#i#tency *9 edit#H !a# *ne *9 the great land+ark# in the hi#t*ry *9 c*+puter #cience) ,hile n*r+ally *ne create# a $ata#et 3a#ed *n e;i#ting data, it# p*##i3le t* create *ne 9r*+ #cratch, a# thi# e;a+ple #h*!#1 //:c0>:Ba#ic:ataSetOperation#.c#

Cha"ter '* >olding Eour 123ects

46#

u#ing Sy#te!.:ata3 c a## Ba#ic:ataSetOperation# ; pu$ ic #tatic *oid Gain0#tringJK arg#1; :ataSet d# 9 Bui d:ataSet013 -rint:ataSetCharacteri#tic#0d#13 < pri*ate #tatic :ataSet Bui d:ataSet01 ; :ataSet d# 9 ne. :ataSet0&Goc%:ataSet&13 :ata'a$ e au'a$ e 9 ne. :ata'a$ e0&)uthor#&13 d#.'a$ e#.)dd0au'a$ e13 :ataCo u!n na!eCo 9 ne. :ataCo u!n0&Ca!e&2 typeof0#tring113 au'a$ e.Co u!n#.)dd0na!eCo 13 :ataRo. arryRo. 9 au'a$ e.Ce.Ro.013 arryRo.J&Ca!e&K 9 &Larry&3 au'a$ e.Ro.#.)dd0 arryRo.13 :ataRo. $ruceRo. 9 au'a$ e.Ce.Ro.013 $ruceRo.J&Ca!e&K 9 &Bruce&3 au'a$ e.Ro.#.)dd0$ruceRo.13 return d#3 < pri*ate #tatic *oid -rint:ataSetCharacteri#tic#0 :ataSet d#1; Sy#te!.Con#o e.VriteLine0 &:ataSet ^&;0<^& ha# ;"< ta$ e#&2 d#.:ataSetCa!e2 d#.'a$ e#.Count13 foreach0:ata'a$ e ta$ e in d#.'a$ e#1; Sy#te!.Con#o e.VriteLine0 &'a$ e ^&;0<^& ha# ;"< co u!n#&2 ta$ e.'a$ eCa!e2 ta$ e.Co u!n#.Count13 foreach0:ataCo u!n co in ta$ e.Co u!n#1; Sy#te!.Con#o e.VriteLine0 &Co u!n ^&;0<^& contain# data of type ;"<&2

46&

Thinking in C

www.ThinkingIn.!et

co .Co u!nCa!e2 co .:ata'ype13 < Sy#te!.Con#o e.VriteLine0 &'he ta$ e contain# ;0< ro.#&2 ta$ e.Ro.#.Count13 foreach0:ataRo. r in ta$ e.Ro.#1; Sy#te!.Con#o e.Vrite0&Ro. :ata: &13 foreach0:ataCo u!n co in ta$ e.Co u!n#1; #tring co Ca!e 9 co .Co u!nCa!e3 Sy#te!.Con#o e.Vrite0 &J;0<K 9 ;"<&2 co Ca!e2 rJco Ca!eK13 < Sy#te!.Con#o e.VriteLine013 < < < <///:8 The ) ET cla##e# related t* $ata#ets are in the #ystem6$ata na+e#pace, #* naturally !e have t* include a using #tate+ent at the 3eginning *9 the pr*gra+) The .ain() +eth*d i# #traight9*r!ard, it call# Build$ata#et() and pa##e# the *34ect returned 3y that +eth*d t* an*ther #tatic +eth*d called !rint$ata#etCharacteristics()) Build$ata#et() intr*duce# #everal ne! cla##e#) 5ir#t c*+e# a $ata#et, u#ing a c*n#truct*r that all*!# u# t* #i+ultane*u#ly na+e it IA*ck?ataSet)J Then, !e declare and initiali7e a $ata+able called I=uth*rJ !hich !e re9erence !ith the au+able varia3le) $ata#et *34ect# have a +ables pr*perty *9 type $ata+ableCollection, !hich i+ple+ent# BCollection) ,hile $ata+ableCollection d*e# n*t i+ple+ent BList, it c*ntain# #*+e #i+ilar +eth*d#, including 'dd, !hich i# u#ed here t* add the ne!ly created au+able t* ds# +ables) $ataColumn#, #uch a# the nameCol in#tantiated in the ne;t line, are a##*ciated !ith a particular $ata+ype) $ata+ype# are n*t nearly a# e;ten#ive *r e;ten#i3le a# n*r+al type#) Only the 9*ll*!ing can 3e #peci9ied a# a $ata+ype1

Cha"ter '* >olding Eour 123ects

46'

B**lean Byte Char ?ateTi+e ?eci+al ?*u3le -nt0. -nt/2 -nt.& SByte Single String Ti+eSpan U-nt0. U-nt/2 U-nt.& -n thi# ca#e, !e #peci9y that the I a+eJ c*lu+n #h*uld #t*re #tring#) ,e add the c*lu+n t* the Columns c*llecti*n Ga $ataColumnCollectionH *9 *ur au+able) One cann*t create r*!# *9 data u#ing a #tandard c*n#truct*r, a# a r*!# #tructure +u#t c*rre#p*nd t* the Columns c*llecti*n *9 a particular $ata+able) -n#tead, $ata*ow# are c*n#tructed 3y u#ing the ,ew*ow() +eth*d *9 a particular $ata+able) Here, au+able6,ew*ow() return# a $ata*ow appr*priate t* *ur I=uth*rJ ta3le, !ith it# #ingle I a+eJ c*lu+n) $ata*ow d*e# n*t i+ple+ent BCollection, 3ut d*e# *verl*ad the inde;ing *perat*r, #* a##igning a

4#(

Thinking in C

www.ThinkingIn.!et

value t* a c*lu+n i# a# #i+ple a# #aying1 arryRo.J&Ca!e&K 9 &Larry&. The re9erence returned 3y ,ew*ow() i# not aut*+atically in#erted int* the $ata+able !hich generate# it, that i# d*ne 3y1 au'a$ e.Ro.#.)dd0 arryRo.13 =9ter creating an*ther r*! t* c*ntain Bruce# na+e, the $ata#et i# returned t* the .ain() +eth*d, !hich pr*+ptly pa##e# it t* !rint$ata#etCharacteristics()) The *utput i#1 :ataSet &Goc%:ataSet& ha# " ta$ e# 'a$ e &)uthor#& ha# " co u!n# Co u!n &Ca!e& contain# data of type Sy#te!.String 'he ta$ e contain# 2 ro.# Ro. :ata: JCa!eK 9 Larry Ro. :ata: JCa!eK 9 Bruce

Connecting to a data+ase
The ta#k *9 actually +*ving data in and *ut *9 a #t*re Geither a l*cal 9ile *r a data3a#e #erver *n the net!*rkH i# the ta#k *9 the B$bConnection inter9ace) Speci9ying !hich data G9r*+ all the ta3le# in the underlying data3a#eH i# the re#p*n#i3ility *9 *34ect# !hich i+ple+ent -?3C*++and) =nd 3ridging the gap 3et!een the#e c*ncern# and the c*ncern# *9 the $ata#et i# the re#p*n#i3ility *9 the B$b'dapter inter9ace) Thu#, !hile $ata#et and the cla##e# di#cu##ed in the previ*u# e;a+ple encap#ulate the I!hatJ *9 the relati*nal data, the B$ata'dapter, B$bCommand, and B$bConnection encap#ulate the IH*!J1

Cha"ter '* >olding Eour 123ects

4#1

The ) ET 5ra+e!*rk currently #hip# !ith t!* managed "ro-iders that B$ata'dapter and it# related cla##e#) One i# highEper9*r+ance pr*vider *pti+i7ed 9*r Aicr*#*9t SML ServerQ it i# l*cated in the Sy#te+)?ata)SDlClient na+e#pace) The *ther pr*vider, in the Sy#te+)?ata)Ole?3 na+e#pace, i# 3a#ed *n the 3r*adly availa3le Aicr*#*9t "ET engine G!hich #hip# a# part *9 ,ind*!# BP and i# d*!nl*ada3le 9r*+ Aicr*#*9t# ,e3#iteH) =dditi*nally, y*u can d*!nl*ad an O?BCE#uppp*rting +anaged pr*vider 9r*+ +#dn)+icr*#*9t)c*+) One #u#pect# that highEper9*r+ance +anaged pr*vider# 9*r Oracle, ?B2, and *ther highEend data3a#e# !ill Duietly 3ec*+e availa3le a# ) ET 3egin# t* achieve #igni9icant +arket #hare) 5*r the #a+ple# in thi# chapter, !ere g*ing t* u#e the Ole?3 cla##e# t* read and !rite an =cce## data3a#e, 3ut !ere g*ing t* upca#t everything t* the =?O) ET inter9ace# #* that the c*de i# a# general a# p*##i3le) The I *rth!indJ data3a#e i# a #a+ple data3a#e 9r*+ Aicr*#*9t that y*u can d*!nl*ad 9r*+ http1<<+#dn)+icr*#*9t)c*+<d*!nl*ad# i9 y*u d*nt already have it *n y*ur hardEdrive 9r*+ in#talling Aicr*#*9t =cce##) The 9ile i# called In!ind)+d3J) Unlike !ith enterpri#e data3a#e#, there i# n* need t* run a data3a#e #erver t* c*nnect t* and +anipulate an =cce## data3a#e) Once y*u have the 9ile y*u can 3egin +anipulating it !ith ) ET c*de) Thi# 9ir#t e;a+ple #h*!# the 3a#ic #tep# *9 c*nnecting t* a data3a#e and 9illing a data#et1

4#)

Thinking in C

www.ThinkingIn.!et

//:c0>::BConnect.c# u#ing Sy#te!.:ata3 u#ing Sy#te!.:ata.O e:$3 c a## Ba#ic:ataSetOperation# ; pu$ ic #tatic *oid Gain0#tringJK arg#1; :ataSet d# 9 +!p oyee#0&C.ind.!d$&13 Sy#te!.Con#o e.VriteLine0 &:S fi ed .ith ;0< ro.#&2 d#.'a$ e#J0K.Ro.#.Count13 < pri*ate #tatic :ataSet +!p oyee#0 #tring fi eCa!e1; 5:$Connection cnctn 9 ne. O e:$Connection013 cnctn.ConnectionString9 &-ro*ider9Gicro#oft.`+'.OL+:B.E.03& R &data #ource9& R fi eCa!e3 try ; cnctn.Open013 #tring #e Str 9 &S+L+C' = HROG +G-LO/++S&3 5:ata)dapter adapter 9 ne. O e:$:ata)dapter0#e Str2 cnctn13 :ataSet d# 9 ne. :ataSet0&+!p oyee#&13 adapter.Hi 0d#13 < fina y ; cnctn.C o#e013 < return d#3 < <///:8 =9ter #peci9ying that !ell 3e u#ing the Sy#te+)?ata and Sy#te+)?ata)Ole?3 na+e#pace#, the .ain() initiali7e# a $ata#et !ith the re#ult# *9 a call t* the #tatic 9uncti*n &mployees()) The nu+3er *9 r*!# in the 9ir#t ta3le *9 the re#ult i# printed t* the c*n#*le) The +eth*d &mployees() take# a #tring a# it# para+eter in *rder t* clari9y the part *9 the c*nnecti*n #tring that i# varia3le) -n thi# ca#e, y*ull

Cha"ter '* >olding Eour 123ects

4#3

*3vi*u#ly have t* +ake #ure that the 9ile I !ind)+d3J i# in the current direct*ry *r +*di9y the call appr*priately) -n *rder t* e+pha#i7e that =?O) ET pr*vide# a3#tract data type# 9*r data3a#e c*nnecti*n, a9ter initiali7ing an 1le$bConnection !e upca#t the re#ult t* the B$bConnection inter9ace) The Connection#tring pr*perty i# #et t* a 3are +ini+u+1 the na+e *9 the pr*vider !e intend t* u#e and the data #*urce) Thi# i# all !e need t* c*nnect t* the *rth!ind data3a#e, 3ut enterpri#e data3a#e# !ill *9ten have #igni9icantly +*re c*+ple; c*nnecti*n #tring#) The call t* cnctn61pen() #tart# the actual pr*ce## *9 c*nnecting t* the data3a#e, !hich in thi# ca#e i# a l*cal 9ile read 3ut !hich !*uld typically 3e *ver the net!*rk) Becau#e data3a#e c*nnecti*n# are the pr*t*typical Ivalua3le n*nE+e+*ry re#*urce,J a# di#cu##ed in Chapter #E;cepti*n##, !e put the c*de that interact# !ith the data3a#e in#ide a try`finally 3l*ck) =# !e #aid, the B$ata'dapter i# the 3ridge 3et!een the Ih*!J *9 c*nnecting t* a data3a#e and the I!hatJ *9 a particular relati*nal vie! int* that data) The 3ridge g*ing 9r*+ the data3a#e t* the $ata#et i# the :ill() +eth*d G!hile the 3ridge 9r*+ the $ata#et t* the data3a#e i# the Vpdate() +eth*d !hich !ell di#cu## in *ur ne;t e;a+pleH) H*! d*e# the B$ata'dapter kn*! !hat data t* put int* the $ata#etF The an#!er i# actually n*t de9ined at the level *9 B$ata'dapter) The 1le$b'dapter #upp*rt# #everal p*##i3ilitie#, including aut*+atically 9illing the $ata#et !ith all, *r a #peci9ied #u3#et, *9 rec*rd# in a given ta3le) The $BConnect e;a+ple #h*!# the u#e *9 Structured Muery Language GSMLH, !hich i# pr*3a3ly the +*#t general #*luti*n) -n thi# ca#e, the SML Duery S+L+C' = HROG +G-LO/++S retrieve# all the c*lu+n# and all the data in the EAPLO:EES ta3le *9 the data3a#e) The 1le$b$ata'dapter ha# a c*n#truct*r !hich accept# a #tring G!hich it interpret# a# a SML DueryH and an B$bConnection) Thi# i# the c*n#truct*r !e u#e and upca#t the re#ult t* B$ata'dapter) *! that !e have *ur *pen c*nnecti*n t* the data3a#e and an B$ata'dapter, !e create a ne! $ata#et !ith the na+e IE+pl*yee#)J Thi# e+pty $ata#et i# pa##ed in t* the B$ata'dapter6:ill() +eth*d,

4#4

Thinking in C

www.ThinkingIn.!et

!hich e;ecute# the Duery via the B$bConnection, add# t* the pa##edEin $ata#et the appr*priate $ata+able and $ataColumn *34ect# that repre#ent the #tructure *9 the re#p*n#e, and then create# and add# t* the $ata#et the $ata*ow *34ect# that repre#ent the re#ult#) The B$bConnection i# Closed !ithin a 9inally 3l*ck, 4u#t in ca#e an &xception !a# thr*!n #*+eti+e during the data3a#e *perati*n) 5inally, the 9illed $ata#et i# returned t* .ain(), !hich duti9ully rep*rt# the nu+3er *9 e+pl*yee# in the *rth!ind data3a#e)

7ast 6eading With an I4ata6eader


The pre9erred +eth*d t* get data i# t* u#e an B$ata'dapter t* #peci9y a vie! int* the data3a#e and u#e B$ata'dapter6:ill() t* 9ill up a $ata#et6 =n alternative, i9 all y*u !ant i# a readE*nly 9*r!ard read, i# t* u#e an B$ata*eader) =n B$ata*eader i# a direct, c*nnected iterat*r *9 the underlying data3a#eQ it# likely t* 3e +*re e99icient than 9illing a $ata#et !ith an B$ata'dapter, 3ut the e99iciency reDuire# y*u t* 9*reg* the 3ene9it# *9 a di#c*nnected architecture) Thi# e;a+ple #h*!# the u#e *9 an B$ata*eader *n the &mployees ta3le *9 the *rth!ind data3a#e1 //:c0>::ataReader.c# u#ing Sy#te!3 u#ing Sy#te!.:ata3 u#ing Sy#te!.:ata.O e:$3 c a## :ataReader ; pu$ ic #tatic *oid Gain01; +nu!erate+!p oyee#0&C.ind.!d$&13 < pri*ate #tatic *oid +nu!erate+!p oyee#0 #tring fi eCa!e1; O e:$Connection cnctn 9 ne. O e:$Connection013 cnctn.ConnectionString9 &-ro*ider9Gicro#oft.`+'.OL+:B.E.03& R &data #ource9& R fi eCa!e3 5:ataReader rdr 9 nu 3 try ;

Cha"ter '* >olding Eour 123ects

4#5

cnctn.Open013 5:$Co!!and #e 9 ne. O e:$Co!!and0 &S+L+C' = HROG +G-LO/++S&2 cnctn13 rdr 9 #e .+xecuteReader013 .hi e 0rdr.Read011 ; Sy#te!.Con#o e.VriteLine0 rdrJ&Hir#tCa!e&K R & & R rdrJ&La#tCa!e&K13 < < fina y ; rdr.C o#e013 cnctn.C o#e013 < < <///:8 The &numerate&mployees() +eth*d #tart# like the c*de in the $BConnect e;a+ple, 3ut !e d* n*t upca#t the 1le$bConnection t* B$bConnection 9*r rea#*n# !ell di#cu## #h*rtly) The c*nnecti*n t* the data3a#e i# identical, 3ut !e declare an B$ata*eader rdr and initiali7e it t* null 3e9*re *pening the data3a#e c*nnecti*nQ thi# i# #* that !e can u#e the finally 3l*ck t* Close() the B$ata*eader a# !ell a# the 1le$bConnection) =9ter *pening the c*nnecti*n t* the data3a#e, !e create an 1le$bCommand !hich !e upca#t t* B$bCommand) -n the ca#e *9 the 1le$bCommand c*n#truct*r !e u#e, the para+eter# are a SML #tate+ent and an 1le$bConnection Gthu#, *ur ina3ility t* upca#t in the 9ir#t line *9 the +eth*dH) The ne;t line, rdr 9 #e .+xecuteReader01, e;ecute# the c*++and and return# a connected B$ata*eader) B$ata*eader6*ead() read# the ne;t line *9 the Duery# re#ult, returning false !hen it run# *ut *9 r*!#) Once all the data i# read, the +eth*d enter# a finally 3l*ck, !hich #ever# the B$ata*eader# c*nnecti*n !ith rdr6Close() and then cl*#e# the data3a#e c*nnecti*n entirely !ith cnctn6Close())

4#6

Thinking in C

www.ThinkingIn.!et

C6>4 With )4O.(%,ith $ata#et# and +anaged pr*vider# in hand, 3eing a3le t* create, read, update, and delete rec*rd# in =?O) ET i# near at hand) Creating data !a# c*vered in the Basic$ata#et1perations e;a+ple P u#e $ata+able6,ew*ow() t* generate an appr*priate $ata*ow, 9ill it !ith y*ur data, and u#e $ata+able6*ows6'dd() t* in#ert it int* the $ata#et) Reading data i# d*ne in a 9le;i3le di#c*nnected !ay !ith an B$ata'dapter *r in a 9a#t 3ut c*nnected +anner !ith an B$ata*eader)

>$date and 4elete


The !*rld !*uld 3e a +uch plea#anter place i9 data never needed t* 3e changed *r era#ed2) The#e t!* *perati*n#, e#pecially in a di#c*nnected +*de, rai#e the di#tinct p*##i3ility that t!* pr*ce##e# !ill atte+pt t* per9*r+ inc*+pati3le +anipulati*n *9 the #a+e data) There are t!* *pti*n# 9*r a data3a#e +*del1 =##u+e that any read that +ight end in an edit will end in an edit, and there9*re n*t all*! any*ne el#e t* d* a #i+ilar edita3le read) Thi# +*del i# kn*!n a# pe##i+i#tic c*ncurrency) =##u+e that alth*ugh pe*ple !ill edit and delete r*!#, +ake the en9*rce+ent *9 c*n#i#tency the re#p*n#i3ility *9 #*+e #*9t!are c*+p*nent *ther than the data3a#e c*+p*nent#) Thi# i# *pti+i#tic c*ncurrency, the +*del that =?O) ET u#e#) ,hen an B$b'dapter atte+pt# t* update a r*! that ha# 3een updated #ince the r*! !a# read, the #ec*nd update 9ail# and the adapter thr*!# a $BConcurrency&xception Gn*te the capital TB that vi*late# ) ET# the na+ing c*nventi*nH) =# an e;a+ple1 0) =nn and Ben 3*th read the data3a#e *9 #eat# le9t *n the % =A 9light t* H*n*lulu) There are % #eat# le9t)

*t *nly !*uld it plea#e the hard drive +anu9acturer#Q it !*uld pr*vide a !ay ar*und the #ec*nd la! *9 ther+*dyna+ic#)

Cha"ter '* >olding Eour 123ects

4##

2) =nn and Ben 3*th #elect the 9light, and their client #*9t!are #h*!# . #eat# le9t) /) =nn #u3+it# the change t* the data3a#e and it c*+plete# 9ine) &) Charlie read# the data3a#e, #ee# . #eat# availa3le *n the 9light) ') Ben #u3+it# the change t* the data3a#e) Becau#e =nne# update happened 3e9*re Ben# update, Ben receive# a $BConcurrency&xception) The data3a#e d*e# not accept Ben# change) .) Charlie #elect# a 9light and #u3+it# the change) Becau#e the r*! ha#nt changed #ince Charlie read the data, Charlie# reDue#t #ucceed#) -t i# i+p*##i3le t* give even general advice a# t* !hat t* d* a9ter receiving a $BConcurrency&xception) S*+eti+e# y*ull !ant t* take the data and reEin#ert it int* the data3a#e a# a ne! rec*rd, #*+eti+e# y*ull di#card the change#, and #*+eti+e# y*ull read the ne! data and rec*ncile it !ith y*ur change#) There are even ti+e# !hen #uch an e;cepti*n indicate# a deep l*gical 9la! that call# 9*r a #y#te+ #hutd*!n) Thi# e;a+ple per9*r+# all *9 the CRU? *perati*n#, rereading the data3a#e a9ter the update #* that the #u3#eDuent deleti*n *9 the ne! rec*rd d*e# n*t thr*! a $BConcurrency&xception1 //:c0>:Crud.c# u#ing Sy#te!.:ata3 u#ing Sy#te!.:ata.O e:$3 c a## Crud ; pu$ ic #tatic *oid Gain0#tringJK arg#1; Crud !yCrud 9 ne. Crud013 !yCrud.Read+!p oyee#0&CVind.!d$&13 !yCrud.Create013 !yCrud.Opdate013 //Cece##ary to a*oid :BConcurrency+xception !yCrud.Reread013 !yCrud.:e ete013 < O e:$:ata)dapter adapter3

4#&

Thinking in C

www.ThinkingIn.!et

:ataSet e!p#3 pri*ate *oid Read+!p oyee#0 #tring path'o)cce##:B1; O e:$Connection cnctn 9 ne. O e:$Connection013 cnctn.ConnectionString9 &-ro*ider9Gicro#oft.`+'.OL+:B.E.03& R &data #ource9& R path'o)cce##:B3 cnctn.Open013 #tring #e Str 9 &S+L+C' = HROG +G-LO/++S&3 adapter 9 ne. O e:$:ata)dapter0#e Str2 cnctn13 ne. O e:$Co!!andBui der0adapter13 e!p# 9 ne. :ataSet0&+!p oyee#&13 adapter.Hi 0e!p#13 < pri*ate *oid Create01; :ataRo. r 9 e!p#.'a$ e#J&'a$ e&K.Ce.Ro.013 rJ&Hir#tCa!e&K 9 &Bo$&3 rJ&La#tCa!e&K 9 &:o$$#&3 e!p#.'a$ e#J&'a$ e&K.Ro.#.)dd0r13 adapter.Opdate0e!p#13 < pri*ate *oid Opdate01; :ataRo. aRo. 9 e!p#.'a$ e#J&'a$ e&K.Ro.#J0K3 Sy#te!.Con#o e.VriteLine0 &Hir#t Ca!e: & R aRo.J&Hir#tCa!e&K13 #tring ne.Ca!e 9 nu 3 if0aRo.J&Hir#tCa!e&K.+7ua #0&Cancy&11; ne.Ca!e 9 &)da!&3 <e #e; ne.Ca!e 9 &Cancy&3 < aRo..Begin+dit013 aRo.J&Hir#tCa!e&K 9 ne.Ca!e3 aRo..+nd+dit013 Sy#te!.Con#o e.VriteLine0 &Hir#t Ca!e: & R aRo.J&Hir#tCa!e&K13

Cha"ter '* >olding Eour 123ects

4#'

//Opdate on y happen# no. int iChangedRo.# 9 adapter.Opdate0e!p#13 Sy#te!.Con#o e.VriteLine0&;0< ro.# updated&2 iChangedRo.#13 < pri*ate *oid Reread01; adapter.Hi 0e!p#13 < pri*ate *oid :e ete01; //See!# to return " greater than actua count int iRo. 9 e!p#.'a$ e#J&'a$ e&K.Ro.#.Count3 :ataRo. a#tRo. 9 e!p#.'a$ e#J&'a$ e&K.Ro.#JiRo. 6 "K3 Sy#te!.Con#o e.VriteLine0&:e eting: & R a#tRo.J&Hir#tCa!e&K13 a#tRo..:e ete013 int iChangedRo.# 9 adapter.Opdate0e!p#13 Sy#te!.Con#o e.VriteLine0&;0< ro.# updated&2 iChangedRo.#13 < <///:8 The .ain() +eth*d *utline# !hat !ere g*ing t* d*1 read the IE+pl*yee#J ta3le, create a ne! rec*rd, update a rec*rd, reread the ta3le Gy*u can c*++ent *ut the call t* *eread() i9 y*u !ant t* #ee a $BConcurrency&xceptionH, and delete the rec*rd !e created) The Crud cla## ha# in#tance varia3le# 9*r h*lding the 1le$b$ata'dapter and $ata#et that the vari*u# +eth*d# !ill u#e) *ead&mployees() *pen# the data3a#e c*nnecti*n and create# the adapter 4u#t a# !eve d*ne 3e9*re) The ne;t line1 ne. O e:$Co!!andBui der0adapter13 de+*n#trate# a utility cla## that aut*+atically generate# and #et# !ithin the 1le$b$ata'dapter the SML #tate+ent# that in#ert, update, and delete data in the #a+e ta3le acted *n 3y the #elect c*++and) 1le$bCommandBuilder i# very c*nvenient 9*r SML data adapter# that !*rk *n a #ingle ta3le Gthere# a c*rre#p*nding #%lCommandBuilder

4&(

Thinking in C

www.ThinkingIn.!et

9*r u#e !ith SML ServerH) 5*r +*re c*+ple; adapter# that inv*lve +ultiple ta3le#, y*u have t* #et the c*rre#p*nding BnsertCommand, $eleteCommand, and VpdateCommand pr*pertie# *9 the 1le$b$ata'dapter) The#e c*++and# are needed t* c*++it t* the data3a#e change# +ade in the $ata#et6 The 9ir#t 9*ur line# *9 +eth*d Create() #h*! *perati*n# *n the $ata#et emps that !eve #een 3e9*re P the u#e *9 +able6,ew*ow(), and $ata*owCollection6'dd() t* +anipulate the $ata#et) The 9inal line call# B$ata'dapter6Vpdate(), !hich atte+pt# t* c*++it the change# in the $ata#et t* the 3acking #t*re Git i# thi# +eth*d !hich reDuire# the SML c*++and# generated 3y the 1le$bCommandBuilderH) The +eth*d Vpdate() 3egin# 3y reading the 9ir#t r*! in the emps $ata#et) The call t* $ata*ow6Begin&dit() put# the $ata*ow in a IPr*p*#edJ #tate) Change# pr*p*#ed in a $ata*ow can either 3e accepted 3y a call t* $ata*ow6&nd&dit() *r the 'cceptChanges() +eth*d *9 either the $ata*ow, $ata+able, *r $ata#et) They can 3e cancelled 3y a call t* $ata*ow6Cancel&dit() *r the *e)ectChanges() +eth*d# *9 the cla##e#) =9ter printing the value *9 the 9ir#t r*!# I5ir#t a+eJ c*lu+n, !e put a*ow in a IPr*p*#edJ #tate and change the I5ir#t a+eJ t* I5red)J ,e call Cancel&dit() and #h*! *n the c*n#*le that I5redJ is not the value) -9 the 9ir#t na+e i# currently I ancyJ !ere g*ing t* change it t* I=da+J and vice ver#a) Thi# ti+e, a9ter calling Begin&dit() and +aking the change, !e call &nd&dit()) =t thi# p*int, the data i# changed in the $ata#et, 3ut n*t yet in the data3a#e) The data3a#e c*++it i# per9*r+ed in the ne;t line, !ith an*ther call t* adapter6Vpdate()) Thi# call t* Vpdate() #ucceed#, a# the r*!# *perated *n 3y the t!* call# t* Vpdate() are di99erent) -9, h*!ever, !e !ere t* atte+pt t* update either *9 the#e t!* r*!# !ith*ut rereading the data 9r*+ the data3a#e, !e !*uld get the dread $BConcurrency&xception) Since deleting the r*! !e added i# e;actly *ur intent, .ain() call# *eread() !hich in turn call# adapter6:ill() t* re9ill the emps $ata#et) 5inally, .ain() call# $elete()) The nu+3er *9 r*!# i# retrieved 9r*+ the *ows c*llecti*n) But 3ecau#e the inde; int* r*!# i# $E3a#ed, !e need t* #u3tract 0 9r*+ the t*tal c*unt t* get the inde; *9 the la#t r*! Ge)g), the

Cha"ter '* >olding Eour 123ects

4&1

$ata*ow in a $ata+able !ith a Count *9 0 !*uld 3e acce##ed at *ows<4>H) Once !e have the la#t r*! in the ?ataSet G!hich !ill 3e the IB*3 ?*33#J rec*rd added 3y the Create() +eth*dH, a call t* $ata*ow6$elete() re+*ve# it 9r*+ the $ata#et and $ata'dapter6Vpdate() c*++it# it t* the data3a#e)

-he O+/ect;6elational I#$edance @is#atch


-9 y*u ever 9ind y*ur#el9 un!elc*+e in a cr*!d *9 #u#pici*u# pr*gra++er#, #ay I- !a# !*ndering !hat i# y*ur 9av*rite techniDue 9*r *verc*+ing the *34ectErelati*nal i+pedance +i#+atchFJ Thi# i# like a #ecret hand#hake in pr*gra++er circle#1 n*t *nly d*e# it ann*unce that y*ure n*t 4u#t #*+e L-SP hacker 9re#h 9r*+ Nendall SDuare, it give# y*ur inDui#it*r# a chance t* h*ld 9*rth *n = Aatter *9 >reat -+p*rt) :*u can #ee the r**t# *9 the +i#+atch even in the 3a#ic e;a+ple# !eve #h*!n here) -t# taken u# #everal page# 4u#t t* #h*! h*! t* d* the eDuivalent *9 new and a##ign+ent t* relati*nal dataK =lth*ugh a ta3le i# #*+ething like a cla##, and a r*! i# #*+ething like an in#tance *9 the cla##, ta3le# have n* c*ncept *9 3inding data and 3ehavi*r int* a c*herent !h*le, n*r d*e# the #tandard relati*nal +*del have any c*ncept *9 inheritance) ,*r#e, it# 3ec*+e apparent *ver the year# that there# n* #ingle #trategy 9*r +apping 3et!een *34ect# and ta3le# that i# appr*priate 9*r all need#) Thinking in Cata2ases !*uld 3e a very di99erent 3**k than Thinking in C ) The *34ect and relati*nal +*del# are very di99erent, 3ut c*ntain 4u#t en*ugh #i+ilaritie# #* that the pain ha#nt 3een en*ugh t* trigger a !h*le#ale +*ve+ent t*!ard# *34ect data3a#e# G!hich have 3een the e;t Big Thing in Pr*gra++ing 9*r +*re than a decadeH) HighEper9*r+ing, highlyErelia3le *34ect data3a#e# are availa3le t*day, 3ut have n* +ind#hare in the enterpri#e +arket) ,hat ha# gained +ind#hare i# a hy3rid +*del, !hich c*+3ine# the repetitive #tructure *9 ta3le# and r*!# !ith a hierarchical c*ntain+ent +*del that i# cl*#er t* the *34ect +*del) Thi# hy3rid +*del, e+3*died in BAL, d*e# n*t directly #upp*rt the +*re c*+plicated c*ncept# *9 relati*nal 4*in# *r *34ect inheritance, 3ut i# a g**d !ayp*int *n the r*ad t* *34ect data3a#e#) ,ell di#cu## BAL

4&)

Thinking in C

www.ThinkingIn.!et

in +*re detail in Chapter #BAL# and revi#it =?O) ET in *ur di#cu##i*n *9 dataE3*und c*ntr*l# in Chapter #,ind*!##)

'u##ar5
T* revie! the t**l# in the ) ET 5ra+e!*rk that c*llect *34ect#1 0) =n array a##*ciate# nu+erical indice# t* *34ect#) -t h*ld# *34ect# *9 a kn*!n type #* that y*u d*nt have t* ca#t the re#ult !hen y*ure l**king up an *34ect) -t can 3e +ultidi+en#i*nal in t!* !ay# P rectangular *r 4agged) H*!ever, it# #i7e cann*t 3e changed *nce y*u create it) 2) =n BList h*ld# #ingle ele+ent#, an B$ictionary h*ld# keyEvalue pair#, and a ,ame1b)ectCollectionBase h*ld# #tringEC*llecti*n pair#) /) Like an array, an BList al#* a##*ciate# nu+erical indice# t* *34ect#R y*u can think *9 array# and BList# a# *rdered c*ntainer#) =n B$ictionary *verl*ad# the 3racket *perat*r *9 the array t* +ake it ea#y t* acce## value#, 3ut the underlying i+ple+entati*n i# n*t nece##arily *rdered) &) A*#t c*llecti*n# aut*+atically re#i7e the+#elve# a# y*u add ele+ent#, 3ut the Bit'rray need# t* 3e e;plicitly #i7ed) ') BCollection# h*ld *nly ob)ect re9erence#, #* pri+itive# are 3*;ed and un3*;ed !hen #t*red) ,ith the e;cepti*n *9 typeE#peci9ic c*ntainer# in Sy#te+)C*llecti*n#)Speciali7ed and th*#e y*u r*ll y*ur#el9, y*u +u#t al!ay# ca#t the re#ult !hen y*u pull an ob)ect re9erence *ut *9 a c*ntainer) TypeE#peci9ic c*ntainer cla##e# !ill 3e #upp*rted natively 3y the ) ET runEti+e #*+eti+e in the 9uture) .) ?ata #tructure# have inherent characteri#tic# di#tinct 9r*+ the data that i# #t*red in the+) S*rting, #earching, and traver#al have traditi*nally 3een +atter# *9 great dayEt*Eday i+p*rt) =dvance# in a3#tracti*n and c*+puter p*!er all*! +*#t pr*gra++er# t* ign*re +*#t *9 the#e i##ue# +*#t *9 the ti+e, 3ut *cca#i*nally pr*duce the +*#t challenging and re!arding *pp*rtunitie# in pr*gra++ing)

Cha"ter '* >olding Eour 123ects

4&3

%) =?O) ET pr*vide# an a3#tracti*n *9 the relati*nal data3a#e +*del) $ata#et# repre#ent relati*nal data in +e+*ry, !hile B$ata'dapter# and related cla##e# +*ve the data in and *ut *9 data3a#e#) The c*llecti*n cla##e# are t**l# that y*u u#e *n a dayEt*Eday 3a#i# t* +ake y*ur pr*gra+# #i+pler, +*re p*!er9ul, and +*re e99ective) Th*r*ughly under#tanding the+ and e;tending and c*+3ining the+ t* rapidly #*lve #*luti*n# i# *ne +ark *9 #*9t!are pr*9e##i*nali#+)

%&ercises

4&4

Thinking in C

www.ThinkingIn.!et

1F, %rror 9andling With %&ce$tions


-n the previ*u# chapter, the u#er 3egan e;pl*iting p*!er9ul, c*+ple; li3rarie# t* rapidly pr*duce #y#te+#) Un9*rtunately, #tu99 happen#) The c*ncept *9 Ir*3u#tne##J i# intr*duced and the reader learn# that !hat #eparate# g**d #*9t!are 9r*+ 3ad i# n*t h*! !ell it d*e# the 4*3 !hen thing# are g*ing a# e;pected, 3ut h*! !ell it per9*r+# !hen the unthinka3le happen#) C## language 9eature# and the ) ET 9ra+e!*rk# li3rary 9eature# 9*r dealing !ith e;cepti*n# are c*vered in depth)

Thi# chapter tie# C# t*gether !ith IE;tre+e Pr*gra++ing,J the #et *9 #*9t!are engineering di#cipline# that have gained !ide#pread attenti*n thr*ugh*ut the devel*p+ent !*rld) The critical c*ncept *9 Ite#tE9ir#t c*dingJ !ill 3e intr*duced, a# !ell a# t**l# 9*r aut*+ating BPE#tyle 3uild# in C#)

Cha"ter '* >olding Eour 123ects

4&5

Every pr*gra+ i# 3a#ed *n a va#t array *9 e;pectati*n#) S*+e e;pectati*n# are #* 3a#ic that it d*e#nt +ake #en#e t* !*rry a3*ut the+ P d*e# the current c*+puter have a hardEdrive, #u99icient R=A t* l*ad the pr*gra+, and #* 9*rth) Other e;pectati*n# are e;plicit in the c*de and vi*lati*n# can 3e di#c*vered at c*+pileEti+e P thi# +eth*d take# an integer a# a para+eter, n*t a #tring, that +eth*d return# a 5i#h n*t a 5*!l) The +a4*rity *9 e;pectati*n#, th*ugh, are i+plicit c*ntract# 3et!een +eth*d# and the client c*de that call# the+) ,hen the reality at runti+e i# #uch that an e;pectati*n g*e# un9ul9illed, C# u#e# E;cepti*n# t* #ignal the di#rupti*n *9 the pr*gra+# e;pected 3ehavi*r)
,hen an *34ect can rec*gni7e a pr*3le+ 3ut d*e# n*t have the c*nte;t t* intelligently deal !ith the pr*3le+, rec*very +ay 3e p*##i3le) 5*r in#tance, !hen a net!*rk +e##age i# n*t ackn*!ledged, perhap# a retry i# in *rder, 3ut that deci#i*n #h*uldnt 3e +ade at the l*!e#t level Gnet!*rk ga+e#, 9*r in#tance, *9ten have data *9 varying i+p*rtance, #*+e *9 !hich +u#t 3e ackn*!ledged and #*+e !hich !*uld 3e !*rthle## 3y the ti+e a retry c*uld 3e +adeH) On the *ther hand, a +eth*d +ay have a pr*3le+ 3ecau#e #*+ething i# a!ry !ith the !ay it i# 3eing u#ed P perhap# a pa##ed in para+eter ha# an invalid value Ga !rintCalendar +eth*d i# called 9*r the +*nth IElevente+3erJH *r perhap# the +eth*d can *nly 3e

4&#

+eaning9ully called !hen the *34ect i# in a di99erent #tate G9*r in#tance, a Cancel +eth*d i# called !hen an Btinerary *34ect i# n*t in a I3**kedJ #tateH) The#e +i#u#e #ituati*n# are tricky 3ecau#e there i# n* !ay in C# t* #peci9y a +eth*d# prec*nditi*n# and p*#tc*nditi*n# a# an e;plicit c*ntract P a !ay in #*urce c*de t* #ay Ii9 y*u call +e !ith ;, y, and 7 #ati#9ied, - !ill guarantee that !hen - return c*nditi*n a, 3, and c !ill 3e #ati#9ied Ga##u+ing *9 c*ur#e that all the +eth*d# - call 9ul9ill their c*ntractual *3ligati*n# !ith +eH)J 5*r in#tance, ) ET# Aath cla## ha# a #Duare r**t 9uncti*n that take# a d*u3le a# it# para+eter) Since ) ET d*e# n*t have a cla## t* repre#ent i+aginary nu+3er#, thi# 9uncti*n can *nly return a +eaning9ul an#!er i9 pa##ed a p*#itive value) -9 thi# +eth*d i# called !ith a negative value, i# that an e;cepti*nal c*nditi*n *r a di#app*inting, 3ut predicta3le, #ituati*nF There# n* !ay t* tell 9r*+ the +eth*d# #ignature1 dou$ e Gath.S7rt0dou$ e d13 =lth*ugh prec*nditi*n# and p*#tc*nditi*n# are n*t e;plicit in C# c*de, y*u #h*uld al!ay# think in ter+# *9 c*ntract# !hile pr*gra++ing and d*cu+ent preE and p*#tEc*nditi*n# in y*ur +eth*d# para+ and return# BAL d*cu+entati*n) The ) ET li3rary !riter# 9*ll*!ed thi# advice and the d*cu+entati*n 9*r Aath)SDrtGH e;plain that it !ill return a a G *t = u+3erH value i9 pa##ed a negative para+eter) There i# n* hardEandE9a#t rule t* deter+ine !hat i# an e;cepti*nal c*nditi*n and !hat i# rea#*na3ly 9*re#eea3le) Returning a #pecial Iinvalid

4&&

valueJ #uch a# d*e# Aath)SDrtGH i# de3ata3le, e#pecially i9 the prec*nditi*n i# n*t a# *3vi*u# a# I#Duare r**t# can *nly 3e taken *n p*#itive nu+3er#)J ,hen an e;cepti*nal c*nditi*n *ccur# #uch that a +eth*d cann*t 9ul9ill it# p*#tEc*nditi*n#, there are *nly t!* valid thing# t* d*1 atte+pt t* change the c*nditi*n# that led t* the pr*3le+ and retry the +eth*d, *r I*rgani7ed panicJ P put *34ect# int* c*n#i#tent #tate#, cl*#e *r relea#e n*nE+e+*ry re#*urce#, and +*ve c*ntr*l t* a +uch di99erent c*nte;t that can either per9*r+ a rec*very *r l*g a# +uch in9*r+ati*n a# p*##i3le a3*ut the c*nditi*n leading t* the 9ailure t* help in de3ugging e99*rt#) S*+e pe*ple e+pha#i7e rec*very 9ar t** earlyQ until late in the devel*p+ent *9 a highE availa3ility #y#te+ it# 3etter t* have y*ur #y#te+ 3reak and trigger a de9ectE9i;ing c*ding #e##i*n than t* cleanupEandErec*ver and all*! the de9ect t* c*ntinue) B*th *9 the#e valid ch*ice# Gretrying *r cleanupH u#ually cann*t 3e 9ully d*ne at the p*int !here the e;cepti*nal c*nditi*n *ccurred) ,ith a net!*rk err*r #*+eti+e# 4u#t !aiting a hal9E#ec*nd *r #* and retrying +ay 3e appr*priate, 3ut u#ually a retry reDuire# changing *pti*n# at a higher level *9 a3#tracti*n G9*r in#tance, a 9ileE!riting related err*r +ight 3e retried a9ter giving the u#er a chance t* ch**#e a di99erent l*cati*nH) Si+ilarly, cleanup leading t* either rec*very *r an *rderly #hutd*!n +ay very !ell reDuire 3ehavi*r 9r*+ all the *34ect# in y*ur #y#te+, n*t 4u#t th*#e *34ect# re9erenced 3y the cla## e;periencing the pr*3le+) ,hen an e;cepti*nal c*nditi*n *ccur#, it i# up t* the tr*u3led +eth*d t* create an *34ect *9 a type derived 9r*+ E;cepti*n) Such *34ect# can 3e thrown #* that c*ntr*l +*ve#, n*t t* the ne;t line *9 c*de *r int* a +eth*d call a# i# n*r+ally the ca#e, 3ut rather pr*pagate# t* 3l*ck# *9 c*de that are dedicated t* the ta#k# *9 either rec*very *r cleanup) The *rderly !ay in !hich E;cepti*n# pr*pagate 9r*+ the p*int *9 tr*u3le ha# t!* 3ene9it#) 5ir#t, it +ake# err*rEhandling c*de hierarchical, like a chain *9 c*++and) Perhap# *ne level *9 c*de can g* thr*ugh a #eDuence *9 *pti*n# and retry, 3ut i9 th*#e 9ail, can give up and pr*pagate the c*de t* a higher level *9 a3#tracti*n, !hich +ay per9*r+ a clean #hutd*!n) Sec*nd, e;cepti*n# clean up err*r handling c*de) -n#tead *9 checking 9*r a particular rare 9ailure and dealing !ith it at +ultiple place# in y*ur

Cha"ter 1(* Error >andling with E%ce"tions

4&'

pr*gra+, y*u n* l*nger need t* check at the p*int *9 the +eth*d call G#ince the e;cepti*n !ill pr*pagate right *ut *9 the pr*3le+ area t* a 3l*ck dedicated t* catching itH) =nd, y*u need t* handle the pr*3le+ in *nly *ne place, the #*Ecalled e%ce"tion handler) Thi# #ave# y*u c*de, and it #eparate# the c*de that de#cri3e# !hat y*u !ant t* d* 9r*+ the c*de that i# e;ecuted !hen thing# g* a!ry) -n general, reading, !riting, and de3ugging c*de 3ec*+e# +uch clearer !ith e;cepti*n# than !ith alternative !ay# *9 err*r handling) Thi# chapter intr*duce# y*u t* the c*de y*u need t* !rite t* pr*perly handle e;cepti*n#, and the !ay y*u can generate y*ur *!n e;cepti*n# i9 *ne *9 y*ur +eth*d# get# int* tr*u3le)

3asic e&ce$tions
,hen y*u thr*! an e;cepti*n, #everal thing# happen) 5ir#t, the e;cepti*n *34ect i# created in the #a+e !ay that any C# *34ect i# created1 *n the heap, !ith new) Then the current path *9 e;ecuti*n Gthe *ne y*u c*uldnt c*ntinueH i# #t*pped and the re9erence 9*r the e;cepti*n *34ect i# e4ected 9r*+ the current c*nte;t) =t thi# p*int the e;cepti*n handling +echani#+ take# *ver and 3egin# t* l**k 9*r an appr*priate place t* c*ntinue e;ecuting the pr*gra+) Thi# appr*priate place i# the e%ce"tion handler6 !h*#e 4*3 i# t* rec*ver 9r*+ the pr*3le+ #* the pr*gra+ can either retry the ta#k *r cleanup and pr*pagate either the *riginal E;cepti*n *r, 3etter, a higherEa3#tracti*n E;cepti*n) =# a #i+ple e;a+ple *9 thr*!ing an e;cepti*n, c*n#ider an *34ect re9erence called t that i# pa##ed in a# a para+eter t* y*ur +eth*d) :*ur de#ign c*ntract +ight reDuire a# a prec*nditi*n that t re9er t* a valid, initiali7ed *34ect) Since C# ha# n* #ynta; 9*r en9*rcing prec*nditi*n#, #*+e *ther piece *9 c*de +ay pa## y*ur +eth*d a null re9erence and c*+pile !ith n* pr*3le+) Thi# i# an ea#y prec*nditi*n vi*lati*n t* di#c*ver and there# n* #pecial in9*r+ati*n a3*ut the pr*3le+ that y*u think !*uld 3e help9ul 9*r it# handler#) :*u can #end in9*r+ati*n a3*ut the err*r int* a larger c*nte;t 3y creating an *34ect repre#enting the pr*3le+ and it# c*nte;t and Ithr*!ingJ it *ut *9 y*ur current c*nte;t) Thi# i# called throwing an e%ce"tion. Here# !hat it l**k# like1 if0t 99 nu 1

4'(

Thinking in C

www.ThinkingIn.!et

thro. ne. )rgu!entCu

+xception013

Thi# thr*!# the e;cepti*n, !hich all*!# y*uRin the current c*nte;tRt* a3dicate re#p*n#i3ility 9*r thinking a3*ut the i##ue 9urther) -t# 4u#t +agically handled #*+e!here el#e) Preci#ely where !ill 3e #h*!n #h*rtly)

%&ce$tion argu#ents
Like any *34ect in C#, y*u al!ay# create e;cepti*n# *n the heap u#ing new, !hich all*cate# #t*rage and call# a c*n#truct*r) There are 9*ur c*n#truct*r# in all #tandard e;cepti*n#1 The de9ault, n* argu+ent c*n#truct*r = c*n#truct*r that take# a #tring a# a +e##age1 thro. ne. )rgu!entCu +xception0&t&13 = c*n#truct*r that take# a +e##age and an inner, l*!erElevel E;cepti*n1 thro. ne. -reconditionNio ation+xception0&in*a id t&2 ne. )rgu!entCu +xception0&t&11 =nd a c*n#truct*r that all*!# 9*r a l*t *9 9le;i3ility Ot*d* 9*r!ard re9erence t* #ecti*n dealing !ith Seriali7ati*n-n9*, Strea+ingC*nte;t c*n#truct*r The key!*rd throw cau#e# a nu+3er *9 relatively +agical thing# t* happen) Typically, y*ull 9ir#t u#e new t* create an *34ect that repre#ent# the err*r c*nditi*n) :*u give the re#ulting re9erence t* throw) The *34ect i#, in e99ect, IreturnedJ 9r*+ the +eth*d, even th*ugh that *34ect type i#nt n*r+ally !hat the +eth*d i# de#igned t* return) = #i+pli#tic !ay t* think a3*ut e;cepti*n handling i# a# an alternate return +echani#+, alth*ugh y*u get int* tr*u3le i9 y*u take that anal*gy t** 9ar) :*u can al#* e;it 9r*+ *rdinary #c*pe# 3y thr*!ing an e;cepti*n) But a value i# returned, and the +eth*d *r #c*pe e;it#) =ny #i+ilarity t* an *rdinary return 9r*+ a +eth*d end# here, 3ecau#e where y*u return i# #*+eplace c*+pletely di99erent 9r*+ !here y*u return 9*r a n*r+al +eth*d call) G:*u end up in an appr*priate e;cepti*n handler that +ight 3e +ile# a!ayR+any level# l*!er *n the call #tackR 9r*+ !here the e;cepti*n !a# thr*!n)H

Cha"ter 1(* Error >andling with E%ce"tions

4'1

Typically, y*ull thr*! a di99erent cla## *9 e;cepti*n 9*r each di99erent type *9 err*r) The in9*r+ati*n a3*ut the err*r i# repre#ented 3*th in#ide the e;cepti*n *34ect and i+plicitly in the type *9 e;cepti*n *34ect ch*#en, #* #*+e*ne in the 3igger c*nte;t can 9igure *ut !hat t* d* !ith y*ur e;cepti*n) GO9ten, it# 9ine that the *nly in9*r+ati*n i# the type *9 e;cepti*n *34ect, and n*thing +eaning9ul i# #t*red !ithin the e;cepti*n *34ect)H

Catching an e&ce$tion
-9 a +eth*d thr*!# an e;cepti*n, it +u#t a##u+e that e;cepti*n i# IcaughtJ and dealt !ith) One *9 the advantage# *9 C## e;cepti*n handling i# that it all*!# y*u t* c*ncentrate *n the pr*3le+ y*ure trying t* #*lve in *ne place, and then deal !ith the err*r# 9r*+ that c*de in an*ther place) T* #ee h*! an e;cepti*n i# caught, y*u +u#t 9ir#t under#tand the c*ncept *9 a guarded region6 !hich i# a #ecti*n *9 c*de that +ight pr*duce e;cepti*n#, and !hich i# 9*ll*!ed 3y the c*de t* handle th*#e e;cepti*n#)

-he try +loc*


-9 y*ure in#ide a +eth*d and y*u thr*! an e;cepti*n G*r an*ther +eth*d y*u call !ithin thi# +eth*d thr*!# an e;cepti*nH, that +eth*d !ill e;it in the pr*ce## *9 thr*!ing) -9 y*u d*nt !ant a throw t* e;it the +eth*d, y*u can #et up a #pecial 3l*ck !ithin that +eth*d t* capture the e;cepti*n) Thi# i# called the tr4 2lock 3ecau#e y*u ItryJ y*ur vari*u# +eth*d call# there) The try 3l*ck i# an *rdinary #c*pe, preceded 3y the key!*rd try1 try ; // Code that !ight generate exception# < -9 y*u !ere checking 9*r err*r# care9ully in a pr*gra++ing language that didnt #upp*rt e;cepti*n handling, y*ud have t* #urr*und every +eth*d call !ith #etup and err*r te#ting c*de, even i9 y*u call the #a+e +eth*d #everal ti+e#) ,ith e;cepti*n handling, y*u put everything in a try 3l*ck

4')

Thinking in C

www.ThinkingIn.!et

and capture all the e;cepti*n# in *ne place) Thi# +ean# y*ur c*de i# a l*t ea#ier t* !rite and ea#ier t* read 3ecau#e the g*al *9 the c*de i# n*t c*n9u#ed !ith the err*r checking)

%&ce$tion handlers
O9 c*ur#e, the thr*!n e;cepti*n +u#t end up #*+eplace) Thi# IplaceJ i# the e%ce"tion handler6 and there# *ne 9*r every e;cepti*n type y*u !ant t* catch) E;cepti*n handler# i++ediately 9*ll*! the try 3l*ck and are den*ted 3y the key!*rd catch1 try ; // Code that !ight generate exception# < catch0'ype" id"1 ; // Uand e exception# of 'ype" < catch0'ype2 id21 ; // Uand e exception# of 'ype2 < catch0'ypeT idT1 ; // Uand e exception# of 'ypeT < // etc... Each catch clau#e Ge;cepti*n handlerH i# like a little +eth*d that take# *ne and *nly *ne argu+ent *9 a particular type) The identi9ier Gid7, id8, and #* *nH can 3e u#ed in#ide the handler, 4u#t like a +eth*d argu+ent) S*+eti+e# y*u never u#e the identi9ier 3ecau#e the type *9 the e;cepti*n give# y*u en*ugh in9*r+ati*n t* deal !ith the e;cepti*n, 3ut the identi9ier +u#t #till 3e there) The handler# +u#t appear directly a9ter the try 3l*ck) -9 an e;cepti*n i# thr*!n, the e;cepti*n handling +echani#+ g*e# hunting 9*r the 9ir#t handler !ith an argu+ent that +atche# the type *9 the e;cepti*n) Then it enter# that catch clau#e, and the e;cepti*n i# c*n#idered handled) The #earch 9*r handler# #t*p# *nce the catch clau#e i# 9ini#hed) Only the +atching catch clau#e e;ecute#Q it# n*t like a switch #tate+ent in !hich y*u need a brea( a9ter each case) *te that, !ithin the try 3l*ck, a nu+3er *9 di99erent +eth*d call# +ight generate the #a+e e;cepti*n, 3ut y*u need *nly *ne handler)

Cha"ter 1(* Error >andling with E%ce"tions

4'3

Ot*d*1 Aake #ure that #upertype +atching i# addre##ed near here

%&ce$tions have a hel$lin*

Creating 5our own e&ce$tions


:*ure n*t #tuck u#ing the e;i#ting C# e;cepti*n#) Thi# i# i+p*rtant 3ecau#e y*ull *9ten need t* create y*ur *!n e;cepti*n# t* den*te a #pecial err*r that y*ur li3rary i# capa3le *9 creating, 3ut !hich !a# n*t 9*re#een !hen the C# e;cepti*n hierarchy !a# created) C## prede9ined e;cepti*n# derive 9r*+ Sy#te+E;cepti*n, !hile y*ur e;cepti*n# are e;pected t* derive 9r*+ =pplicati*nE;cepti*n) T* create y*ur *!n e;cepti*n cla##, y*ure 9*rced t* inherit 9r*+ an e;i#ting type *9 e;cepti*n, pre9era3ly *ne that i# cl*#e in +eaning t* y*ur ne! e;cepti*n Gthi# i# *9ten n*t p*##i3le, h*!everH) The +*#t trivial !ay t* create a ne! type *9 e;cepti*n i# 4u#t t* let the c*+piler create the de9ault c*n#truct*r 9*r y*u, #* it reDuire# al+*#t n* c*de at all1 //:c0>:Si!p e+xception:e!o.c# // 5nheriting your o.n exception#. u#ing Sy#te!3 c a## Si!p e+xception : )pp ication+xception ;< pu$ ic c a## Si!p e+xception:e!o ; pu$ ic *oid H01 ; Sy#te!.Con#o e.VriteLine0 &'hro.ing Si!p e+xception fro! H01&13 thro. ne. Si!p e+xception 013 < pu$ ic #tatic *oid Gain01 ; Si!p e+xception:e!o #ed 9 ne. Si!p e+xception:e!o013 try ; #ed.H013 < catch0Si!p e+xception 1 ;

4'4

Thinking in C

www.ThinkingIn.!et

Sy#te!.Con#o e.+rror.VriteLine0&Caught it!&13 < < < ///:8 ,hen the c*+piler create# the de9ault c*n#truct*r, it !hich aut*+atically Gand invi#i3lyH call# the 3a#eEcla## de9ault c*n#truct*r) =# y*ull #ee, the +*#t i+p*rtant thing a3*ut an e;cepti*n i# the cla## na+e, #* +*#t *9 the ti+e an e;cepti*n like the *ne #h*!n a3*ve i# #ati#9act*ry) Here, the re#ult i# printed t* the c*n#*le standard error #trea+ 3y !riting t* #ystem6Console6&rror) Thi# #trea+ can 3e redirected t* any *ther +ext=riter 3y calling #ystem6Console6#et&rror() Gn*te that thi# i# Ta#y++etricJ P the &rror pr*perty d*e#nt #upp*rt a##ign+ent, 3ut there# a #et&rror()) ,hy !*uld thi# 3eFH Creating an e;cepti*n cla## that *verride# the #tandard c*n#truct*r# i# al#* Duite #i+ple1 //:c0>:Hu Con#tructor#.c# u#ing Sy#te!3 c a## Gy+xception : +xception ; pu$ ic Gy+xception01 : $a#e01 ;< pu$ ic Gy+xception0#tring !#g1 : $a#e0!#g1 ;< pu$ ic Gy+xception0#tring !#g2 +xception inner1 : $a#e0!#g2 inner1;< < pu$ ic c a## Hu Con#tructor# ; pu$ ic #tatic *oid H01 ; Sy#te!.Con#o e.VriteLine0 &'hro.ing Gy+xception fro! H01&13 thro. ne. Gy+xception013 < pu$ ic #tatic *oid _01 ; Sy#te!.Con#o e.VriteLine0 &'hro.ing Gy+xception fro! _01&13 thro. ne. Gy+xception0&Originated in _01&13 <

Cha"ter 1(* Error >andling with E%ce"tions

4'5

pu$ ic #tatic *oid U01; try; 5013 <catch0:i*ideBybero+xception e1; Sy#te!.Con#o e.VriteLine0&5ncrea#ing a$#traction e*e &13 thro. ne. Gy+xception0&Originated in U01&2 e13 < < pu$ ic #tatic *oid 501; Sy#te!.Con#o e.VriteLine0&'hi#' trou$ e&13 int y 9 03 int x 9 " / y3 < cau#e

pu$ ic #tatic *oid Gain01 ; try ; H013 < catch0Gy+xception e1 ; Sy#te!.Con#o e.+rror.VriteLine0e.Stac%'race13 < try ; _013 < catch0Gy+xception e1 ; Sy#te!.Con#o e.+rror.VriteLine0e.Ge##age13 < try; U013 <catch0Gy+xception e1; Sy#te!.Con#o e.+rror.VriteLine0e.Ge##age13 Sy#te!.Con#o e.+rror.VriteLine0&5nner exception: & R e.5nner+xception13 Sy#te!.Con#o e.+rror.VriteLine0&Source: & R e.Source13 Sy#te!.Con#o e.+rror.VriteLine0&'argetSite: & R e.'argetSite13 < < < ///:8

4'6

Thinking in C

www.ThinkingIn.!et

The c*de added t* .y&xception i# #+allRthe additi*n *9 three c*n#truct*r# that de9ine the !ay .y&xception i# created) The 3a#eEcla## c*n#truct*r i# e;plicitly inv*ked 3y u#ing the D base key!*rd) The *utput *9 the pr*gra+ i#1 'hro.ing Gy+xception fro! H01 at Hu Con#tructor#.H01 at Hu Con#tructor#.Gain01 'hro.ing Gy+xception fro! _01 Originated in _01 'hi#' cau#e trou$ e 5ncrea#ing a$#traction e*e Originated in U01 5nner exception: Sy#te!.:i*ideBybero+xception: )tte!pted to di*ide $y Mero. at Hu Con#tructor#.501 at Hu Con#tructor#.U01 Source: Hu Con#tructor# 'argetSite: Noid U01 :*u can #ee the a3#ence *9 the detail +e##age in the .y&xception thr*!n 9r*+ :( )) The 3l*ck that catche# the e;cepti*n thr*!n 9r*+ :() #h*!# the #tack trace all the !ay t* the *rigin *9 the e;cepti*n) Thi# i# pr*3a3ly the +*#t help9ul pr*perty in E;cepti*n and i# a great aid t* de3ugging) ,hen "() e;ecute#, it call# B(), !hich atte+pt# an illegal arith+etic *perati*n) The atte+pt t* divide 3y 7er* thr*!# a $ivideBy\ero&xception Gde+*n#trating the truth *9 the previ*u# #tate+ent a3*ut the type na+e 3eing the +*#t i+p*rtant thingH) "() catche# the $ivideBy\ero&xception, 3ut increa#e# the a3#tracti*n level 3y !rapping it in a .y&xception) Then, !hen the .y&xception i# caught in .ain(), !e can #ee the inner e;cepti*n and it# *rigin in B()) The #ource pr*perty c*ntain# the na+e *9 the a##e+3ly that thre! the e;cepti*n, !hile the +arget#ite pr*perty return# a handle t* the +eth*d that thre! the e;cepti*n) +arget#ite i# appr*priate 9*r #*phi#ticated re9lecti*nE3a#ed e;cepti*n diagn*#tic# and handling)

Cha"ter 1(* Error >andling with E%ce"tions

4'#

The pr*ce## *9 creating y*ur *!n e;cepti*n# can 3e taken 9urther) :*u can add e;tra c*n#truct*r# and +e+3er#1 //:c0>:+xtraHeature#.c# // Hurther e!$e i#h!ent of exception c a##e#. u#ing Sy#te!3 c a## Gy+xception2 : +xception ; int errorCode3 pu$ ic int +rrorCode; get ; return errorCode3 < < pu$ ic Gy+xception201 : $a#e01;< pu$ ic Gy+xception20#tring !#g1 : $a#e0!#g1 ;< pu$ ic Gy+xception20#tring !#g2 int errorCode1 : $a#e0!#g1 ; thi#.errorCode 9 errorCode3 < < pu$ ic c a## +xtraHeature# ; pu$ ic #tatic *oid H01 ; Sy#te!.Con#o e.VriteLine0 &'hro.ing Gy+xception2 fro! H01&13 thro. ne. Gy+xception2013 < pu$ ic #tatic *oid _01 ; Sy#te!.Con#o e.VriteLine0 &'hro.ing Gy+xception2 fro! _01&13 thro. ne. Gy+xception20&Originated in _01&13 < pu$ ic #tatic *oid U01 ; Sy#te!.Con#o e.VriteLine0 &'hro.ing Gy+xception2 fro! U01&13 thro. ne. Gy+xception20 &Originated in U01&2 EF13 < pu$ ic #tatic *oid Gain0StringJK arg#1 ;

4'&

Thinking in C

www.ThinkingIn.!et

try ; H013 < catch0Gy+xception2 e1 ; Sy#te!.Con#o e.+rror.VriteLine0e.Stac%'race13 < try ; _013 < catch0Gy+xception2 e1 ; Sy#te!.Con#o e.+rror.VriteLine0e.Stac%'race13 < try ; U013 < catch0Gy+xception2 e1 ; Sy#te!.Con#o e.+rror.VriteLine0e.Stac%'race13 Sy#te!.Con#o e.+rror.VriteLine0&e.+rrorCode 9 & R e.+rrorCode13 < < < ///:8 = pr*perty &rrorCode ha# 3een added, al*ng !ith an additi*nal c*n#truct*r that #et# it) The *utput i#1 'hro.ing Gy+xception2 fro! H01 at +xtraHeature#.H01 in ::^tic^exception#^+xtraHeature#.c#: ine at +xtraHeature#.Gain0StringJK arg#1 C:^:ocu!ent# and Setting#^ arry^Gy :ocu!ent#^+xtraHeature#.c#: ine TI 'hro.ing Gy+xception2 fro! _01 at +xtraHeature#._01 in ::^tic^exception#^+xtraHeature#.c#: ine at +xtraHeature#.Gain0StringJK arg#1 ::^tic^exception#^+xtraHeature#.c#: ine 'hro.ing Gy+xception2 fro! U01 at +xtraHeature#.U01 in ::^tic^exception#^+xtraHeature#.c#: ine

2T in

2I in ET

TT

Cha"ter 1(* Error >andling with E%ce"tions

4''

at +xtraHeature#.Gain0StringJK arg#1 in C:^:ocu!ent# and Setting#^ arry^Gy :ocu!ent#^+xtraHeature#.c#: ine EI e.+rrorCode 9 EF Since an e;cepti*n i# 4u#t an*ther kind *9 *34ect, y*u can c*ntinue thi# pr*ce## *9 e+3elli#hing the p*!er *9 y*ur e;cepti*n cla##e#) =n err*r c*de, a# illu#trated here, i# pr*3a3ly n*t very u#e9ul, #ince the type *9 the E;cepti*n give# y*u a g**d idea *9 the I!hatJ *9 the pr*3le+) A*re intere#ting !*uld 3e t* e+3ed a clue a# t* the Ih*!J *9 retrying *r cleanup P #*+e kind *9 *34ect that encap#ulated the c*nte;t *9 the 3r*ken c*ntract) Neep in +ind, h*!ever, that the 3e#t de#ign i# the *ne that thr*!# e;cepti*n# rarely and that the 3e#t pr*gra++er i# the *ne !h*#e !*rk deliver# the +*#t 3ene9it t* the cu#t*+er, n*t the *ne !h* c*+e# up !ith the clevere#t #*luti*n t* !hat t* d* !hen thing# g* !r*ngK

C#s Lac* O0 Chec*ed %&ce$tions


S*+e language#, n*ta3ly "ava, reDuire a +eth*d t* li#t rec*vera3le e;cepti*n# it +ay thr*!) Thu#, in "ava, reading data 9r*+ a #trea+ i# d*ne !ith a +eth*d that i# declared a# int read01 thro.# 5O+xception !hile the eDuivalent +eth*d in C# i# #i+ply int read01) Thi# d*e# n*t +ean that C# #*+eh*! av*id# the vari*u# un9*re#eea3le circu+#tance# that can ruin a read, n*r even that they are nece##arily le## likely t* *ccur in C#) -9 y*u l**k at the d*cu+entati*n 9*r Sy#te!.5O.Strea!.Read01 y*ull #ee that it can thr*!, ye#, an B1&xception) The e99ect *9 including a li#t *9 e;cepti*n# in a +eth*d# declarati*n i# that at c*+pileEti+e, i9 the +eth*d i# u#ed, the c*+piler can a##ure that the E;cepti*n i# either handled *r pa##ed *n) Thu#, in language# like "ava, the e;cepti*n i# e;plicitly part *9 the +eth*d# #ignature P IPa## +e para+eter# *9 type #uch and #* and -ll return a value *9 a certain type) H*!ever, i9 thing# g* a!ry, - +ay al#* thr*! the#e particular type# *9 E;cepti*n)J "u#t a# the c*+piler can en9*rce that a +eth*d that take# an

5((

Thinking in C

www.ThinkingIn.!et

int and return# a #tring i# n*t pa##ed a d*u3le *r u#ed t* a##ign t* a 9l*at #* t** d*e# the c*+piler en9*rce the E;cepti*n #peci9icati*n) Checked e;cepti*n# #uch a# in "ava are n*t intended t* deal !ith prec*nditi*n vi*lati*n#, !hich are 3y 9ar the +*#t c*++*n cau#e *9 e;cepti*nal c*nditi*n#) = prec*nditi*n vi*lati*n Gcalling a +eth*d !ith an i+pr*per para+eter, calling a #tateE#peci9ic +eth*d *n an *34ect that# n*t in the reDuired #tateH i#, 3y de9initi*n, the re#ult *9 a pr*gra++ing err*r) Retrie# are, at 3e#t, u#ele## in #uch a #ituati*n Gat !*r#t, the retry !ill !*rk and there3y all*! the pr*gra++ing err*r t* g* un9i;edKH) S* "ava ha# an*ther type *9 e;cepti*n that i# unchecked) -n practice !hat happen# i# that !hile pr*gra++er# are generally accepting *9 #tr*ng typeEchecking !hen it c*+e# t* para+eter# and return value#, the value *9 #tr*ngly typed e;cepti*n# i# n*t nearly a# evident in realE!*rld practice) There are t** +any l*!Elevel thing# that can g* !r*ng G9ailure# *9 9ile# and net!*rk# and R=A and #* 9*rthH and +any pr*gra++er# d* n*t #ee the 3ene9it *9 creating an a3#tracti*n hierarchy a# they deal !ith all 9ailure# in a generic +anner) =nd the di99erent intent *9 checked and unchecked e;cepti*n# i# c*n9u#ing t* +any devel*per#) =nd thu# *ne #ee# a great deal *9 "ava c*de in t!* eDually 3ad 9*r+#1 +eaningle## pr*pagati*n *9 l*!Ea3#tracti*n e;cepti*n# G,e3 #ervice# that are declared a# thr*!ing -OE;cepti*n#H and I+ake it c*+pileJ hack# !here +eth*d# are declared a# Ithr*!# E;cepti*nJ Gin *ther !*rd#, #aying I- can thr*! anything - darn !ell plea#e)JH) ,*r#e, th*ugh, it# n*t unc*++*n t* #ee the very !*r#t p*##i3le I#*luti*n,J !hich i# t* catch and ign*re the e;cepti*n, all 9*r the #ake *9 getting a clean c*+pile) The*retically, i9 y*ure g*ing t* have a #tr*ngly typed language, it pr*3a3ly +ake# #en#e 9*r e;cepti*n# t* 3e part *9 the +eth*d #ignature) Prag+atically, th*ugh, the prevalence *9 3ad e;cepti*nEhandling c*de in "ava argue# 9*r C## appr*ach, !hich i# e##entially that the 3urden i# *n the pr*gra++er t* kn*! t* place err*rEhandling c*de in the appr*priate place#)

Catching an5 e&ce$tion


-t i# p*##i3le t* create a handler that catche# any type *9 e;cepti*n) :*u d* thi# 3y catching the 3a#eEcla## e;cepti*n type &xception1

Cha"ter 1(* Error >andling with E%ce"tions

5(1

catch0+xception e1 ; Sy#te!.Con#o e.+rror.VriteLine0&Caught an exception&13 < Thi# !ill catch any e;cepti*n, #* i9 y*u u#e it y*ull !ant t* put it at the end *9 y*ur li#t *9 handler# t* av*id pree+pting any e;cepti*n handler# that +ight *ther!i#e 9*ll*! it) Since the &xception cla## i# the 3a#e *9 all the e;cepti*n cla##e#, y*u d*nt get +uch #peci9ic in9*r+ati*n a3*ut the #peci9ic pr*3le+) :*u d*, h*!ever, get #*+e +eth*d# 9r*+ ob)ect Gevery3*dy# 3a#e typeH) The *ne that +ight c*+e in handy 9*r e;cepti*n# i# et+ype(), !hich return# an *34ect repre#enting the cla## *9 this) :*u can in turn read the ,ame pr*perty *9 thi# +ype *34ect) :*u can al#* d* +*re #*phi#ticated thing# !ith +ype *34ect# that arent nece##ary in e;cepti*n handling) +ype *34ect# !ill 3e #tudied later in thi# 3**k)

6ethrowing an e&ce$tion
S*+eti+e# y*ull !ant t* rethr*! the e;cepti*n that y*u 4u#t caught, particularly !hen y*u u#e catch(&xception) t* catch any e;cepti*n) Since y*u already have the re9erence t* the current e;cepti*n, y*u can #i+ply rethr*! that re9erence1 catch0+xception e1 ; Sy#te!.Con#o e.+rror.VriteLine0&)n exception .a# thro.n&13 thro. e3 < Rethr*!ing an e;cepti*n cau#e# the e;cepti*n t* g* t* the e;cepti*n handler# in the ne;tEhigher c*nte;t) =ny 9urther catch clau#e# 9*r the #a+e try 3l*ck are #till ign*red) -n additi*n, everything a3*ut the e;cepti*n *34ect i# pre#erved, #* the handler at the higher c*nte;t that catche# the #peci9ic e;cepti*n type can e;tract all the in9*r+ati*n 9r*+ that *34ect)

5()

Thinking in C

www.ThinkingIn.!et

%levating the a+straction level


U#ually !hen catching e;cepti*n# and then pr*pagating the+ *ut!ard, y*u #h*uld elevate the a3#tracti*n level *9 the caught E;cepti*n) 5*r in#tance, at the 3u#ine##El*gic level, all y*u +ay care a3*ut i# that Ithe charge didnt g* thr*ugh)J :*ull certainly !ant t* pre#erve the in9*r+ati*n *9 the le##Ea3#tract E;cepti*n 9*r de3ugging purp*#e#, 3ut 9*r l*gical purp*#e#, y*u !ant t* deal !ith all pr*3le+# eDually) //:c0>:Rethro..c# u#ing Sy#te!3 na!e#pace Rethro.; c a## 'ran#actionHai ure+xception : )pp ication+xception ; pu$ ic 'ran#actionHai ure+xception0+xception e1 : $a#e0&Logica fai ure cau#ed $y o.6 e*e exception&2 e1; < < c a## 'ran#action ; Rando! r 9 ne. Rando!013 pu$ ic *oid -roce##01; try ; if 0r.Cext:ou$ e01 Z 0.T1 ; thro. ne. )rith!etic+xception013 < e #e ; if 0r.Cext:ou$ e01 Z 0.P1 ; thro. ne. Hor!at+xception013 < < < catch 0+xception e1 ; 'ran#actionHai ure+xception tfe 9 ne. 'ran#actionHai ure+xception0e13 thro. tfe3 < < <

Cha"ter 1(* Error >andling with E%ce"tions

5(3

c a## Bu#ine##Logic ; 'ran#action !y'ran#action 9 ne. 'ran#action013 pu$ ic *oid :oCharge01; try ; !y'ran#action.-roce##013 Sy#te!.Con#o e.VriteLine0&'ran#action .ent through&13 < catch 0'ran#actionHai ure+xception tfe1 ; Sy#te!.Con#o e.VriteLine0tfe.Ge##age13 Sy#te!.Con#o e.+rror.VriteLine0tfe.5nner+xception13 < < pu$ ic #tatic *oid Gain01; Bu#ine##Logic $ 9 ne. Bu#ine##Logic013 for 0int i 9 03 i W "03 iRR1 ; $ .:oCharge013 < < < < ///:8

-n thi# e;a+ple, the cla## +ransaction ha# an e;cepti*n cla## that i# at it# #a+e level *9 a3#tracti*n in +ransaction:ailure&xception) The try`catch(&xception eH c*n#truct in +ransaction6!rocess() +ake# 9*r a nice and e;plicit c*ntract1 I- try t* return v*id, 3ut i9 anything g*e# a!ry in +y pr*ce##ing, - +ay thr*! a +ransaction:ailed&xception)J -n *rder t* generate #*+e e;cepti*n#, !e u#e a rand*+ nu+3er generat*r t* thr*! di99erent type# *9 l*!Elevel e;cepti*n# in +ransaction6!rocess()) =ll e;cepti*n# are caught in +ransaction6!rocess()# catch 3l*ck, !here they are placed Iin#ideJ a ne! +ransaction:ailure&xception u#ing that type# *verridden c*n#truct*r that take# an e;cepti*n and

5(4

Thinking in C

www.ThinkingIn.!et

create# a generic IL*gical 9ailure cau#ed 3y l*!Elevel e;cepti*nJ +e##age) The c*de then thr*!# the ne!ly created +ransaction:ailure&xception, !hich i# in turn caught 3y BusinessLogic6$oCharge()# catch(+ransaction:ailure&xception tfe) 3l*ck) The higherE a3#tracti*n e;cepti*n# +e##age i# printed t* the C*n#*le, !hile the l*!erEa3#tracti*n e;cepti*n i# #ent t* the Err*r #trea+ G!hich i# al#* the c*n#*le, 3ut the p*int i# that there i# a #eparati*n 3et!een the t!* level# *9 a3#tracti*n) -n practice, the higherEa3#tracti*n e;cepti*n !*uld 3e u#ed 9*r 3u#ine## l*gic ch*ice# and the l*!erEa3#tracti*n e;cepti*n 9*r de3uggingH)

'tandard C# e&ce$tions
The C# cla## &xception de#cri3e# anything that can 3e thr*!n a# an e;cepti*n) There are t!* general type# *9 &xception *34ect# GItype# *9J X Iinherited 9r*+JH) #ystem&xception repre#ent# e;cepti*n# in the Sy#te+ na+e#pace and it# de#cendant# Gin *ther !*rd#, ) ET# #tandard e;cepti*n#H) :*ur e;cepti*n# 3y c*nventi*n #h*uld e;tend 9r*+ 'pplication&xception) -9 y*u 3r*!#e the ) ET d*cu+entati*n, y*ull #ee that each na+e#pace ha# a #+all hand9ul *9 e;cepti*n# that are at a level *9 a3#tracti*n appr*priate t* the na+e#pace) 5*r in#tance, Sy#te+)-O ha# an BnternalBuffer1verflow&xception, !hich i# pretty darn l*!Elevel, !hile Sy#te+),e3)Service#)Pr*t*c*l# ha# #oap&xception, !hich i# pretty darn highElevel) -t# !*rth 3r*!#ing thr*ugh the#e e;cepti*n# *nce t* get a 9eel 9*r the vari*u# e;cepti*n#, 3ut y*ull #**n #ee that there i#nt anything #pecial 3et!een *ne e;cepti*n and the ne;t e;cept 9*r the na+e) The 3a#ic idea i# that the na+e *9 the e;cepti*n repre#ent# the pr*3le+ that *ccurred, and the e;cepti*n na+e i# intended t* 3e relatively #el9E e;planat*ry)

Cha"ter 1(* Error >andling with E%ce"tions

5(5

Per0or#ing cleanu$ with 0inall5


There# *9ten #*+e piece *9 c*de that y*u !ant t* e;ecute !hether *r n*t an e;cepti*n i# thr*!n !ithin a try 3l*ck) Thi# u#ually pertain# t* #*+e *perati*n *ther than +e+*ry rec*very G#ince that# taken care *9 3y the gar3age c*llect*rH) T* achieve thi# e99ect, y*u u#e a finally clau#e at the end *9 all the e;cepti*n handler#) The 9ull picture *9 an e;cepti*n handling #ecti*n i# thu#1 try ; // 'he guarded region: :angerou# acti*itie# // that !ight thro. )2 B2 or C < catch0) a"1 ; // Uand er for #ituation ) < catch0B $"1 ; // Uand er for #ituation B < catch0C c"1 ; // Uand er for #ituation C < fina y ; // )cti*itie# that happen e*ery ti!e < -n finally 3l*ck#, y*u can u#e c*ntr*l 9l*! #tate+ent# brea(, continue, *r goto *nly 9*r l**p# that are entirely in#ide the finally 3l*ckQ y*u cann*t per9*r+ a 4u+p *ut *9 the finally 3l*ck) Si+ilarly, y*u can n*t u#e return in a finally 3l*ck) Ci*lating the#e rule# !ill give a c*+piler err*r) T* de+*n#trate that the finally clau#e al!ay# run#, try thi# pr*gra+1 //:c0>:) .ay#Hina y.c# // 'he fina y c au#e i# a .ay# executed. u#ing Sy#te!3 c a## 'hree+xception : )pp ication+xception ;< pu$ ic c a## Hina yVor%# ; #tatic int count 9 03

5(6

Thinking in C

www.ThinkingIn.!et

pu$ ic #tatic *oid Gain01 ; .hi e0true1; try; if0countRR W T1; thro. ne. 'hree+xception013 < Sy#te!.Con#o e.VriteLine0&Co exception&13 < catch0'hree+xception 1 ; Sy#te!.Con#o e.VriteLine0&'hree+xception&13 < fina y ; Sy#te!.Con#o e.+rror.VriteLine0&5n fina y c au#e&13 //! if0count 99 T1 $rea%3 W6 Co!pi er error < if0count Z T1 $rea%3 < < < ///:8 Thi# pr*gra+ al#* give# a hint 9*r h*! y*u can deal !ith the 9act that e;cepti*n# in C# d* n*t all*! y*u t* re#u+e 3ack t* !here the e;cepti*n !a# thr*!n, a# di#cu##ed earlier) -9 y*u place y*ur try 3l*ck in a l**p, y*u can e#ta3li#h a c*nditi*n that +u#t 3e +et 3e9*re y*u c*ntinue the pr*gra+) :*u can al#* add a static c*unter *r #*+e *ther device t* all*! the l**p t* try #everal di99erent appr*ache# 3e9*re giving up) Thi# !ay y*u can 3uild a greater level *9 r*3u#tne## int* y*ur pr*gra+#) The *utput i#1 'hree+xception 5n fina y c au#e 'hree+xception 5n fina y c au#e 'hree+xception 5n fina y c au#e Co exception 5n fina y c au#e ,hether an e;cepti*n i# thr*!n *r n*t, the finally clau#e i# al!ay# e;ecuted)

Cha"ter 1(* Error >andling with E%ce"tions

5(#

Whats finally 0or<


Since C# ha# a gar3age c*llect*r, relea#ing +e+*ry i# virtually never a pr*3le+) S* !hy d* y*u need finallyF finally i# nece##ary !hen y*u need t* #et #*+ething other than +e+*ry 3ack t* it# *riginal #tate) Thi# i# #*+e kind *9 cleanup like an *pen 9ile *r net!*rk c*nnecti*n, #*+ething y*uve dra!n *n the #creen, *r even a #!itch in the *ut#ide !*rld, a# +*deled in the 9*ll*!ing e;a+ple1 //:c0>:VhyHina y.c# // Vhy u#e fina yY u#ing Sy#te!3 c a## S.itch ; $oo #tate 9 fa #e3 pu$ ic $oo Read; get ; return #tate3 < #et ; #tate 9 *a ue3 < < pu$ ic *oid On01; #tate 9 true3 < pu$ ic *oid Off01; #tate 9 fa #e3 < < c a## OnOff+xception" : +xception ;< c a## OnOff+xception2 : +xception ;< pu$ ic c a## OnOffS.itch ; #tatic S.itch #. 9 ne. S.itch013 #tatic *oid H01 ;< pu$ ic #tatic *oid Gain01 ; try ; #..On013 // Code that can thro. exception#... H013 #..Off013 < catch0OnOff+xception" 1 ; Sy#te!.Con#o e.VriteLine0&OnOff+xception"&13 #..Off013 < catch0OnOff+xception2 1 ; Sy#te!.Con#o e.VriteLine0&OnOff+xception2&13

5(&

Thinking in C

www.ThinkingIn.!et

#..Off013 < < < ///:8 The g*al here i# t* +ake #ure that the #!itch i# *99 !hen .ain( ) i# c*+pleted, #* sw61ff( ) i# placed at the end *9 the try 3l*ck and at the end *9 each e;cepti*n handler) But it# p*##i3le that an e;cepti*n c*uld 3e thr*!n that i#nt caught here, #* sw61ff( ) !*uld 3e +i##ed) H*!ever, !ith finally y*u can place the cleanup c*de 9r*+ a try 3l*ck in 4u#t *ne place1 //:c0>:VhyHina y2.c# // Vhy u#e fina yY u#ing Sy#te!3 c a## S.itch ; $oo #tate 9 fa #e3 pu$ ic $oo Read; get ; return #tate3< #et ; #tate 9 *a ue3< < pu$ ic *oid On01; #tate 9 true3< pu$ ic *oid Off01; #tate 9 fa #e3< < c a## OnOff+xception" : +xception ; < c a## OnOff+xception2 : +xception ; < pu$ ic c a## OnOffS.itch ; #tatic S.itch #. 9 ne. S.itch013 #tatic *oid H01 ;< pu$ ic #tatic *oid Gain01 ; try ; #..On013 // Code that can thro. exception#... H013 < catch 0OnOff+xception" 1 ;

Cha"ter 1(* Error >andling with E%ce"tions

5('

Sy#te!.Con#o e.VriteLine0&OnOff+xception"&13 < catch 0OnOff+xception2 1 ; Sy#te!.Con#o e.VriteLine0&OnOff+xception2&13 < fina y ; #..Off013 < < < ///:8 Here the sw61ff( ) ha# 3een +*ved t* 4u#t *ne place, !here it# guaranteed t* run n* +atter !hat happen#) Even in ca#e# in !hich the e;cepti*n i# n*t caught in the current #et *9 catch clau#e#, finally !ill 3e e;ecuted 3e9*re the e;cepti*n handling +echani#+ c*ntinue# it# #earch 9*r a handler at the ne;t higher level1 //:c0>:Ce#tedHina y.c# // Hina y i# a .ay# executed. u#ing Sy#te!3 c a## Hour+xception : )pp ication+xception ;< pu$ ic c a## ) .ay#Hina y ; pu$ ic #tatic *oid Gain01 ; Sy#te!.Con#o e.VriteLine0 &+ntering fir#t try $ oc%&13 try ; Sy#te!.Con#o e.VriteLine0 &+ntering #econd try $ oc%&13 try ; thro. ne. Hour+xception013 < fina y ; Sy#te!.Con#o e.VriteLine0 &fina y in 2nd try $ oc%&13 < < catch0Hour+xception 1 ; Sy#te!.Con#o e.VriteLine0 &Caught Hour+xception in "#t try $ oc%&13 < fina y ;

51(

Thinking in C

www.ThinkingIn.!et

Sy#te!.Con#o e.VriteLine0 &fina y in "#t try $ oc%&13 < < < ///:8 The *utput 9*r thi# pr*gra+ #h*!# y*u !hat happen#1 +ntering fir#t try $ oc% +ntering #econd try $ oc% fina y in 2nd try $ oc% Caught Hour+xception in "#t try $ oc% fina y in "#t try $ oc%

7inall5 and using


,ay 3ack in Chapter #initiali7ati*n and cleanup#, !e di#cu##ed C## using 3l*ck#) *! !e can 9inally e;plain h*! it !*rk#) C*n#ider thi# c*de, !hich u#e# inheritance, upca#ting, and a try`finally 3l*ck t* en#ure that cleanup happen#1 //:c0>:O#ingC eanup.c# u#ing Sy#te!3 c a## O#ingC eanup : 5:i#po#a$ e ; pu$ ic #tatic *oid Gain01; try ; 5:i#po#a$ e uc 9 ne. O#ingC eanup013 try ; thro. ne. Cot5!p e!ented+xception013 < fina y ; uc.:i#po#e013 < <catch0+xception 1; Sy#te!.Con#o e.VriteLine0&)fter di#po#a &13 < < O#ingC eanup01;

Cha"ter 1(* Error >andling with E%ce"tions

511

ca

Sy#te!.Con#o e.VriteLine0&Con#tructor ed&13 < pu$ ic *oid :i#po#e01; Sy#te!.Con#o e.VriteLine0&:i#po#e ca < ed&13

8O#ingC eanup01; Sy#te!.Con#o e.VriteLine0&:e#tructor ca < <//:8 :*u #h*uld n*t 3e #urpri#ed at the *utput1 Con#tructor ca ed :i#po#e ca ed )fter di#po#a :e#tructor ca ed Changing the .ain() +eth*d t*1

ed&13

pu$ ic #tatic *oid Gain01; try ; O#ingC eanup uc 9 ne. O#ingC eanup013 u#ing0uc1; thro. ne. Cot5!p e!ented+xception013 < <catch0+xception 1; Sy#te!.Con#o e.VriteLine0&)fter di#po#a &13 < < pr*duce# the e;act #a+e *utput) -n 9act, the using key!*rd i# 4u#t I#yntactic #ugarJ that !rap# an B$isposable #u3type in a try`finally 3l*ckK Behind the #cene#, the e;act #a+e c*de i# generated, 3ut the using 3l*ck i# ter#er)

Pit0all, the lost e&ce$tion


-n general, C## e;cepti*n i+ple+entati*n i# Duite *ut#tanding, 3ut un9*rtunately there# a 9la!) =lth*ugh e;cepti*n# are an indicati*n *9 a

51)

Thinking in C

www.ThinkingIn.!et

cri#i# in y*ur pr*gra+ and #h*uld never 3e ign*red, it# p*##i3le 9*r an e;cepti*n t* #i+ply 3e l*#t) Thi# happen# !ith a particular c*n9igurati*n u#ing a finally clau#e1 //:c0>:Lo#t+xception.c# // Uo. an exception can $e u#ing Sy#te!3 o#t.

c a## Nery5!portant+xception : +xception ; < c a## UoUu!+xception : +xception ; < pu$ ic c a## Lo#tGe##age ; *oid H01 ; thro. ne. Nery5!portant+xception013 < *oid :i#po#e01 ; thro. ne. UoUu!+xception013 < pu$ ic #tatic *oid Gain01; try ; Lo#tGe##age ! 9 ne. Lo#tGe##age013 try ; !.H013 < fina y ; !.:i#po#e013 < < catch 0+xception e1 ; Sy#te!.Con#o e.VriteLine0e13 < < < ///:8 The *utput i#1 UoUu!+xception: +xception of type UoUu!+xception .a# thro.n. at Lo#tGe##age.:i#po#e01 at Lo#tGe##age.Gain01

Cha"ter 1(* Error >andling with E%ce"tions

513

:*u can #ee that there# n* evidence *9 the HeryBmportant&xception, !hich i# #i+ply replaced 3y the "o"um&xception in the finally clau#e) Thi# i# a rather #eri*u# pit9all, #ince it +ean# that an e;cepti*n can 3e c*+pletely l*#t, and in a 9ar +*re #u3tle and di99icultEt*Edetect 9a#hi*n than the e;a+ple a3*ve) -n c*ntra#t, C@@ treat# the #ituati*n in !hich a #ec*nd e;cepti*n i# thr*!n 3e9*re the 9ir#t *ne i# handled a# a dire pr*gra++ing err*r) T* av*id thi# p*##i3ility, it i# a g**d idea t* !rap all y*ur !*rk in#ide a finally 3l*ck in a try`catch(&xception)D //:c0>:Carefu Hina u#ing Sy#te!3 y.c#

c a## Nery5!portant+xception : +xception ; < c a## UoUu!+xception : +xception ; < pu$ ic c a## Lo#tGe##age ; *oid H01 ; thro. ne. Nery5!portant+xception013 < *oid :i#po#e01 ; thro. ne. UoUu!+xception013 < pu$ ic #tatic *oid Gain01; try ; Lo#tGe##age ! 9 ne. Lo#tGe##age013 try ; !.H013 < fina y ; try; !.:i#po#e013 <catch0+xception e1; Sy#te!.Con#o e.VriteLine0e13 < < < catch 0+xception e1 ; Sy#te!.Con#o e.VriteLine0e13 < <

514

Thinking in C

www.ThinkingIn.!et

< ///:8 Pr*duce# the de#ired *utput1 UoUu!+xception: +xception of type UoUu!+xception .a# thro.n. at Lo#tGe##age.:i#po#e01 at Lo#tGe##age.Gain01 Nery5!portant+xception: +xception of type Nery5!portant+xception .a# thro.n. at Lo#tGe##age.H01 at Lo#tGe##age.Gain01

Constructors
,hen !riting c*de !ith e;cepti*n#, it# particularly i+p*rtant that y*u al!ay# a#k, I-9 an e;cepti*n *ccur#, !ill thi# 3e pr*perly cleaned upFJ A*#t *9 the ti+e y*ure 9airly #a9e, 3ut in c*n#truct*r# there# a pr*3le+) The c*n#truct*r put# the *34ect int* a #a9e #tarting #tate, 3ut it +ight per9*r+ #*+e *perati*nR#uch a# *pening a 9ileRthat d*e#nt get cleaned up until the u#er i# 9ini#hed !ith the *34ect and call# a #pecial cleanup +eth*d) -9 y*u thr*! an e;cepti*n 9r*+ in#ide a c*n#truct*r, the#e cleanup 3ehavi*r# +ight n*t *ccur pr*perly) Thi# +ean# that y*u +u#t 3e e#pecially diligent !hile y*u !rite y*ur c*n#truct*r) Since y*uve 4u#t learned a3*ut finally, y*u +ight think that it i# the c*rrect #*luti*n) But it# n*t Duite that #i+ple, 3ecau#e finally per9*r+# the cleanup c*de e-er4 time6 even in the #ituati*n# in !hich y*u d*nt !ant the cleanup c*de e;ecuted until the cleanup +eth*d run#) Thu#, i9 y*u d* per9*r+ cleanup in finally, y*u +u#t #et #*+e kind *9 9lag !hen the c*n#truct*r 9ini#he# n*r+ally #* that y*u d*nt d* anything in the finally 3l*ck i9 the 9lag i# #et) Becau#e thi# i#nt particularly elegant Gy*u are c*upling y*ur c*de 9r*+ *ne place t* an*therH, it# 3e#t i9 y*u try t* av*id per9*r+ing thi# kind *9 cleanup in finally unle## y*u are 9*rced t*) -n the 9*ll*!ing e;a+ple, a cla## called Bnput:ile i# created that *pen# a 9ile and all*!# y*u t* read it *ne line Gc*nverted int* a #tringH at a ti+e) -t u#e# the cla##e# :ile*eader and Buffered*eader 9r*+ the "ava #tandard -<O li3rary that !ill 3e di#cu##ed in Chapter 00, 3ut !hich are

Cha"ter 1(* Error >andling with E%ce"tions

515

#i+ple en*ugh that y*u pr*3a3ly !*nt have any tr*u3le under#tanding their 3a#ic u#e1 //:c0>:Con#tructorHina y.c# // -aying attention to exception# // in con#tructor#. u#ing Sy#te!3 u#ing Sy#te!.5O3 na!e#pace C eanup; interna c a## 5nputHi e : 5:i#po#a$ e ; pri*ate Strea!Reader inStrea!3 interna 5nputHi e0#tring fCa!e1 ; try ; inStrea! 9 ne. Strea!Reader0 ne. Hi eStrea!0 fCa!e2 Hi eGode.Open113 // Other code that !ight thro. exception# < catch 0Hi eCotHound+xception e1 ; Sy#te!.Con#o e.+rror.VriteLine0 &Cou d not open & R fCa!e13 // Va#n't open2 #o don't c o#e it thro. e3 < catch 0+xception e1 ; // ) other exception# !u#t c o#e it try ; inStrea!.C o#e013 < catch 05O+xception 1 ; Sy#te!.Con#o e.+rror.VriteLine0 &in.C o#e01 un#ucce##fu &13 < thro. e3 // Rethro. < fina y ; // :on't c o#e it here!!! < <

516

Thinking in C

www.ThinkingIn.!et

interna #tring ReadLine01 ; #tring #3 try ; # 9 inStrea!.ReadLine013 < catch 05O+xception 1 ; Sy#te!.Con#o e.+rror.VriteLine0 &ReadLine01 un#ucce##fu &13 # 9 &fai ed&3 < return #3 < pu$ ic *oid :i#po#e01 ; try ; inStrea!.C o#e013 < catch 05O+xception 1 ; Sy#te!.Con#o e.+rror.VriteLine0 &in.C o#e01 un#ucce##fu &13 < < < pu$ ic c a## C eanup ; pu$ ic #tatic *oid Gain01 ; try ; 5nputHi e inHi e 9 ne. 5nputHi e0&C eanup.c#&13 u#ing0inHi e1; String #3 int i 9 "3 .hi e 00# 9 inHi e.ReadLine011 !9 nu 1 Sy#te!.Con#o e.VriteLine0 &&R iR R R &: & R #13 < < catch 0+xception e1 ; Sy#te!.Con#o e.+rror.VriteLine0 &Caught in Gain&13

Cha"ter 1(* Error >andling with E%ce"tions

51#

Sy#te!.Con#o e.+rror.VriteLine0 e.Stac%'race13 < < < < ///:8 The c*n#truct*r 9*r Bnput:ile take# a string argu+ent, !hich i# the na+e *9 the 9ile y*u !ant t* *pen) -n#ide a try 3l*ck, it create# a :ile#tream u#ing the 9ile na+e) = :ile#tream i#nt particularly u#e9ul 9*r te;t until y*u turn ar*und and u#e it t* create a #tream*eader that can deal !ith +*re than *ne character at a ti+e) -9 the :ile#tream c*n#truct*r i# un#ucce##9ul, it thr*!# a :ile,ot:ound&xception, !hich +u#t 3e caught #eparately 3ecau#e that# the *ne ca#e in !hich y*u d*nt !ant t* cl*#e the 9ile #ince it !a#nt #ucce##9ully *pened) =ny other catch clau#e# +u#t cl*#e the 9ile 3ecau#e it was *pened 3y the ti+e th*#e catch clau#e# are entered) GO9 c*ur#e, thi# i# trickier i9 +*re than *ne +eth*d can thr*! a :ile,ot:ound&xception) -n that ca#e, y*u +ight !ant t* 3reak thing# int* #everal try 3l*ck#)H The Close( ) +eth*d +ight thr*! an e;cepti*n #* it i# tried and caught even th*ugh it# !ithin the 3l*ck *9 an*ther catch clau#eRit# 4u#t an*ther pair *9 curly 3race# t* the C# c*+piler) =9ter per9*r+ing l*cal *perati*n#, the e;cepti*n i# rethr*!n, !hich i# appr*priate 3ecau#e thi# c*n#truct*r 9ailed, and y*u !*uldnt !ant the calling +eth*d t* a##u+e that the *34ect had 3een pr*perly created and !a# valid) -n thi# e;a+ple, !hich d*e#nt u#e the a9*re+enti*ned 9lagging techniDue, the finally clau#e i# de9initely not the place t* Close( ) the 9ile, #ince that !*uld cl*#e it every ti+e the c*n#truct*r c*+pleted) Since !e !ant the 9ile t* 3e *pen 9*r the u#e9ul li9eti+e *9 the Bnput:ile *34ect thi# !*uld n*t 3e appr*priate) The *eadLine( ) +eth*d return# a string c*ntaining the ne;t line in the 9ile) -t call# #tream*eader6*eadLine( ), !hich can thr*! an e;cepti*n, 3ut that e;cepti*n i# caught #* *eadLine( ) d*e#nt thr*! any e;cepti*n#)

51&

Thinking in C

www.ThinkingIn.!et

The $ispose( ) +eth*d +u#t 3e called !hen the Bnput:ile i# 9ini#hed !ith) Thi# !ill relea#e the #y#te+ re#*urce# G#uch a# 9ile handle#H that are u#ed 3y the #tream*eader and<*r :ile#tream *34ect#) :*u d*nt !ant t* d* thi# until y*ure 9ini#hed !ith the Bnput:ile *34ect, at the p*int y*ure g*ing t* let it g*) :*u +ight think *9 putting #uch 9uncti*nality int* a de#truct*r +eth*d, 3ut a# +enti*ned in Chapter #initiali7ati*n and cleanup# y*u cant al!ay# 3e #ure !hen the de#truct*r !ill 3e called Geven i9 y*u can 3e #ure that it !ill 3e called, all y*u kn*! a3*ut when i# that it# #ure t* 3e called 3e9*re the pr*ce## end#H) -n the Cleanup cla##, an Bnput:ile i# created t* *pen the #a+e #*urce 9ile that create# the pr*gra+, the 9ile i# read in a line at a ti+e, and line nu+3er# are added) The using key!*rd i# u#ed t* en#ure that Bnput:ile6$ispose() i# called) =ll e;cepti*n# are caught generically in .ain( ), alth*ugh y*u c*uld ch**#e greater granularity) One *9 the 3ene9it# *9 thi# e;a+ple i# t* #h*! y*u !hy e;cepti*n# are intr*duced at thi# p*int in the 3**kRy*u cant d* 3a#ic -<O !ith*ut u#ing e;cepti*n#) E;cepti*n# are #* integral t* pr*gra++ing in C# that y*u can acc*+pli#h *nly #* +uch !ith*ut kn*!ing h*! t* !*rk !ith the+)

%&ce$tion #atching
,hen an e;cepti*n i# thr*!n, the e;cepti*n handling #y#te+ l**k# thr*ugh the Ineare#tJ handler# in the *rder they are !ritten) ,hen it 9ind# a +atch, the e;cepti*n i# c*n#idered handled, and n* 9urther #earching *ccur#) Aatching an e;cepti*n d*e#nt reDuire a per9ect +atch 3et!een the e;cepti*n and it# handler) = derivedEcla## *34ect !ill +atch a handler 9*r the 3a#e cla##, a# #h*!n in thi# e;a+ple1 //:c0>:SneeMe.c# // Catching exception hierarchie#. u#ing Sy#te!3 c a## )nnoyance : +xception ;< c a## SneeMe : )nnoyance ;< pu$ ic c a## Uu!an ;

Cha"ter 1(* Error >andling with E%ce"tions

51'

pu$ ic #tatic *oid Gain01 ; try ; thro. ne. SneeMe013 < catch0SneeMe 1 ; Sy#te!.Con#o e.+rror.VriteLine0&Caught SneeMe&13 < catch0)nnoyance 1 ; Sy#te!.Con#o e.+rror.VriteLine0&Caught )nnoyance&13 < < < ///:8 The #neeTe e;cepti*n !ill 3e caught 3y the 9ir#t catch clau#e that it +atche#R!hich i# the 9ir#t *ne, *9 c*ur#e) H*!ever, i9 y*u re+*ve the 9ir#t catch clau#e, leaving *nly1 try ; thro. ne. SneeMe013 < catch0)nnoyance1 ; Sy#te!.Con#o e.+rror.VriteLine0&Caught )nnoyance&13 < The c*de !ill #till !*rk 3ecau#e it# catching the 3a#e cla## *9 #neeTe) Put an*ther !ay, catch('nnoyance e) !ill catch an 'nnoyance or an4 class deri-ed $rom it) Thi# i# u#e9ul 3ecau#e i9 y*u decide t* add +*re derived e;cepti*n# t* a +eth*d, then the client pr*gra++er# c*de !ill n*t need changing a# l*ng a# the client catche# the 3a#e cla## e;cepti*n#) -9 y*u try t* I+a#kJ the derivedEcla## e;cepti*n# 3y putting the 3a#eEcla## catch clau#e 9ir#t, like thi#1 try ; thro. ne. SneeMe013 < catch0)nnoyance a1 ; Sy#te!.Con#o e.+rror.VriteLine0&Caught )nnoyance&13 < catch0SneeMe #1 ; Sy#te!.Con#o e.+rror.VriteLine0&Caught SneeMe&13 <

5)(

Thinking in C

www.ThinkingIn.!et

the c*+piler !ill give y*u an err*r +e##age, #ince it #ee# that the #neeTe catchEclau#e can never 3e reached)

%&ce$tion guidelines
U#e e;cepti*n# t*1 () 5i; the pr*3le+ and call the +eth*d that cau#ed the e;cepti*n again) 6) Patch thing# up and c*ntinue !ith*ut retrying the +eth*d) 0$) Calculate #*+e alternative re#ult in#tead *9 !hat the +eth*d !a# #upp*#ed t* pr*duce) 00) ?* !hatever y*u can in the current c*nte;t and rethr*! the same e;cepti*n t* a higher c*nte;t) 02) ?* !hatever y*u can in the current c*nte;t and thr*! a di$$erent e;cepti*n t* a higher c*nte;t) 0/) Ter+inate the pr*gra+) 0&) Si+pli9y) G-9 y*ur e;cepti*n #che+e +ake# thing# +*re c*+plicated, then it i# pain9ul and ann*ying t* u#e)H 0') Aake y*ur li3rary and pr*gra+ #a9er) GThi# i# a #h*rtEter+ inve#t+ent 9*r de3ugging, and a l*ngEter+ inve#t+ent G9*r applicati*n r*3u#tne##)H

'u##ar5
-+pr*ved err*r rec*very i# *ne *9 the +*#t p*!er9ul !ay# that y*u can increa#e the r*3u#tne## *9 y*ur c*de) Err*r rec*very i# a 9unda+ental c*ncern 9*r every pr*gra+ y*u !rite, 3ut it# e#pecially i+p*rtant in C#, !here *ne *9 the pri+ary g*al# i# t* create pr*gra+ c*+p*nent# 9*r *ther# t* u#e) To create a ro2ust s4stem6 each com"onent must 2e ro2ust. E;cepti*n# are n*t terri3ly di99icult t* learn, and are *ne *9 th*#e 9eature# that pr*vide i++ediate and #igni9icant 3ene9it# t* y*ur pr*4ect)

Cha"ter 1(* Error >andling with E%ce"tions

5)1

Ktodo S (ew Cha$ter< 4esign 35 Contract


,herea# C# ha# n* checked e;cepti*n#, and "ava ha# checked e;cepti*n# that en9*rce the pr*pagati*n and handling *9 th*#e e;cepti*n# 3a#ed *n 3ad pr*gra+ #tate, 3ut d*e# n*thing t* diagn*#e prec*nditi*n and p*#tc*nditi*n vi*lati*n#, the Ei99el pr*gra++ing all*!# *ne t* #peci9y a +eth*d# c*ntract e;plicitly) The c*ncept *9 an e;plicit declarati*n *9 a +eth*d# c*ntract and a largely aut*+atic !ay t* validate that c*ntract lie# at the heart *9 IE;tre+e Pr*gra++ing,J the #et *9 di#cipline# !hich have recently gained great attenti*n) The e##ential disci"line in E;tre+e Pr*gra++ing i# called Ite#tE9ir#t pr*gra++ing)J The te#t#, in thi# ca#e, are unit te#t# P e;erci#e# *9 a cla### #et *9 c*ntract#) The accepta3ility *9 thi# di#cipline i# dependent up*n +aking the creati*n and e;ecuti*n *9 te#t #uite# a# #traight9*r!ard a# p*##i3leQ pr*gra++er# !ill n*t !rite te#t c*de i9 d*ing #* i# n*t very ea#y) U#ing C## attri3ute#, it i# p*##i3le 9*r a 9ra+e!*rk t* Idi#c*verJ +eth*d# that are +arked a# te#t#)

%&ercises

5))

Thinking in C

www.ThinkingIn.!et

11, I?O in C#
Creating a g**d input<*utput G-<OH #y#te+ i# *ne *9 the +*re di99icult ta#k# 9*r the language de#igner)
Thi# i# evidenced 3y the nu+3er *9 di99erent appr*ache#) The challenge #ee+# t* 3e in c*vering all eventualitie#) *t *nly are there di99erent #*urce# and #ink# *9 -<O that y*u !ant t* c*++unicate !ith G9ile#, the c*n#*le, net!*rk c*nnecti*n#H, 3ut y*u need t* talk t* the+ in a !ide variety *9 !ay# G#eDuential, rand*+Eacce##, 3u99ered, 3inary, character, 3y line#, 3y !*rd#, etc)H) The ) ET li3rary de#igner# attacked thi# pr*3le+ 3y creating l*t# *9 cla##e#) -n 9act, there are #* +any cla##e# 9*r ) ET# -<O #y#te+ that it can 3e inti+idating at 9ir#t Gir*nically, the de#ign actually prevent# an e;pl*#i*n *9 cla##e#H) =# a re#ult there are a 9air nu+3er *9 cla##e# t* learn 3e9*re y*u under#tand en*ugh *9 ) ET# -<O picture t* u#e it pr*perly)

%ile. &irectory. and !ath


Be9*re getting int* the cla##e# that actually read and !rite data t* #trea+#, !ell l**k at the utility cla##e# that a##i#t y*u in handling 9ile direct*ry i##ue#) The#e utility cla##e# c*n#i#t *9 three cla##e# that have 4u#t

5)3

#tatic +eth*d#1 !ath, $irectory, and :ile) The#e cla##e# have #*+e!hat c*n9u#ing na+e# in that there# n* c*rre#p*ndence 3et!een *34ect in#tance# and ite+# !ithin the 9ileE#y#te+ Gindeed, y*u cant in#tantiate the#e cla##e# P their c*n#truct*r# are n*t pu3licH)

) director5 lister
Let# #ay y*u !ant t* li#t the na+e# *9 the 9ile# in the direct*ry) Thi# i# ea#ily d*ne !ith the #tatic $irectory6 et:iles() +eth*d, a# i# #h*!n in thi# #a+ple1 //c"":HLi#t.c# //:i#p ay# directory u#ing Sy#te!.5O3 i#ting

pu$ ic c a## HLi#t; pu$ ic #tatic *oid Gain0#tringJK arg#1; #tring dir'oRead 9 &.&3 #tring pattern 9 &=&3 if0arg#.Length Z 01; dir'oRead 9 arg#J0K3 < if0arg#.Length Z "1; pattern 9 arg#J"K3 < #tringJK f-ath# 9 :irectory._etHi e#0dir'oRead2 pattern13 foreach0#tring f-ath in f-ath#1;

5)4

Hi e5nfo f5nfo 9 ne. Hi e5nfo0f-ath13 Sy#te!.Con#o e.VriteLine0 &-ath 9 ;0< Hi ena!e: ;"< ext: ;2< & R &touch: ;T< #iMe: ;E<&2 f-ath2 f5nfo.Ca!e2 f5nfo.+xten#ion2 f5nfo.La#tVrite'i!e2 f5nfo.Length13 Sy#te!.Con#o e.VriteLine0fCa!e13 < < <///:8 ,hen run !ith n* argu+ent#, thi# return# all the na+e# in the current direct*ryQ an*ther direct*ry can 3e #peci9ied !ith the 9ir#t argu+ent, and a #tandard ?OS 9ilena+e pattern !ith the #ec*nd) =n *verl*ad *9 the $irectory6 et:iles() +eth*d take# 4u#t a #ingle #tring, !hich i# eDuivalent t* calling $irectory6 et:iles(dir#tring, G;G)6 The +eth*d $irectory6 et:iles() i# a little p**rly na+ed, it# really returned #tring# that repre#ent the path# t* 9ile# G#* perhap# it !*uld have 3een 3etter na+ed et:ile!aths()H) T* get in9*r+ati*n *n the c*rre#p*nding 9ile, the path i# pa##ed in t* a :ileBnfo c*n#truct*r) The :ileBnfo and related $irectoryBnfo cla##e# encap#ulate !hat the 9ile #y#te+ kn*!# P thing# like #i7e, ti+e *9 creati*n and la#t edit, attri3ute# #uch a# 3eing ReadOnly, etc)

Chec*ing 0or and creating directories


The :List pr*gra+ a3*ve returned *nly path# t* 9ile#, n*t t* direct*rie#) $irectory6 et:ile#ystem&ntries() return# path# t* 3*th 9ile# and direct*rie#, !hile $irectory6 et$irectories() return# path# t* the #u3direct*rie# *9 the given direct*ry) //c"": :irLi#t.c# //:i#p ay# i#ting of #u$directorie# u#ing Sy#te!.5O3 pu$ ic c a## :irLi#t; pu$ ic #tatic *oid Gain0#tringJK arg#1; #tring dir'oRead 9 &.&3 #tring pattern 9 &=&3

Cha"ter 11* The ,a-a IF1 @4stem

5)5

if0arg#.Length Z 01; dir'oRead 9 arg#J0K3 < if0arg#.Length Z "1; pattern 9 arg#J"K3 < #tringJK #u$dir# 9 :irectory._et:irectorie#0 dir'oRead2 pattern13 foreach0#tring #u$dir in #u$dir#1; :irectory5nfo d5nfo 9 ne. :irectory5nfo0#u$dir13 Sy#te!.Con#o e.VriteLine0 &-ath 9 ;0< Created: ;"< )cce##ed: ;2< & R & Vritten to ;T< &2 #u$dir2 d5nfo.Creation'i!e2 d5nfo.La#t)cce##'i!e2 d5nfo.La#tVrite'i!e13 < < <///:8 -n additi*n t* getting in9*r+ati*n *n 9ile# and direct*rie#, the :ile and $irectory cla##e# c*ntain +eth*d# 9*r creating, deleting, and +*ving 9ile#y#te+ entitie#) Thi# e;a+ple #h*!# h*! t* create ne! #u3direct*rie#, 9ile#, and delete direct*rie#1 //:c"":Hi eGanip //:e!on#trate# $a#ic fi e#y#te! !anipu ation u#ing Sy#te!3 u#ing Sy#te!.5O3 c a## Hi eGanip; pu$ ic #tatic *oid Gain01; #tring cur-ath 9 :irectory._etCurrent:irectory013 :irectory5nfo cur:ir 9 ne. :irectory5nfo0cur-ath13 #tring curCa!e 9 cur:ir.Ca!e3 charJK char# 9 curCa!e.'oChar)rray013 )rray.Re*er#e0char#13 #tring re*Ca!e 9 ne. String0char#13 if0:irectory.+xi#t#0re*Ca!e11;

5)6

Thinking in C

www.ThinkingIn.!et

:irectory.:e ete0re*Ca!e2 true13 <e #e; :irectory.Create:irectory0re*Ca!e13 #tring fCa!e 9 &./& R re*Ca!e R &/Hoo.fi e&3 Hi e.Create0fCa!e13 < < <///:8 5ir#t, !e u#e $irectory6 etCurrent$irectory() t* retrieve the current pathQ the #a+e data i# al#* availa3le a# &nvironment6Current$irectory) T* get the current direct*ry# na+e, !e u#e the $irectoryBnfo cla## and it# ,ame pr*perty) The na+e *9 *ur ne! direct*ry i# the current direct*ry# na+e in rever#e) The 9ir#t ti+e thi# pr*gra+ run#, $irectory6&xists() !ill return 9al#e Gunle## y*u happen t* run thi# pr*gra+ in a direct*ry !ith a rever#edEna+e #u3direct*ry already thereKH) -n that ca#e, !e u#e $irectory6Create$irectory() and :ile6Create() Gn*te the #light inc*n#i#tency in na+ingH t* create a ne! #u3direct*ry and a 9ile) -9 y*u check, y*ull #ee that I5**)9ileJ i# *9 length $ P :ile6Create() !*rk# at the 9ile#y#te+ level, n*t at the level *9 actually initiali7ing the 9ile !ith u#e9ul data) The #ec*nd ti+e :ile.anip i# run, the &xists() +eth*d !ill return true and $irectory6$elete() delete# 3*th the direct*ry and all its contents6 including $iles and su2directories) -9 y*u d*nt !ant thi# highly danger*u# 3ehavi*r, either pa## in a false value, *r u#e the *verl*aded $irectory6$elete(string) !hich d*e#nt take a 3**l and !hich !ill thr*! an B1&xception i9 called *n a n*nEe+pty direct*ry)

'solated Stores
S*+e *9 the +*#t c*++*n 9ileE*riented ta#k# are a##*ciated !ith a #ingle u#er1 pre9erence# #h*uld 3e #et t* individual u#er#, #ecurity dictate# that there 3e re#tricti*n# *n ar3itrary 9ile +anipulati*n 3y c*+p*nent# d*!nl*aded *99 the ,e3, etc) -n the#e #cenari*#, the ) ET 5ra+e!*rk pr*vide# 9*r isolated storage) =n i#*lated #t*re i# a virtual 9ile #y#te+ !ithin a data com"artment) = data c*+part+ent i# 3a#ed *n the u#er, a##e+3ly, and perhap# *ther a#pect# *9 the c*de# identity Ge)g), it# #ignatureH) -#*lated #t*rage i# 9*r th*#e #ituati*n# !hen y*u d*nt need *r !ant data3a#eElevel #ecurity and c*ntr*lQ i#*lated #t*re# end up a# 9ile# *n

Cha"ter 11* The ,a-a IF1 @4stem

5)#

the hardEdrive and !hile *peratingE#y#te+ re#tricti*n# +ay prevent the+ 9r*+ 3eing ca#ually availa3le, it# n*t appr*priate t* u#e i#*lated #t*rage 9*r highEvalue data) >etting an i#*lated #t*re 9*r the current a##e+3ly i# #traight9*r!ard i9 !*rdy, *ne u#e# a #tatic +eth*d called etVser#tore:or'ssembly() in the Bsolated#torage:ile cla##1 //c"":5#oStore.c# u#ing Sy#te!.5O.5#o atedStorage3 c a## 5#oStore; pu$ ic #tatic *oid Gain01; 5#o atedStorageHi e i#f 9 5#o atedStorageHi e._etO#erStoreHor)##e!$ y013 Sy#te!.Con#o e.VriteLine0 &)##e!$ y identity ;0< ^n& R &CurrentSiMe ;"< ^n& R &Gaxi!u!SiMe ;2< ^n& R &Scope ;T< ^n&2 i#f.)##e!$ y5dentity2 i#f.CurrentSiMe2 i#f.Gaxi!u!SiMe2 i#f.Scope13 < <///:8 5ir#t, !e have t* #peci9y that !ere u#ing the #ystem6B16Bsolated#torage na+e#pace) =9ter !e create the i#*lated #t*re, !e print #*+e *9 it# attri3ute# t* the c*n#*le) = typical run l**k# like thi#1 )##e!$ y identity WSy#te!.Security.-o icy.Or *er#ion9&"&Z WOr Zfi e://::/tic/chap""/5#oStore.exeW/Or Z W/Sy#te!.Security.-o icy.Or Z CurrentSiMe 0 Gaxi!u!SiMe >22TTF20T?IPEFFPI0F Scope O#er2 )##e!$ y Becau#e !eve n*t d*ne any digital #igning G#ee chapter ##ecurity#H, the identit4 *9 the a##e+3ly thi# i# 3eing run 9r*+ i# #i+ply the na+e *9 the

5)&

Thinking in C

www.ThinkingIn.!et

a##e+3ly a# a URL) The #t*re c*n#u+e# n* #pace currently and !*uld 3e all*!ed t* c*n#u+e a# +uch a# 6>B) The #t*re that !eve g*t a handle *n i# a##*ciated !ith the u#er and a##e+3ly# identityQ i9 !e changed either *9 th*#e, !ed get a di99erent i#*lated #t*re) The Bsolated:ile#tore i# e##entially a virtual 9ile #y#te+, 3ut un9*rtunately it d*e# n*t #upp*rt the general #ystem6B1 cla##e# #uch a# $irectory, $irectoryBnfo, :ile, and :ileBnfo) Rather, the Bsolated:ile#tore cla## ha# #tatic +eth*d# et$irectory,ames() and et:ile,ames() !hich c*rre#p*nd t* $irectory6 et$irectories() and $irectory6 et:ile,ames()) Thi# i# Duite clu+#y, a# *ne cann*t u#e *34ect# t* traver#e d*!n a tree *9 direct*rie# Ga# *ne can d* !ith the $irectory cla##H, 3ut rather +u#t per9*r+ #tring +anipulati*n t* c*n#truct path# !ithin the i#*lated #t*re) H*pe9ully 9uture ver#i*n# *9 the 9ra+e!*rk !ill +*ve t*!ard# c*n#i#tency !ith the #ystem6B1 na+e#pace#)

In$ut and out$ut


-<O li3rarie# *9ten u#e the a3#tracti*n *9 a stream, !hich repre#ent# any data #*urce *r #ink a# an *34ect capa3le *9 pr*ducing *r receiving piece# *9 data) The #trea+ hide# the detail# *9 !hat happen# t* the data in#ide the actual -<O device) The C# li3rary cla##e# 9*r -<O are divided 3y input and *utput, a# y*u can #ee 3y e;a+ining the *nline help re9erence t* the ) ET 5ra+e!*rk) By inheritance, everything derived 9r*+ the #tream cla## ha# 3a#ic +eth*d# called ReadGH, ReadByteGH, ,riteGH, and ,riteByteGH 9*r reading and !riting array# and #ingle 3yte#) H*!ever, y*u !*nt generally u#e the#e +eth*d#Q they e;i#t #* that *ther cla##e# can u#e the+Rthe#e *ther cla##e# pr*vide a +*re u#e9ul inter9ace) Thu#, y*ull rarely create an *34ect 9*r input *r *utput 3y u#ing a #ingle cla##, 3ut in#tead !ill layer +ultiple *34ect# t*gether t* pr*vide y*ur de#ired 9uncti*nality) The 9act that y*u create +*re than *ne *34ect t* create a #ingle re#ulting #trea+ i# the pri+ary rea#*n that ) ET# -O li3rary i# c*n9u#ing) =n*ther #ad 9act*r that c*ntri3ute# t* c*n9u#i*n i# that, al*ne *9 all the +a4*r ) ET na+e#pace#, the #ystem6B1 na+e#pace vi*late# g**d *34ectE *riented de#ign principle#) -n chapter #inheritance#, !e #p*ke *9 the

Cha"ter 11* The ,a-a IF1 @4stem

5)'

3ene9it# *9 aggregating inter9ace# t* #peci9y the +i; *9 a3#tract data type# in an i+ple+entati*n) Rather than d* that, the ) ET -O cla##e# have an *verlyEinclu#ive #tream 3a#e cla## and a tri* *9 pu3lic in#tance pr*pertie# Can*ead, Can=rite, and Can#ee( that #u3#titute 9*r !hat #h*uld 3e type in9*r+ati*n) The +*tivati*n 9*r thi# !a# pr*3a3ly a !ellE +eaning de#ire t* av*id an Ie;pl*#i*nJ in type# and inter9ace#, 3ut g**d de#ign i# a# #i+ple a# p*##i3le and no sim"ler) By g*ing t** 9ar !ith #tream, and !ith an un9*rtunate hand9ul *9 na+ing and 3ehavi*r inc*n#i#tencie#, the #ystem6B1 na+e#pace can 3e Duite 9ru#trating)

-5$es o0 Stream
Cla##e# de#cended 9r*+ #tream c*+e in t!* type#1 i+ple+entati*n cla##e# a##*ciated !ith a particular type *9 data #ink *r #*urce1 0) Ae+*ryStrea+# are the #i+ple#t #trea+# and !*rk !ith inE+e+*ry data repre#entati*n# 2) 5ileStrea+# !*rk !ith 9ile# and add 9uncti*n# 9*r l*cking the 9ile 9*r e;clu#ive acce##) -#*latedSt*rage5ileStrea+ de#cend# 9r*+ 5ileStrea+ and i# u#ed 3y i#*lated #t*re#) /) et!*rkStrea+# are very help9ul !hen net!*rk pr*gra++ing and encap#ulate G3ut pr*vide acce## t*H an underlying net!*rk #*cket)

=nd cla##e# !hich are u#ed t* dyna+ically add additi*nal re#p*n#i3ilitie# t* *ther #trea+#1 0) Crypt*Strea+# can enc*de and dec*de any *ther #trea+#, !hether th*#e #trea+# *riginate in +e+*ry, the 9ile #y#te+, *r *ver a net!*rk) 2) Bu99eredStrea+# i+pr*ve the per9*r+ance *9 +*#t #trea+ #cenari*# 3y reading and !riting 3yte# in large chunk#, rather than *ne at a ti+e) Cla##e# #uch a# Crypto#tream and Buffered#tream are called I,rapperJ *r I?ec*rat*rJ cla##e# G#ee Thinking in /atternsH)

53(

Thinking in C

www.ThinkingIn.!et

-e&t and 3inar5


Having deter+ined !here the #trea+ i# t* e;i#t G+e+*ry, 9ile, *r net!*rkH and h*! it i# t* 3e dec*rated G!ith crypt*graphy and 3u99eringH, y*ull need t* ch**#e !hether y*u !ant t* deal !ith the #trea+ a# character# *r a# 3yte#) -9 a# character#, y*u can u#e the #tream*eader and #tream=riter cla##e# t* deal !ith the data a# line# *9 #tring#, i9 a# 3yte#, y*u can u#e Binary*eader and Binary=riter t* tran#late 3yte# t* and 9r*+ the pri+itive value type#)

=ll t*ld, there are 6$ di99erent valid c*+3inati*n# *9 the#e three a#pect# and !hile it can 3e c*n9u#ing at 9ir#t, it# clearer than having, 9*r in#tance, a cla## called BinaryCrypto:ile*eader) "u#t t* keep y*u *n y*ur t*e#, th*ugh, #tream*eader and #tream=riter have #i3ling cla##e# #tring*eader and #tring=riter !hich !*rk directly *n #tring#, n*t #trea+#)

Wor*ing With 4i00erent 'ources


Thi# e;a+ple #h*!# that alth*ugh the !ay in !hich *ne turn# a #*urce int* a #trea+ di99er#, *nce in hand, any #*urce can 3e treated eDuivalently1 //:c"":SourceStrea!.c# u#ing Sy#te!3 u#ing Sy#te!.'ext3 u#ing Sy#te!.5O3 c a## SourceStrea! ; Strea! #rc3

Cha"ter 11* The ,a-a IF1 @4stem

531

SourceStrea!0Strea! #rc1; thi#.#rc 9 #rc3 < /= #tatic SourceStrea! HorCet.or%Strea!01; #tring thin%ing5n 9 &....!icro#oft.co!&3 5-)ddre## tCet 9 :n#.Re#o *e0thin%ing5n1.)ddre##Li#tJ0K3 5-+nd-oint ep 9 ne. 5-+nd-oint0tCet2 I013 Soc%et # 9 ne. Soc%et0 )ddre##Ha!i y.5nterCet.or%2 Soc%et'ype.Strea!2 -rotoco 'ype.'cp 13 #.Connect0ep13 Cet.or%Strea! nStrea! 9 ne. Cet.or%Strea!0#13 SourceStrea! #rcStrea! 9 ne. SourceStrea!0nStrea!13 return #rcStrea!3 < =/ *oid Read) 01; Sy#te!.Con#o e.VriteLine0 &Reading #trea! of type & R #rc._et'ype0113 int nextByte3 .hi e 00nextByte 9 #rc.ReadByte011 !9 6"1 ; Sy#te!.Con#o e.Vrite00char1 nextByte13 < < pu$ ic #tatic *oid Gain01; SourceStrea! #rcStr 9 HorGe!oryStrea!013 #rcStr.Read) 013 #rcStr 9 HorHi eStrea!013 #rcStr.Read) 013 //#rcStr 9 HorCet.or%Strea!013 //#rcStr.Read) 013 <

53)

Thinking in C

www.ThinkingIn.!et

#tatic SourceStrea! HorGe!oryStrea!01; #tring aString 9 &!ary had a itt e a!$&3 Onicode+ncoding ue 9 ne. Onicode+ncoding013 char $yte# 9 ue._etByte#0aString13 Ge!oryStrea! !e!Strea! 9 ne. Ge!oryStrea!0$yte#13 SourceStrea! #rcStrea! 9 ne. SourceStrea!0!e!Strea!13 return #rcStrea!3 < #tatic SourceStrea! HorHi eStrea!01; #tring fCa!e 9 &SourceStrea!.c#&3 Hi eStrea! fStrea! 9 ne. Hi eStrea!0fCa!e2 Hi eGode.Open13 SourceStrea! #rcStrea! 9 ne. SourceStrea!0fStrea!13 return #rcStrea!3 < < The c*n#truct*r t* #ource#tream take# a #tream and a##ign# it t* the in#tance varia3le src, !hile the +eth*d *ead'll() read# that src *ne 3yte at a ti+e until the +eth*d return# E0, indicating that there are n* +*re 3yte#) Each 3yte read i# ca#t t* a char and #ent t* the c*n#*le) The .ain() +eth*d u#e# the #tatic +eth*d# :or.emory#tream() and :or:ile#tream() t* in#tantiate #ource#tream# and then call# the *ead'll() +eth*d) S* 9ar, all the c*de ha# dealt !ith #tream# n* +atter !hat their real #*urce, 3ut the #tatic +eth*d# +u#t nece##arily 3e #peci9ic t* the #u3type *9 #tream 3eing created) -n the ca#e *9 the .emory#tream, !e #tart !ith a string, u#e the Vnicode&ncoding cla## 9r*+ the #ystem6+ext na+e#pace t* c*nvert the string int* an array *9 bytes, and pa## the re#ult int* the .emory#tream c*n#truct*r) The .emory#tream g*e# t* the #ource#tream c*n#truct*r, and then !e return the #ource#tream)

Cha"ter 11* The ,a-a IF1 @4stem

533

5*r the 5ileStrea+, *n the *ther hand, !e have t* #peci9y an e;tant 9ilena+e and !hat 5ileA*de !e !i#h t* u#e t* *pen it) The 5ileA*de enu+erati*n include#1 +able 77-76 :ile.ode Halues :ile.ode6Halue 'ppend Behavior -9 the 9ile e;i#t#, *pen it and g* t* the end *9 the 9ile i++ediately) -9 the 9ile d*e# n*t e;i#t, create it) 5ile cann*t 3e read) Create# a ne! 9ile *9 the given na+e, e-en i$ that 9ile already e;i#t# Git era#e# the e;tant 9ileH) Create# a ne! 9ile, i$ it does not e%ist) -9 the 9ile e;i#t#, thr*!# an B1&xception) Open# an e;i#ting 9ile and thr*!# a :ile,ot:ound&xception *ther!i#e) Create# and *pen# a 9ile, creating a ne! 9ile i9 nece##ary Open# an e;i#ting 9ile and truncate# it# #i7e t* 7er*)

Create

Create,ew 1pen 1pen1rCreate +runcate

7un With Cr5$to'trea#s


Aicr*#*9t ha# d*ne a 3ig 9av*r t* eC*++erce devel*per# 3y including indu#trialE#trength crypt*graphy #upp*rt in the ) ET 5ra+e!*rk) Aany pe*ple +i#takenly 3elieve that t* 3e anything 3ut a pa##ive c*n#u+er *9 crypt*graphy reDuire# hardc*re +athe+atic#) *t #*) ,hile 9e! pe*ple are capa3le *9 devel*ping ne! 9unda+ental alg*rith+#, crypt*graphic "rotocols that u#e the alg*rith+# 9*r c*+ple; ta#k# are acce##i3le t* any*ne, !hile actual a""lications that u#e the#e pr*t*c*l# t* deliver 3u#ine## value are 9e! and 9ar 3et!een) Crypt*graphic alg*rith+# c*+e in t!* 9unda+ental 9lav*r#1 s4mmetric algorithms u#e the #a+e key t* encrypt and decrypt a data #trea+, !hile

534

Thinking in C

www.ThinkingIn.!et

as4mmetric algorithms have a Ipu3licJ key 9*r encrypti*n and a IprivateJ key 9*r decrypti*n) The ) ET 5ra+e!*rk c*+e# !ith #everal #y++etric alg*rith+# and t!* a#y++etric alg*rith+#, *ne 9*r general u#e and *ne that #upp*rt# the #tandard 9*r digital #ignature#)

Category Sy++etric

,ame ?ES

Characteristics Older US 5ederal #tandard 9*r I#en#itive 3ut n*t cla##i9iedJ data) '.E3it e99ective key) Cracked in 22 h*ur# 3y U2'$,$$$ cu#t*+ c*+puter, plu# 0$$N di#tri3uted PC#) -9 it# !*rth encrypting, it# !*rth n*t u#ing ?ES) =n e;ten#i*n *9 ?ES that ha# a 002E3it e99ective key Gn*te that thi# increa#e# cracking di99iculty 3y 2'.H) Caria3le key #i7e, i+ple+entati*n #ee+# t* 3e 9a#te#t #y++etric) =lg*rith+ ch*#en 9*r =dvanced Encrypti*n Standard, e99ectively ?ES replace+ent) 5a#t, varia3le and large key #i7e#, generally the 3e#t #y++etric cipher) Pr*n*unced IrainEdahlJ Cann*t 3e u#ed 9*r encrypti*nQ *nly g**d 9*r digital #igning) Patent e;pired, al+*#t #yn*ny+*u# !ith pu3licEkey crypt*pgraphy)

Sy++etric

Triple?ES

Sy++etric Sy++etric

RC2 Ri4ndael

=#y++etric =#y++etric

?S= RS=

Crypt*Strea+# are *nly created 3y the #y++etric alg*rith+#) //:c"":SecretCode.c# u#ing Sy#te!3 u#ing Sy#te!.5O3 u#ing Sy#te!.Security.Cryptography3

Cha"ter 11* The ,a-a IF1 @4stem

535

c a## SecretCode; #tring fi eCa!e3 #tring Hi eCa!e; get ; return fi eCa!e3 < #et ; fi eCa!e 9 *a ue3 < < RiDndae Ganaged r!3 SecretCode0#tring fCa!e1; fi eCa!e 9 fCa!e3 r! 9 ne. RiDndae Ganaged013 r!._enerateaey013 r!._enerate5N013 < *oid +ncode'oHi e0#tring outCa!e1; Hi eStrea! #rc 9 ne. Hi eStrea!0 fi eCa!e2 Hi eGode.Open13 5Crypto'ran#for! encoder 9 r!.Create+ncryptor013 CryptoStrea! #tr 9 ne. CryptoStrea!0 #rc2 encoder2 CryptoStrea!Gode.Read13 Hi eStrea! outHi e 9 ne. Hi eStrea!0 outCa!e2 Hi eGode.Create13 int i 9 03 .hi e00i 9 #tr.ReadByte011 !9 6"1; outHi e.VriteByte00$yte1i13 < #rc.C o#e013 outHi e.C o#e013 < *oid :ecode0#tring cypherHi e1; Hi eStrea! #rc 9 ne. Hi eStrea!0 cypherHi e2 Hi eGode.Open13

536

Thinking in C

www.ThinkingIn.!et

5Crypto'ran#for! decoder 9 r!.Create:ecryptor013 CryptoStrea! #tr 9 ne. CryptoStrea!0 #rc2 decoder2 CryptoStrea!Gode.Read13 int i 9 03 .hi e00i 9 #tr.ReadByte011 !9 6"1; Sy#te!.Con#o e.Vrite00char1 i13 < #rc.C o#e013 < pu$ ic #tatic *oid Gain0#tringJK arg#1; SecretCode #c 9 ne. SecretCode0arg#J0K13 #c.+ncode'oHi e0&encoded.dat&13 Sy#te!.Con#o e.VriteLine0&:ecoded:&13 #c.:ecode0&encoded.dat&13 < <///:8 The crypt*graphic pr*vider# are in the Sy#te+)Security)Crypt*graphy na+e#pace) Each alg*rith+ ha# 3*th a 3a#e cla## na+ed a9ter the alg*rith+ G?ES, Ri4ndael, RS=, etc)H and an i+ple+entati*n *9 that alg*rith+ pr*vided 3y Aicr*#*9t) Thi# i# a nice de#ign, all*!ing *ne t* plug in ne! i+ple+entati*n# *9 vari*u# alg*rith+# a# de#ired) The Sy#te+)Security)Crypt*graphy na+e#pace i# n*t part *9 Aicr*#*9t# #u3+i##i*n t* ECA= and there9*re the #*urce c*de i# n*t availa3le t* #crutiny a# part *9 the #haredE#*urce C*++*n Language -n9ra#tructure initiative that Aicr*#*9t i# trying t* u#e t* generate g**d!ill in the acade+ic c*++unity) =lth*ugh Aicr*#*9t# i+ple+entati*n# have 3een validated 3y the US and Canadian 5ederal g*vern+ent#, it# a pity that thi# #*urce c*de i# n*t availa3le 9*r pu3lic revie!) -n thi# ca#e, !e u#e the Ri4ndaelAanaged cla## that i+ple+ent# the Ri4ndael alg*rith+) Like the *ther i+ple+entati*n#, the Ri4ndaelAanaged cla## i# a3le t* generate rand*+ key# and initiali7ati*n vect*r#, a# #h*!n in the #ecretCode c*n#truct*r, !hich al#* #et# an in#tance varia3le file,ame t* the na+e *9 the 9ile !hich !ell 3e encrypting)

Cha"ter 11* The ,a-a IF1 @4stem

53#

&ncode+o:ile() *pen# a :ile#tream na+ed src t* *ur t*E3eE encrypted 9ile) The #y++etric crypt*graphic alg*rith+# each pr*vide a Create&ncryptor() and Create$ecryptor() +eth*d !hich return# an BCrypto+ransform that i# a nece##ary para+eter 9*r the Crypto#tream c*n#truct*r) ,ith the input #trea+ src, the BCrypto+ransform enc*der, and the Crypto#tream.ode6*ead +*de a# para+eter# !e generate a Crypto#tream called str) The out:ile #trea+ i# c*n#tructed in a 9a+iliar !ay 3ut thi# ti+e !ith :ile.ode6Create) ,e read the str Crypto#tream and !rite it t* the out:ile, u#ing the +eth*d =riteByte()) Once d*ne, !e cl*#e 3*th the #*urce 9ile and the ne!ly created encrypted 9ile) The +eth*d $ecode() d*e# the c*+ple+entQ it *pen# a :ile#tream, u#e# the *i)ndael.anaged in#tance t* create an BCrypto+ransform decoder and a Crypto#tream appr*priate 9*r reading the encrypted 9ile) ,e read the encrypted 9ile *ne 3yte at a ti+e and print the *utput *n the c*n#*le) The .ain() +eth*d create# a ne! #ecretCode cla##, pa##ing in the 9ir#t c*++andEline argu+ent a# the 9ilena+e t* 3e enc*ded) Then, the call t* &ncode+o:ile() encrypt# that 9ile t* an*ther called Ienc*ded)dat)J Once that 9ile i# created, it i# in turn dec*ded 3y the $ecode() +eth*d) One characteri#tic *9 a g**d encrypted #trea+ i# that it i# di99icult t* di#tingui#h 9r*+ a #trea+ *9 rand*+ dataQ #ince rand*+ data i# n*nE c*+pre##i3le, i9 y*u atte+pt t* c*+pre## Ienc*ded)datJ y*u #h*uld #ee tht #ure en*ugh the Ic*+pre##edJ 9ile i# larger than the *riginal)

3inar56eader and 3inar5Writer


,hile !eve 3een a3le t* get 3y !ith reading and !riting individual 3yte#, d*ing #* reDuire# a l*t *9 e;tra e99*rt !hen dealing !ith anything 3ut the #i+ple#t data) Binary*eader and Binary=riter are !rapper cla##e# !hich can ea#e the ta#k *9 dealing !ith the +*#t c*++*n pri+itive value type#) The Binary,riter cla## c*ntain# a large nu+3er *9 *verridden =rite() +eth*d#, a# illu#trated in thi# #a+ple1 //:c"":BinaryVrite.c# u#ing Sy#te!3

53&

Thinking in C

www.ThinkingIn.!et

u#ing Sy#te!.5O3 c a## BinaryVrite; pu$ ic #tatic *oid Gain01; Strea! fStrea! 9 ne. Hi eStrea!0 &$inaryio.dat&2 Hi eGode.Create13 Vrite'ype#0fStrea!13 fStrea!.C o#e013 < #tatic *oid Vrite'ype#0Strea! #in%1; BinaryVriter $. 9 ne. BinaryVriter0#in%13 $..Vrite0true13 $..Vrite0fa #e13 $..Vrite00$yte1 F13 $..Vrite0ne. $yteJK ; "2 22 T2 E <13 $..Vrite0'M'13 $..Vrite0ne. charJK ; ')'2 'B'2 'C'2 ':' <13 $..Vrite0ne. :eci!a 0"2T.EP113 $..Vrite0"2T.EP13 $..Vrite00#hort1 2"213 $..Vrite00 ong1 2"213 $..Vrite0&W$oo eanZtrueW/$oo eanZ&13 < <///:8 Binary,rite# AainGH +eth*d create# a 5ileStrea+ 9*r !riting, upca#t# the re#ult t* #tream, pa##e# it t* the #tatic =rite+ypes() +eth*d, and a9ter!ard# cl*#e# it) The =rite+ypes() +eth*d take# the pa##ed in #tream and pa##e# it a# a para+eter t* the Binary=riter c*n#truct*r) Then, !e call Binary=riter6=rite() !ith vari*u# para+eter#, everything 9r*+ bool t* string) Behind the #cene#, the Binary=riter turn# the#e type# int* #eDuence# *9 3yte# and !rite# the+ t* the underlying #trea+) Every type, e;cept 9*r string, ha# a predeter+ined length in 3yte# P even 3**l#, !hich c*uld 3e repre#ented in a #ingle 3it, are #t*red a# a 9ull 3yte EEE #* it +ight 3e +*re accurate t* call thi# type *9 #t*rage I3yte dataJ rather than I3inary data)J T* #t*re a #tring, Binary=riter 9ir#t !rite#

Cha"ter 11* The ,a-a IF1 @4stem

53'

*ne *r +*re 3yte# t* indicate the nu+3er *9 3yte# that the #tring reDuire# 9*r #t*rageQ the#e 3yte# u#e % 3it# t* enc*de the length and the ( th 3it Gi9 nece##aryH t* indicate that the ne;t 3yte i# n*t the 9ir#t character *9 the #tring, 3ut an*ther length 3yte) The Binary=riter cla## d*e# n*thing !e c*uldnt d* *n *ur *!n, 3ut it# +uch +*re c*nvenient) aturally, there# a c*+ple+entary Binary*eader cla##, 3ut 3ecau#e *ne cann*t have p*ly+*rphi#+ 3a#ed *nly *n return type G#ee chapter #p*ly+*rphi#+#H, the +eth*d# 9*r reading vari*u# type# are a little l*nger1 //:c"":BinaryRead.c# u#ing Sy#te!3 u#ing Sy#te!.5O3 c a## BinaryRead; pu$ ic #tatic *oid Gain0#tringJK arg#1; Strea! fStrea! 9 ne. BufferedStrea!0 ne. Hi eStrea!0arg#J0K2 Hi eGode.Open113 Byte:u!p0fStrea!13 fStrea!.C o#e013 fStrea! 9 ne. BufferedStrea!0 ne. Hi eStrea!0arg#J0K2 Hi eGode.Open113 Read'ype#0fStrea!13 fStrea!.C o#e013 < #tatic *oid Byte:u!p0Strea! #rc1; int i 9 03 .hi e00i 9 #rc.ReadByte011 !9 6"1; Sy#te!.Con#o e.VriteLine0 &;0< 9 ;"< &2 0char1 i2 i13 < Sy#te!.Con#o e.VriteLine013 < #tatic *oid Read'ype#0Strea! #rc1; BinaryReader $r 9 ne. BinaryReader0#rc13 $oo $ 9 $r.ReadBoo ean013 Sy#te!.Con#o e.VriteLine0$13

54(

Thinking in C

www.ThinkingIn.!et

$ 9 $r.ReadBoo ean013 Sy#te!.Con#o e.VriteLine0$13 $yte $t 9 $r.ReadByte013 Sy#te!.Con#o e.VriteLine0$t13 $yteJK $yte)rray 9 $r.ReadByte#0E13 Sy#te!.Con#o e.VriteLine0$yte)rray13 char c 9 $r.ReadChar013 Sy#te!.Con#o e.VriteLine0c13 charJK char)rray 9 $r.ReadChar#0E13 Sy#te!.Con#o e.VriteLine0char)rray13 :eci!a d 9 $r.Read:eci!a 013 Sy#te!.Con#o e.VriteLine0d13 :ou$ e d$ 9 $r.Read:ou$ e013 Sy#te!.Con#o e.VriteLine0d$13 #hort # 9 $r.Read5nt"?013 Sy#te!.Con#o e.VriteLine0#13 ong 9 $r.Read5nt?E013 Sy#te!.Con#o e.VriteLine0 13 #tring tag 9 $r.ReadString013 Sy#te!.Con#o e.VriteLine0tag13 < <///:8 Binary*ead6.ain() intr*duce# an*ther !rapper cla##, Buffered#tream, !hich increa#e# the e99iciency *9 n*nE+e+*ryE3a#ed #trea+# 3y u#ing an internal +e+*ry 3u99er t* te+p*rarily #t*re the data rather than !riting a #ingle 3yte t* the underlying 9ile *r net!*rk) Bu99eredStrea+# are largely tran#parent t* u#e, alth*ugh the +eth*d :lush(), !hich #end# the c*ntent# *9 the 3u99er t* the underlying #trea+, regardle## *9 !hether it# 9ull *r n*t, can 3e u#ed t* 9ineEtune 3ehavi*r) Binary*ead !*rk# *n a 9ile !h*#e na+e i# pa##ed in *n the c*++and line) Byte$ump() #h*!# the c*ntent# *9 the 9ile *n the c*n#*le, printing the 3yte a# 3*th a character and di#playing it# deci+al value) ,hen run *n I3inaryi*)datJ, the run 3egin#1 d 9 " 9 0 9 F d 9 " e 9 2 f 9 T

Cha"ter 11* The ,a-a IF1 @4stem

541

g 9 E M 9 "22 ) 9 ?P B 9 ?? C 9 ?F : 9 ?I LetcL The 9ir#t t!* 3yte# repre#ent the B**lean value# true and 9al#e, !hile the ne;t part# *9 the 9ile c*rre#p*nd directly t* the value# *9 the 3yte# and char# !e !r*te !ith the pr*gra+ Binary=rite) The +*re c*+plicated data type# are harder t* interpret, 3ut t*!ard# the end *9 thi# +eth*d, y*ull #ee a 3yte value *9 202 that c*rre#p*nd# t* the short and the long !e !r*te) The la#t part *9 the *utput 9r*+ thi# +eth*d l**k# like thi#1 h W $ o o e a n Z t r u e W / $ o o e a n Z 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 2T ?0 >I """ """ "0I "0" >F ""0 ?2 ""? ""E ""F "0" ?0 EF >I """ """ "0I "0" >F ""0 ?2

54)

Thinking in C

www.ThinkingIn.!et

Thi# particular #tring, !hich c*n#u+e# 2& 3yte# *9 #t*rage G0 length 3yte, and 2/ character 3yte#H, i# the BAL eDuivalent *9 the #ingle 3yte at the 3eginning *9 the 9ile that #t*re# a bool) ,ell di#cu## BAL in length in chapter #BAL#, 3ut thi# #h*!# the pri+ary tradeE*99 3et!een 3inary data and BAL P e99iciency ver#u# de#criptivene##) -r*nically, !hile l*cal #t*rage i# e;periencing greaterEthanEA**re#ELa! increa#e# in data den#ity Gand there3y 3ec*+ing cheaper and cheaperH and net!*rk 3and!idth Ge#pecially t* the h*+e and *ver !irele##H !ill 3e a pr*3le+ 9*r the 9*re#eea3le 9uture, 9ile 9*r+at# re+ain pri+arily 3inary and BAL i# e;pl*ding a# the *verEnet!*rk 9*r+at *9 ch*iceK =9ter Binary*ead du+p# the ra! data t* the c*n#*le, it then read# the #a+e #trea+, thi# ti+e !ith the #tatic +eth*d *ead+ypes()) *ead+ypes() in#tantiate# a Binary*eader() and call# it# vari*u# *eadxxx() +eth*d# in e;act c*rre#p*ndence t* the Binary=riter6=rite() +eth*d# *9 Binary=rite6=rite+ypes()) ,hen run *n 3inaryi*)dat, Binary*ead6*ead+ypes() repr*duce# the e;act data, 3ut y*u can al#* run the pr*gra+ *n any 9ile and it !ill ga+ely interpret that pr*gra+# 3yte# a# the #peci9ied type#) Here# the *utput !hen Binary*ead i# run *n it# *!n #*urce 9ile1 'rue 'rue PI Sy#te!.ByteJK B inar 6T.PFT22?F>22"T??T?P"F"IIEPF0I"+6FP ?.2F?TEI?TE02P2+62EP 2>>?2 IT20FFT"IP"IT0P00>> e!.5O3 c a## BinaryRead; pu$ ic #tatic *oid Gain0#tringJK arg#1; Strea! fStrea! 9 ne. BufferedStrea!0 =gain, thi# i# the price t* 3e paid 9*r the e99iciency *9 3yte data P the #lighte#t di#crepancy 3et!een the type# #peci9ied !hen the data i# !ritten and !hen it i# read lead# t* inc*rrect data value#, 3ut the pr*3le+ !ill

Cha"ter 11* The ,a-a IF1 @4stem

543

pr*3a3ly n*t 3e detected until #*+e other +eth*d atte+pt# t* u#e thi# !r*ng data)

'trea#6eader and 'trea#Writer


Becau#e #tring# are #uch a c*++*n data type, the ) ET 5ra+e!*rk pr*vide# #*+e dec*rat*r cla##e# t* aid in reading line# and 3l*ck# *9 te;t) The #tream*eader and #tream=riter cla##e# dec*rate #trea+# and #tring*eader and #tring=riter dec*rate string#) The +*#t u#e9ul +eth*d in #tream*eader i# *eadLine(), a# de+*n#trated in thi# #a+ple, !hich print# a 9ile t* the c*n#*le !ith line nu+3er# prepended1 //:c"":Line)t)'i!e.c# u#ing Sy#te!3 u#ing Sy#te!.5O3 c a## Line)t)'i!e; pu$ ic #tatic *oid Gain0#tringJK arg#1; foreach0#tring fCa!e in arg#1; Strea! #rc 9 ne. BufferedStrea!0 ne. Hi eStrea!0fCa!e2 Hi eGode.Open113 Line-rint0#rc13 #rc.C o#e013 < < #tatic *oid Line-rint0Strea! #rc1; Strea!Reader r 9 ne. Strea!Reader0#rc13 int ine 9 03 #tring aLine 9 &&3 .hi e00aLine 9 r.ReadLine011 !9 nu 1; Sy#te!.Con#o e.VriteLine0&;0<: ;"<&2 ineRR2 aLine13 < < <///:8 The .ain() +eth*d take# a c*++andEline 9ilena+e and *pen# it, dec*rate# the :ile#tream !ith a Buffered#tream, and pa##e# the re#ulting #tream t* the Line!rint() #tatic +eth*d) Line!rint()

544

Thinking in C

www.ThinkingIn.!et

create# a ne! #tream*eader t* dec*rate the Buffered#tream and u#e# #tream*eader6*eadLine() t* read the underlying #trea+ a line at a ti+e) #tream*eader6*eadLine() return# a null re9erence at the end *9 the 9ile, ending the *utput l**p) Strea+Reader i# u#e9ul 9*r !riting line# and 3l*ck# *9 te;t, and c*ntain# a #le! *9 *verl*aded =rite() +eth*d# #i+ilar t* th*#e in Binary,riter, a# thi# e;a+ple #h*!#1 //:c"":'extVrite.c# u#ing Sy#te!3 u#ing Sy#te!.5O3 c a## 'extVrite; pu$ ic #tatic *oid Gain01; Strea! fStrea! 9 ne. Hi eStrea!0 &textio.dat&2 Hi eGode.Create13 VriteLine'ype#0fStrea!13 fStrea!.C o#e013 < #tatic *oid VriteLine'ype#0Strea! #in%1; Strea!Vriter #. 9 ne. Strea!Vriter0#in%13 #..VriteLine0true13 #..VriteLine0fa #e13 #..VriteLine00$yte1 F13 #..VriteLine0'M'13 #..VriteLine0ne. charJK ; ')'2 'B'2 'C'2 ':' <13 #..VriteLine0ne. :eci!a 0"2T.EP113 #..VriteLine0"2T.EP13 #..VriteLine00#hort1 2"213 #..VriteLine00 ong1 2"213 #..VriteLine0&;0< : ;"<&2 &#tring for!atting #upported&2 &true&13 #..C o#e013 < <///:8

Cha"ter 11* The ,a-a IF1 @4stem

545

Like the Binary,rite #a+ple, thi# pr*gra+ create# a 9ile#trea+ Gthi# ti+e 9*r a 9ile called Ite;ti*)datJH and pa##e# that t* an*ther +eth*d that dec*rate# the underlying data #ink and !rite# t* it) -n additi*n t* =rite() +eth*d# that are *verl*aded t* !rite the pri+itive type#, #tream=riter !ill call +o#tring() *n an4 *34ect and #upp*rt# #tring 9*r+atting) -n *ne *9 the na+e#pace# ann*yance#, #tream=riter i# 3u99ered Galth*ugh it d*e#nt de#cend 9r*+ Buffered#treamH, and #* y*u +u#t e;plicitly call Close() in *rder t* 9lu#h the line# t* the underlying #trea+) The data !ritten 3y #tream=riter i# in te;t 9*r+at, a# #h*!n in the c*ntent# *9 te;ti*)dat1 'rue Ha #e F M )BC: "2T.EP "2T.EP 2"2 2"2 #tring for!atting #upported : true Bear in +ind that #tream*eader d*e# n*t have *eadxxx() +eth*d# P i9 y*u !ant t* #t*re pri+itive type# t* 3e read and u#ed a# pri+itive type#, y*u #h*uld u#e the 3yteE*riented *eader and =riter cla##e#) :*u could #t*re the data a# te;t, read it a# te;t, and then per9*r+ the vari*u# #tring par#ing *perati*n# t* recreate the value#, 3ut that !*uld 3e !a#te9ul) -t# !*rth n*ting that #tream*eader and #tream=riter have #i3ling cla##e# #tring*eader and #tring=riter that are de#cended 9r*+ the #a+e *eader and =riter a3#tracti*n) Since string *34ect# are i++uta3le G*nce #et, a string cann*t 3e changedH, there i# a need 9*r an e99icient t**l 9*r 3uilding #tring# and c*+ple; 9*r+atting ta#k#) The 3a#ic ta#k *9 3uilding a #tring 9r*+ #u3#tring# i# handled 3y the #tringBuilder cla##, !hile the c*+ple; 9*r+atting can 3e d*ne !ith the #tring=riter G!hich dec*rate# a #tringBuilder in the #a+e !ay that the #tream=riter dec*rate# a #treamH)

546

Thinking in C

www.ThinkingIn.!et

6ando# access with 'ee*


The Strea+ 3a#e cla## c*ntain# a +eth*d called #ee(() that can 3e u#ed t* 4u+p 3et!een rec*rd# and data #ecti*n# *9 kn*!n #i7e G*r #i7e# that can 3e c*+puted 3y reading header data in the #trea+H) The rec*rd# d*nt have t* 3e the #a+e #i7eQ y*u 4u#t have t* 3e a3le t* deter+ine h*! 3ig they are and !here they are placed in the 9ile) The SeekGH +eth*d take# a l*ng Gi+plying a +a;i+u+ 9ile #i7e *9 ( e;a3yte#, !hich !ill h*pe9ully #u99ice 9*r a 9e! year#H and a value 9r*+ the #ee(1rigin enu+erati*n !hich can 3e Begin, Current, *r &nd) The SeekOrigin value #peci9ie# the p*int 9r*+ !hich the #eek 4u+p#) =lth*ugh #ee(() i# de9ined in #tream, n*t all #tream# #upp*rt it G9*r in#tance, *ne cant I4u+p ar*undJ a net!*rk #trea+H) The Can#ee( 3**l pr*perty #peci9ie# !hether the #trea+ #upp*rt# #ee(() and the related Length() and #etLength() +eh*d#, a# !ell a# the !osition() +eth*d !hich return# the current p*#iti*n in the #tream) -9 Can#ee( i# false and *ne *9 the#e +eth*d# i# called, it !ill thr*! a ,ot#upported&xception) Thi# i# p**r de#ign) Supp*rt 9*r rand*+ acce## i# 3a#ed *n type, n*t #tate, and #h*uld 3e #peci9ied in an inter9ace G#ay, B#ee(ableH that i# i+ple+ented 3y the appr*priate #u3type# *9 #tream) -9 y*u u#e #ee(1rigin6&nd, y*u #h*uld u#e a negative nu+3er 9*r the *99#etQ per9*r+ing a #ee(() 3ey*nd the end *9 the stream +*ve# t* the end *9 the 9ile Gi)e), *eadByte() !ill return a E0, etc)H) Thi# e;a+ple #h*!# the 3a#ic u#e *9 #tream6#ee(()1 //:c"":Hi$See%.c# u#ing Sy#te!3 u#ing Sy#te!.5O3 c a## Hi$See% ; Strea! #rc3 Hi$See%0Strea! #rc1; thi#.#rc 9 #rc3 <

Cha"ter 11* The ,a-a IF1 @4stem

54#

*oid :oSee%0See%Origin #o1; if 0#o 99 See%Origin.+nd1 ; #rc.See%06"02 #o13 < e #e ; #rc.See%0"02 #o13 < int i 9 #rc.ReadByte013 Sy#te!.Con#o e.VriteLine0 &"0 $yte# fro! ;0< i# : ;"<&2 #o2 0char1 i13 < pu$ ic #tatic *oid Gain0#tringJK arg#1; foreach0#tring fCa!e in arg#1; Hi eStrea! f 9 nu 3 try ; f 9 ne. Hi eStrea!0fCa!e2 Hi eGode.Open13 Hi$See% f# 9 ne. Hi$See%0f13 f#.:oSee%0See%Origin.Begin13 f#.:oSee%0See%Origin.+nd13 f.See%0"22 See%Origin.Begin13 f#.:oSee%0See%Origin.Current13 < catch 0+xception ex1 ; Sy#te!.Con#o e.VriteLine0ex13 < fina y ; f.C o#e013 < < < <///:8

'tandard I?O
The ter+ standard IF1 re9er# t* the Uni; c*ncept G!hich i# repr*duced in #*+e 9*r+ in ,ind*!# and +any *ther *perating #y#te+#H *9 a #ingle #trea+ *9 in9*r+ati*n that i# u#ed 3y a pr*gra+) =ll the pr*gra+# input can c*+e 9r*+ standard in"ut, all it# *utput can g* t* standard out"ut, and all *9 it# err*r +e##age# can 3e #ent t* standard error) The value *9 #tandard -<O i# that pr*gra+# can ea#ily 3e chained t*gether and *ne pr*gra+# #tandard *utput can 3ec*+e the #tandard input 9*r an*ther

54&

Thinking in C

www.ThinkingIn.!et

pr*gra+) A*re than 4u#t a c*nvenience, thi# i# a p*!er9ul architectural pattern called /i"es and +iltersQ alth*ugh thi# architecture !a# n*t very c*++*n in the 066$#, it# a very p*!er9ul *ne, a# any*ne !h*# !itne##ed a U -B guru can te#ti9y)

6eading 0ro# standard in$ut


5*ll*!ing the #tandard -<O +*del, the C*n#*le cla## e;p*#e# three #tatic pr*pertie#1 Out, Err*r, and -n) The Sy#te+ cla## ha# a #tatic C*n#*le pr*perty that !eve 3een u#ing 9*r *utput thr*ugh*ut the 3**k and in Chapter #E;cepti*n# !e #ent #*+e err*r +e##age# t* Sy#te+)C*n#*le)Err*r) Out and Err*r are Te;t,riter#, !hile -n i# a Te;tReader) Typically, y*u either !ant t* read c*n#*le input a# either a character *r a c*+plete line at a ti+e) Here# an e;a+ple that #i+ply ech*e# each line that y*u type in1 //c"":+cho5n.c# // Uo. to read fro! #tandard input. pu$ ic c a## +cho5n ; pu$ ic #tatic *oid Gain01; #tring #3 .hi e00# 9 Sy#te!.Con#o e.5n.ReadLine011.Length !9 01 Sy#te!.Con#o e.VriteLine0#13 // )n e!pty ine ter!inate# the progra! < < ///:8

6edirecting standard I?O


The Console cla## all*!# y*u t* redirect the #tandard input, *utput, and err*r -<O #trea+# u#ing #i+ple #tatic +eth*d call#1 #etBn(+ext*eader) #et1ut(+ext=riter) #et&rror(+ext=riter)

Cha"ter 11* The ,a-a IF1 @4stem

54'

GThere i# n* *3vi*u# rea#*n !hy the#e +eth*d# are u#ed rather than all*!ing the Pr*pertie# t* 3e #et directly)H Redirecting *utput i# e#pecially u#e9ul i9 y*u #uddenly #tart creating a large a+*unt *9 *utput *n y*ur #creen and it# #cr*lling pa#t 9a#ter than y*u can read it) Redirecting input i# valua3le 9*r a c*++andEline pr*gra+ in !hich y*u !ant t* te#t a particular u#erEinput #eDuence repeatedly) Here# a #i+ple e;a+ple that #h*!# the u#e *9 the#e +eth*d#1 //: c"":Redirecting.c# // :e!on#trate# #tandard 5/O redirection. u#ing Sy#te!3 u#ing Sy#te!.5O3 pu$ ic c a## Redirecting ; pu$ ic #tatic *oid Gain01; Strea!Reader #r 9 ne. Strea!Reader0 ne. BufferedStrea!0 ne. Hi eStrea!0 &Redirecting.c#&2 Hi eGode.Open1113 Strea!Vriter #. 9 ne. Strea!Vriter0 ne. BufferedStrea!0 ne. Hi eStrea!0 &redirect.dat&2 Hi eGode.Create1113 Sy#te!.Con#o e.Set5n0#r13 Sy#te!.Con#o e.SetOut0#.13 Sy#te!.Con#o e.Set+rror0#.13 String #3 .hi e00# 9 Sy#te!.Con#o e.5n.ReadLine011 !9 nu Sy#te!.Con#o e.Out.VriteLine0#13 Sy#te!.Con#o e.Out.C o#e013 // Re!e!$er thi#! < < ///:8 Thi# pr*gra+ attache# #tandard input t* a 9ile, and redirect# #tandard *utput and #tandard err*r t* an*ther 9ile)

55(

Thinking in C

www.ThinkingIn.!et

6egular %&$ressions
Regular e;pre##i*n# are a p*!er9ul patternE+atching t**l 9*r interpreting and +anipulating #tring#) =lth*ugh regular e;pre##i*n# are n*t nece##arily related t* input and *utput, it i# pr*3a3ly their +*#t c*++*n applicati*n, #* !ell di#cu## the+ here) Regular e;pre##i*n# have a l*ng hi#t*ry in the 9ield *9 c*+puter #cience 3ut c*ntinue t* 3e e;panded and i+pr*ved, !hich give# ri#e t* an inti+idating #et *9 capa3ilitie# and alternate r*ute# t* a given end) The regular e;pre##i*n# in the ) ET 5ra+e!*rk are Perl ' c*+pati3le 3ut include additi*nal 9eature# #uch a# rightEt*Ele9t +atching and d* n*t reDuire a #eparate c*+pilati*n #tep) The 9unda+ental re#p*n#i3ility *9 the #ystem6+ext6*egular&xpressions *egex cla## i# t* +atch a given pattern !ith a given target #tring) The pattern i# de#cri3ed in a ter#e n*tati*n that c*+3ine# literal te;t that +u#t appear in the target !ith +etaEte;t that #peci9ie# 3*th accepta3le variati*n# in te;t and de#ired +anipulati*n# #uch a# varia3le a##ign+ent *r te;t replace+ent) Thi# #a+ple print# *ut the 9ile na+e# and line# that +atch a regular e;pre##i*n typed in the c*++and line1 //:c"":'_rep.c# //:e!on#trate $a#ic regex !atching again#t fi e# u#ing Sy#te!3 u#ing Sy#te!.5O3 u#ing Sy#te!.'ext.Regu ar+xpre##ion#3 c a## '_rep; pu$ ic #tatic *oid Gain0#tringJK arg#1; '_rep tg 9 ne. '_rep0arg#J0K13 tg.)pp y'oHi e#0arg#J"K13 < Regex re3 '_rep0#tring pattern1; re 9 ne. Regex0pattern13 <

Cha"ter 11* The ,a-a IF1 @4stem

551

*oid )pp y'oHi e#0#tring f-attern1; #tringJK fCa!e# 9 :irectory._etHi e#0&.&2 f-attern13 foreach 0#tring fCa!e in fCa!e# 1 ; Strea!Reader #r 9 nu 3 try; #r 9 ne. Strea!Reader0 ne. BufferedStrea!0 ne. Hi eStrea!0 fCa!e2 Hi eGode.Open1113 #tring ine 9 &&3 int Count 9 03 .hi e00 ine 9 #r.ReadLine011 !9 nu 1; CountRR3 if0re.5#Gatch0 ine11; Sy#te!.Con#o e.VriteLine0 &;0< ;"<: ;2<&2 fCa!e2 Count2 ine13 < < <fina y; #r.C o#e013 < < < <///:8 The .ain() +eth*d pa##e# the 9ir#t c*++andEline argu+ent t* the + rep() c*n#truct*r, !hich in turn pa##e# it t* the *egex() c*n#truct*r) The #ec*nd argu+ent i# then pa##ed a# the argu+ent t* the 'pply+o:iles() +eth*d) 'pply+o:iles() u#e# -O techniDue# !eve di#cu##ed previ*u#ly t* read a #erie# *9 9ile# lineE3yEline and incre+enting the varia3le lCount t* let u# kn*! !hat line nu+3er !*rk#) Each line i# pa##ed t* the *egex6Bs.atch() +eth*d, and i9 that +eth*d return# true, the 9ilena+e, line nu+3er, and c*ntent# *9 the line are printed t* the #creen) :*u +ight gue## that Itgrep u#ing tgrep)c#J !*uld print line# /, &, and ' *9 tgrep)c#, 3ut y*u +ight n*t e;pect that Itgrep Z$E6\ tgrep)c#J !*uld print every line that c*ntain# a nu+3er, *r that Itgrep Zd#\9Zd!\bZd#\bX b)c#J

55)

Thinking in C

www.ThinkingIn.!et

!*uld print every line that a##ign# a value t* a varia3le that 3egin# !ith a l*!erca#e T9) Like SML in =?O) ET, the regular e;pre##i*n n*tati*n i# a #eparate language Duite unlike C#, and Thinking in ?egular E%"ressions !*uld 3e Duite a di99erent 3**k than thi# *ne) -n additi*n t* #i+ply deter+ining i9 a +atch e;i#t#, *egex can actually return the value *9 the +atche#, a# thi# pr*gra+ de+*n#trate#1 //:c"":_repGatche#.c# u#ing Sy#te!3 u#ing Sy#te!.5O3 u#ing Sy#te!.'ext.Regu ar+xpre##ion#3 c a## _repGatche#; pu$ ic #tatic *oid Gain0#tringJK arg#1; _repGatche# tg 9 ne. _repGatche#0arg#J0K13 #tring target 9 arg#J"K3 tg.)pp y'oHi e#0target13 < Regex re3 _repGatche#0#tring pattern1; re 9 ne. Regex0pattern13 < *oid )pp y'oHi e#0#tring f-attern1; #tringJK fCa!e# 9 :irectory._etHi e#0 &.&2 f-attern13 foreach 0#tring fCa!e in fCa!e# 1 ; Strea!Reader #r 9 nu 3 try; #r 9 ne. Strea!Reader0 ne. BufferedStrea!0 ne. Hi eStrea!0fCa!e2 Hi eGode.Open1113 #tring ine 9 &&3 int Count 9 03 .hi e00 ine 9 #r.ReadLine011 !9 nu 1; CountRR3

Cha"ter 11* The ,a-a IF1 @4stem

553

if0re.5#Gatch0 ine11; Sy#te!.Con#o e.VriteLine0 &;0< ;"<: ;2<&2 fCa!e2 Count2 Sho.Gatche#0re.Gatche#0 ine113 < < <fina y; #r.C o#e013 < < < pri*ate *oid Sho.Gatche#0GatchCo ection !c1; for0int i 9 03 i W !c.Count3 iRR1; Sy#te!.Con#o e.VriteLine0 &GatchJ;0<K 9 ;"<&2 i2 !cJiK13 < <

ine13

< *egex6.atches() return# a .atchCollection !hich naturally c*ntain# .atch *34ect#) Thi# #a+ple pr*gra+ can 3e help9ul in de3ugging the devel*p+ent *9 a regular e;pre##i*n, !hich 9*r +*#t *9 u# reDuire# a c*n#idera3le a+*unt *9 trial and err*rK The #tatic +eth*d Rege;)ReplaceGH can +ake c*+ple; tran#9*r+ati*n# #urpri#ingly #traight9*r!ard) Thi# #a+ple +ake# pattern #u3#tituti*n# in a te;t 9ile1 //:c"":'Sed.c# u#ing Sy#te!3 u#ing Sy#te!.5O3 u#ing Sy#te!.'ext.Regu ar+xpre##ion#3 c a## 'Sed; pu$ ic #tatic *oid Gain0#tringJK arg#1; 'Sed tg 9 ne. 'Sed0arg#J0K2 arg#J"K13 #tring target 9 arg#J2K3 tg.)pp y'oHi e#0target13 < #tring pattern3

554

Thinking in C

www.ThinkingIn.!et

#tring rep3 'Sed0#tring pattern2 #tring rep1; thi#.pattern 9 pattern3 thi#.rep 9 rep3 < *oid )pp y'oHi e#0#tring f-attern1; #tringJK fCa!e# 9 :irectory._etHi e#0&.&2 f-attern13 foreach 0#tring fCa!e in fCa!e# 1 ; Strea!Reader #r 9 nu 3 try; #r 9 ne. Strea!Reader0 ne. BufferedStrea!0 ne. Hi eStrea!0 fCa!e2 Hi eGode.Open1113 #tring ine 9 &&3 int Count 9 03 .hi e00 ine 9 #r.ReadLine011 !9 nu 1; #tring nLine 9 Regex.Rep ace0 ine2 pattern2 rep13 Sy#te!.Con#o e.VriteLine0nLine13 < <fina y; #r.C o#e013 < < < < Like the previ*u# #a+ple#, thi# *ne !*rk# !ith c*++andEline argu+ent#, 3ut thi# ti+e, in#tead *9 in#tantiating a *egex 9*r patternE+atching, the 9ir#t t!* c*++andEline argu+ent# are 4u#t #t*red a# #tring#, !hich are later pa##ed t* the *egex6*eplace() +eth*d) -9 the pattern +atche#, the replace+ent pattern i# in#erted int* the #tring, i9 n*t, the line i# unt*uched) ,hether t*uched *r n*t, the line i# !ritten t* the c*n#*leQ thi# +ake# thi# pr*gra+ a ItinyJ ver#i*n *9 U -B# #ed c*++and and i# very c*nvenient)

Cha"ter 11* The ,a-a IF1 @4stem

555

Chec*ing ca$itali:ation st5le


-n thi# #ecti*n !ell l**k at a c*+plete e;a+ple *9 the u#e *9 C# -O !hich al#* u#e# regular e;pre##i*n) Thi# pr*4ect i# directly u#e9ul 3ecau#e it per9*r+# a #tyle check t* +ake #ure that y*ur capitali7ati*n c*n9*r+# t* the C# #tyle) -t *pen# each 6cs 9ile in the current direct*ry and e;tract# all the cla## na+e# and identi9ier#, then #h*!# y*u i9 any *9 the+ d*nt +eet the C# #tyle) :*u can then u#e the TSed #a+ple a3*ve t* aut*+atically replace the+) The pr*gra+ u#e# t!* regular e;pre##i*n# that +atch !*rd# that preced a 3l*ck and !hich 3egin !ith a l*!erca#e letter) One *egex +atche# 3l*ckE *riented identi9ier# G#uch a# cla##, inter9ace, pr*perty, and na+e#pace na+e#H and the *ther catche# +eth*d declarati*n#) ?*ing thi# in a #ingle *egex i# *ne *9 the e;erci#e# at the end *9 the chapter) //:c"":CapSty e.c# //Scan# a .c# fi e# for proper y capita iMed //!ethod and c a##na!e# u#ing Sy#te!3 u#ing Sy#te!.5O3 u#ing Sy#te!.'ext.Regu ar+xpre##ion#3 pu$ ic c a## CapSty e; pu$ ic #tatic *oid Gain01; #tringJK fCa!e# 9 :irectory._etHi e#0&.&2&=.c#&13 foreach0#tring fCa!e in fCa!e#1; CapSty e c# 9 nu 3 try; c# 9 ne. CapSty e0fCa!e13 c#.Chec%013 <fina y; c#.C o#e013 < < < #tringJK %eyVord#9 ne. #tringJK; &a$#tract&2 &e*ent&2 &ne.&2 &#truct&2 &a#&2 &exp icit&2 &nu &2 &#.itch&2 &$a#e&2 &extern&2

556

Thinking in C

www.ThinkingIn.!et

&o$Dect&2 &thi#&2 &$oo &2 &fa #e&2 &operator&2 &thro.&2 &$rea%&2 &fina y&2 &out&2 &true&2 &$yte&2 &fixed&2 &o*erride&2 &try&2 &ca#e&2 &f oat&2 &para!#&2 &typeof&2 &catch&2 &for&2 &pri*ate&2 &uint&2 &char&2 &foreach&2 &protected&2 &u ong&2 &chec%ed&2 &goto&2 &pu$ ic&2 &unchec%ed&2 &c a##&2 &if&2 &readon y&2 &un#afe&2 &con#t&2 &i!p icit&2 &ref&2 &u#hort&2 &continue&2 &in&2 &return&2 &u#ing&2 &deci!a &2 &int&2 &#$yte&2 &*irtua &2 &defau t&2 &interface&2 &#ea ed&2 &*o ati e&2 &de egate&2 &interna &2 &#hort&2 &*oid&2 &do&2 &i#&2 &#iMeof&2 &.hi e&2 &dou$ e&2 & oc%&2 &#tac%a oc&2 &e #e&2 & ong&2 &#tatic&2 &enu!&2 &na!e#pace&2 &#tring&2 &try&2 &catch&2 &fina y&2 &u#ing&2 &e #e&2 &#.itch&2 &pu$ ic&2 &#tatic&2 &*oid&2 &foreach&2 &if&2 &.hi e&2 &$oo &2 &$yte&2 &for&2 &get&2 &#et& <3 Strea!Reader fStrea!3 Regex $ oc%-refix3 Regex !ethod:ef3 CapSty e0#tring fCa!e1; fStrea! 9 ne. Strea!Reader0 ne. BufferedStrea!0 ne. Hi eStrea!0fCa!e2 Hi eGode.Open1113 /= !atche# Du#t6$efore6$rac%et identifier #tarting .ith o.erca#e =/ $ oc%-refix 9 ne. Regex0\&J^#K0YWidZJa6MKJ^.K=1J^#K=;&13 /= !atche# Du#t6$efore6$rac%et .ith argu!ent and identifier #tarting .ith o.erCa#e =/ !ethod:ef 9 i#t

Cha"ter 11* The ,a-a IF1 @4stem

55#

ne. Regex0 \&J^#K0YWidZJa6MKJ^.K=1^#=^00.=1^1J^#K=;&13 Sy#te!.Con#o e.VriteLine0 &Chec%ing fi e: & R fCa!e13 < *oid C o#e01; fStrea!.C o#e013 < *oid Chec%01; #tring ine 9 &&3 int Count 9 03 .hi e00 ine 9 fStrea!.ReadLine011 !9 nu CountRR3 if0Su#piciou#0 ine11; Sy#te!.Con#o e.VriteLine0 &;0<: ;"<&2 Count2 ine13 < < < $oo

1;

Su#piciou#0#tring ine1; if0GatchCotaey.ord0 ine2 $ oc%-refix1 99 true1; return true3 < if0GatchCotaey.ord0 ine2 !ethod:ef1 99 true1; return true3 < return fa #e3 GatchCotaey.ord0#tring ine2 Regex re1; if0re.5#Gatch0 ine11; Gatch ! 9 re.Gatch0 ine13 #tring identifier 9 !._roup#J&id&K.Na ue3 if0)rray.5ndexOf0%eyVord#2 identifier1 W 01; return true3 < <

< $oo

55&

Thinking in C

www.ThinkingIn.!et

return fa #e3 < < The .ain() generate# a li#t *9 all the C# 9ile# in the current direct*ry and 9*r each *ne create# a Cap#tyle in#tance, run# Cap#tyle6Chec(() and then Cap#tyle6Close()6 Each Cap#tyle in#tance c*ntain# a li#t *9 C# key!*rd# that are all*!ed t* 3e in l*!erca#e, a# !ell a# in#tance varia3le# that h*ld the t!* regular e;pre##i*n#, and a #tream*eader in#tance varia3le that read# the underlying 9ile) The Cap#tyle() c*n#truct*r *pen# the 9ile and c*n#truct# the t!* t!* regular e;pre##i*n#) The e;pre##i*n# !ill +atch na+e#pace#, cla## and inter9ace identi9ier#, pr*pertie#, and +eth*d na+e# that precede a TcT character Ghandling +ultiEline 3racketing c*nventi*n# i# an*ther e;erci#eKH) =dditi*nally, the e;pre##i*n# u#e grou" naming t* a##*ciate the !*rd that 3egin# !ith a l*!erca#e letter t* a rege; varia3le called id GI0YWidZJa6MKJ^.K=1J i# the relevant n*tati*nQ the parenthe#e# #peci9y the gr*up, the YWidZ #peci9ie# the na+eH) The Chec(() +eth*d g*e# thr*ugh the #tream*eader lineE3yEline, #eeing i9 #uspicious() return# trueQ i9 #*, that line i# *utput t* the C*n#*le) #uspicious() in turn call# .atch,otEeyword(), pa##ing in the #u#pect line and a re9erence t* *ne *9 the t!* in#tance *egex#) .atch,otEeyword() check# 9*r a +atchQ i9 there i# *ne it a##ign# the value *9 the *egex gr*up na+ed id t* the #tring identifier) -9 thi# #tring d*e# n*t appear in the array *9 C# key!*rd#, .atch,otEeyword() return# true, !hich cau#e# #uspicious t* return true t* Chec(()) -n additi*n t* n*t handling +ultiEline 3racketing, thi# pr*gra+ #*+eti+e# +ark# string# that c*ntain 9*r+atting 3racket# inc*rrectly) -9 y*u i+pr*ve the pr*gra+, plea#e dr*p the auth*r# a line at !!!)thinkingin)net)

'u##ar5
The ) ET -O #trea+ li3rary d*e# #ati#9y the 3a#ic reDuire+ent#1 y*u can per9*r+ reading and !riting !ith the c*n#*le, a 9ile, a 3l*ck *9 +e+*ry, *r even acr*## the -nternet Ga# y*u !ill #ee in Chapter #net!*rking#H)

Cha"ter 11* The ,a-a IF1 @4stem

55'

,ith inheritance, y*u can create ne! type# *9 input and *utput *34ect#) The -O li3rary 3ring# up +i;ed 9eeling#Q it d*e# the 4*3 and it u#e# the ?ec*rat*r pattern t* g**d e99ect) But i9 y*u d*nt already under#tand the ?ec*rat*r pattern, the de#ign i# n*nintuitive, #* there# e;tra *verhead in learning and teaching it) There are al#* #*+e p**r ch*ice# in na+ing and i+ple+entati*n i##ue#) H*!ever, *nce y*u do under#tand the 9unda+ental# *9 #tream# and the ?ec*rat*r pattern and 3egin u#ing the li3rary in #ituati*n# that reDuire it# 9le;i3ility, y*u can 3egin t* 3ene9it 9r*+ thi# de#ign, at !hich p*int it# c*#t in e;tra line# *9 c*de !ill n*t 3*ther y*u at all)

%&ercises

56(

Thinking in C

www.ThinkingIn.!et

12, 6e0lection and )ttri+utes


The idea *9 runEti+e type identi9icati*n GRTT-H #ee+# 9airly #i+ple at 9ir#t1 it let# y*u 9ind the e;act type *9 an *34ect !hen y*u *nly have a re9erence t* the 3a#e type)
H*!ever, the need 9*r RTT- unc*ver# a !h*le pleth*ra *9 intere#ting Gand *9ten perple;ingH OO de#ign i##ue#, and rai#e# 9unda+ental Due#ti*n# *9 h*! y*u #h*uld #tructure y*ur pr*gra+#) Thi# chapter l**k# at the !ay# that "ava all*!# y*u t* di#c*ver in9*r+ati*n a3*ut *34ect# and cla##e# at runEti+e) Thi# take# t!* 9*r+#1 Itraditi*nalJ RTT-, !hich a##u+e# that y*u have all the type# availa3le at c*+pileEti+e and runEti+e, and the Ire9lecti*nJ +echani#+, !hich all*!# y*u t* di#c*ver cla## in9*r+ati*n #*lely at runEti+e) The Itraditi*nalJ RTT- !ill 3e c*vered 9ir#t, 9*ll*!ed 3y a di#cu##i*n *9 re9lecti*n)

561

-he need 0or 6--I


C*n#ider the n*! 9a+iliar e;a+ple *9 a cla## hierarchy that u#e# p*ly+*rphi#+) The generic type i# the 3a#e cla## #hape, and the #peci9ic derived type# are Circle, #%uare, and +riangle1
Shape d ra w 12

C ir c le

S q u a re

T r ia n g le

Thi# i# a typical cla## hierarchy diagra+, !ith the 3a#e cla## at the t*p and the derived cla##e# gr*!ing d*!n!ard) The n*r+al g*al in *34ectE *riented pr*gra++ing i# 9*r the 3ulk *9 y*ur c*de t* +anipulate re9erence# t* the 3a#e type G#hape, in thi# ca#eH, #* i9 y*u decide t* e;tend the pr*gra+ 3y adding a ne! cla## G*homboid, derived 9r*+ #hape, 9*r e;a+pleH, the 3ulk *9 the c*de i# n*t a99ected) -n thi# e;a+ple, the dyna+ically 3*und +eth*d in the #hape inter9ace i# draw( ), #* the intent i# 9*r the client pr*gra++er t* call draw( ) thr*ugh a generic #hape re9erence) draw( ) i# *verridden in all *9 the derived cla##e#, and 3ecau#e it i# a dyna+ically 3*und +eth*d, the pr*per 3ehavi*r !ill *ccur

56)

even th*ugh it i# called thr*ugh a generic #hape re9erence) That# p*ly+*rphi#+) Thu#, y*u generally create a #peci9ic *34ect GCircle, #%uare, *r +riangleH, upca#t it t* a #hape G9*rgetting the #peci9ic type *9 the *34ectH, and u#e that an*ny+*u# #hape re9erence in the re#t *9 the pr*gra+) =# a 3rie9 revie! *9 p*ly+*rphi#+ and upca#ting, y*u +ight c*de the a3*ve e;a+ple a# 9*ll*!#1 //: c"2:Shape#.Da*a i!port Da*a.uti .=3 c a## Shape ; *oid dra.01 ; Sy#te!.out.print n0thi# R &.dra.01&13 < < c a## Circ e extend# Shape ; pu$ ic String toString01 ; return &Circ e&3 < < c a## S7uare extend# Shape ; pu$ ic String toString01 ; return &S7uare&3 < < c a## 'riang e extend# Shape ; pu$ ic String toString01 ; return &'riang e&3 < < pu$ ic c a## Shape# ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; Li#t # 9 ne. )rrayLi#t013 #.add0ne. Circ e0113 #.add0ne. S7uare0113 #.add0ne. 'riang e0113 5terator e 9 #.iterator013 .hi e0e.ha#Cext011 00Shape1e.next011.dra.013

Cha"ter 1)* ?un time T4"e Identi$ication

563

< < ///:8 The 3a#e cla## c*ntain# a draw( ) +eth*d that indirectly u#e# to#tring( ) t* print an identi9ier 9*r the cla## 3y pa##ing this t* #ystem6out6println( )) -9 that 9uncti*n #ee# an *34ect, it aut*+atically call# the to#tring( ) +eth*d t* pr*duce a #tring repre#entati*n) Each *9 the derived cla##e# *verride# the to#tring( ) +eth*d G9r*+ ob)ectH #* that draw( ) end# up printing #*+ething di99erent in each ca#e) -n main( ), #peci9ic type# *9 #hape are created and then added t* a List) Thi# i# the p*int at !hich the upca#t *ccur# 3ecau#e the List h*ld# *nly ob)ect#) Since everything in "ava G!ith the e;cepti*n *9 pri+itive#H i# an ob)ect, a List can al#* h*ld #hape *34ect#) But during an upca#t t* ob)ect, it al#* l*#e# any #peci9ic in9*r+ati*n, including the 9act that the *34ect# are #hape#) T* the 'rrayList, they are 4u#t ob)ect#) =t the p*int y*u 9etch an ele+ent *ut *9 the List !ith next( ), thing# get a little 3u#y) Since the List h*ld# *nly ob)ect#, next( ) naturally pr*duce# an ob)ect reference) But !e kn*! it# really a #hape re9erence, and !e !ant t* #end #hape +e##age# t* that *34ect) S* a ca#t t* #hape i# nece##ary u#ing the traditi*nal I(#hape)J ca#t) Thi# i# the +*#t 3a#ic 9*r+ *9 RTT-, #ince in "ava all ca#t# are checked at runEti+e 9*r c*rrectne##) That# e;actly !hat RTT- +ean#1 at runEti+e, the type *9 an *34ect i# identi9ied) -n thi# ca#e, the RTT- ca#t i# *nly partial1 the ob)ect i# ca#t t* a #hape, and n*t all the !ay t* a Circle, #%uare, *r +riangle) That# 3ecau#e the *nly thing !e know at thi# p*int i# that the List i# 9ull *9 #hape#) =t c*+pileEti+e, thi# i# en9*rced *nly 3y y*ur *!n #el9Ei+p*#ed rule#, 3ut at runEti+e the ca#t en#ure# it) *! p*ly+*rphi#+ take# *ver and the e;act +eth*d that# called 9*r the #hape i# deter+ined 3y !hether the re9erence i# 9*r a Circle, #%uare, *r +riangle) =nd in general, thi# i# h*! it #h*uld 3eQ y*u !ant the 3ulk *9 y*ur c*de t* kn*! a# little a# p*##i3le a3*ut s"eci$ic type# *9 *34ect#, and t* 4u#t deal !ith the general repre#entati*n *9 a 9a+ily *9 *34ect# Gin thi# ca#e, #hapeH) =# a re#ult, y*ur c*de !ill 3e ea#ier t* !rite, read, and +aintain, and y*ur de#ign# !ill 3e ea#ier t* i+ple+ent, under#tand, and

564

Thinking in C

www.ThinkingIn.!et

change) S* p*ly+*rphi#+ i# the general g*al in *34ectE*riented pr*gra++ing) But !hat i9 y*u have a #pecial pr*gra++ing pr*3le+ that# ea#ie#t t* #*lve i9 y*u kn*! the e;act type *9 a generic re9erenceF 5*r e;a+ple, #upp*#e y*u !ant t* all*! y*ur u#er# t* highlight all the #hape# *9 any particular type 3y turning the+ purple) Thi# !ay, they can 9ind all the triangle# *n the #creen 3y highlighting the+) Or perhap# y*ur +eth*d need# t* Ir*tateJ a li#t *9 #hape#, 3ut it +ake# n* #en#e t* r*tate a circle #* y*ud like t* #kip *nly the circle *34ect#) Thi# i# !hat RTT- acc*+pli#he#1 y*u can a#k a #hape re9erence the e;act type that it# re9erring t*) ,ith RTT- y*u can #elect and i#*late #pecial ca#e#)

-he Class o+/ect


T* under#tand h*! RTT- !*rk# in "ava, y*u +u#t 9ir#t kn*! h*! type in9*r+ati*n i# repre#ented at runEti+e) Thi# i# acc*+pli#hed thr*ugh a #pecial kind *9 *34ect called the Class o23ect6 !hich c*ntain# in9*r+ati*n a3*ut the cla##) GThi# i# #*+eti+e# called a meta9class.H -n 9act, the Class *34ect i# u#ed t* create all *9 the IregularJ *34ect# *9 y*ur cla##) There# a Class *34ect 9*r each cla## that i# part *9 y*ur pr*gra+) That i#, each ti+e y*u !rite and c*+pile a ne! cla##, a #ingle Class *34ect i# al#* created Gand #t*red, appr*priately en*ugh, in an identically na+ed 6class 9ileH) =t runEti+e, !hen y*u !ant t* +ake an *34ect *9 that cla##, the "ava Cirtual Aachine G"CAH that# e;ecuting y*ur pr*gra+ 9ir#t check# t* #ee i9 the Class *34ect 9*r that type i# l*aded) -9 n*t, the "CA l*ad# it 3y 9inding the 6class 9ile !ith that na+e) Thu#, a "ava pr*gra+ i#nt c*+pletely l*aded 3e9*re it 3egin#, !hich i# di99erent 9r*+ +any traditi*nal language#) Once the Class *34ect 9*r that type i# in +e+*ry, it i# u#ed t* create all *34ect# *9 that type) -9 thi# #ee+# #had*!y *r i9 y*u d*nt really 3elieve it, here# a de+*n#trati*n pr*gra+ t* pr*ve it1 //: c"2:S.eetShop.Da*a // +xa!ination of the .ay the c a## oader .or%#.

Cha"ter 1)* ?un time T4"e Identi$ication

565

c a## Candy ; #tatic ; Sy#te!.out.print n0&Loading Candy&13 < < c a## _u! ; #tatic ; Sy#te!.out.print n0&Loading _u!&13 < < c a## Coo%ie ; #tatic ; Sy#te!.out.print n0&Loading Coo%ie&13 < < pu$ ic c a## S.eetShop ; pu$ ic #tatic *oid !ain0StringJK arg#1 ; Sy#te!.out.print n0&in#ide !ain&13 ne. Candy013 Sy#te!.out.print n0&)fter creating Candy&13 try ; C a##.forCa!e0&_u!&13 < catch0C a##CotHound+xception e1 ; e.printStac%'race0Sy#te!.err13 < Sy#te!.out.print n0 &)fter C a##.forCa!e0^&_u!^&1&13 ne. Coo%ie013 Sy#te!.out.print n0&)fter creating Coo%ie&13 < < ///:8 Each *9 the cla##e# Candy, um, and Coo(ie have a static clau#e that i# e;ecuted a# the cla## i# l*aded 9*r the 9ir#t ti+e) -n9*r+ati*n !ill 3e printed t* tell y*u !hen l*ading *ccur# 9*r that cla##) -n main( ), the *34ect creati*n# are #pread *ut 3et!een print #tate+ent# t* help detect the ti+e *9 l*ading)

566

Thinking in C

www.ThinkingIn.!et

= particularly intere#ting line i#1 C a##.forCa!e0&_u!&13 Thi# +eth*d i# a static +e+3er *9 Class Gt* !hich all Class *34ect# 3el*ngH) = Class *34ect i# like any *ther *34ect and #* y*u can get and +anipulate a re9erence t* it) GThat# !hat the l*ader d*e#)H One *9 the !ay# t* get a re9erence t* the Class *34ect i# for,ame( ), !hich take# a #tring c*ntaining the te;tual na+e G!atch the #pelling and capitali7ati*nKH *9 the particular cla## y*u !ant a re9erence 9*r) -t return# a Class re9erence) The *utput *9 thi# pr*gra+ 9*r *ne "CA i#1 in#ide !ain Loading Candy )fter creating Candy Loading _u! )fter C a##.forCa!e0&_u!&1 Loading Coo%ie )fter creating Coo%ie :*u can #ee that each Class *34ect i# l*aded *nly !hen it# needed, and the static initiali7ati*n i# per9*r+ed up*n cla## l*ading)

Class literals
"ava pr*vide# a #ec*nd !ay t* pr*duce the re9erence t* the Class *34ect, u#ing a class literal) -n the a3*ve pr*gra+ thi# !*uld l**k like1 _u!.c a##3 !hich i# n*t *nly #i+pler, 3ut al#* #a9er #ince it# checked at c*+pileE ti+e) Becau#e it eli+inate# the +eth*d call, it# al#* +*re e99icient) Cla## literal# !*rk !ith regular cla##e# a# !ell a# inter9ace#, array#, and pri+itive type#) -n additi*n, there# a #tandard 9ield called +@!& that e;i#t# 9*r each *9 the pri+itive !rapper cla##e#) The +@!& 9ield pr*duce# a re9erence t* the Class *34ect 9*r the a##*ciated pri+itive type, #uch that1

Cha"ter 1)* ?un time T4"e Identi$ication

56#

` is e%uivalent to ` boolean6class char6class byte6class short6class int6class long6class float6class double6class void6class Boolean6+@!& Character6+@!& Byte6+@!& #hort6+@!& Bnteger6+@!& Long6+@!& :loat6+@!& $ouble6+@!& Hoid6+@!&

Ay pre9erence i# t* u#e the I6classJ ver#i*n# i9 y*u can, #ince theyre +*re c*n#i#tent !ith regular cla##e#)

Chec*ing +e0ore a cast


S* 9ar, y*uve #een RTT- 9*r+# including1 3. The cla##ic ca#tQ e)g), I(#hape),J !hich u#e# RTT- t* +ake #ure the ca#t i# c*rrect and thr*!# a ClassCast&xception i9 y*uve per9*r+ed a 3ad ca#t)

0.) The Class *34ect repre#enting the type *9 y*ur *34ect) The Class *34ect can 3e Dueried 9*r u#e9ul runEti+e in9*r+ati*n) -n C@@, the cla##ic ca#t I(#hape)J d*e# not per9*r+ RTT-) -t #i+ply tell# the c*+piler t* treat the *34ect a# the ne! type) -n "ava, !hich d*e# per9*r+ the type check, thi# ca#t i# *9ten called a Itype #a9e d*!nca#t)J The rea#*n 9*r the ter+ Id*!nca#tJ i# the hi#t*rical arrange+ent *9 the cla## hierarchy diagra+) -9 ca#ting a Circle t* a #hape i# an upca#t, then ca#ting a #hape t* a Circle i# a d*!nca#t) H*!ever, y*u kn*! a Circle i# al#* a #hape, and the c*+piler 9reely all*!# an upca#t a##ign+ent, 3ut y*u don:t kn*! that a #hape i# nece##arily a Circle, #* the c*+piler

56&

Thinking in C

www.ThinkingIn.!et

d*e#nt all*! y*u t* per9*r+ a d*!nca#t a##ign+ent !ith*ut u#ing an e;plicit ca#t) There# a third 9*r+ *9 RTT- in "ava) Thi# i# the key!*rd instanceof that tell# y*u i9 an *34ect i# an in#tance *9 a particular type) -t return# a boolean #* y*u u#e it in the 9*r+ *9 a Due#ti*n, like thi#1 if0x in#tanceof :og1 00:og1x1.$ar%013 The a3*ve if #tate+ent check# t* #ee i9 the *34ect x 3el*ng# t* the cla## $og 2e$ore ca#ting x t* a $og) -t# i+p*rtant t* u#e instanceof 3e9*re a d*!nca#t !hen y*u d*nt have *ther in9*r+ati*n that tell# y*u the type *9 the *34ectQ *ther!i#e y*ull end up !ith a ClassCast&xception) Ordinarily, y*u +ight 3e hunting 9*r *ne type Gtriangle# t* turn purple, 9*r e;a+pleH, 3ut y*u can ea#ily tally all *9 the *34ect# u#ing instanceof) Supp*#e y*u have a 9a+ily *9 !et cla##e#1 //: c"2:-et#.Da*a c a## -et ;< c a## :og extend# -et ;< c a## -ug extend# :og ;< c a## Cat extend# -et ;< c a## Rodent extend# -et ;< c a## _er$i extend# Rodent ;< c a## Ua!#ter extend# Rodent ;< c a## Counter ; int i3 < ///:8 The Counter cla## i# u#ed t* keep track *9 the nu+3er *9 any particular type *9 !et) :*u c*uld think *9 it a# an Bnteger that can 3e +*di9ied) U#ing instanceof, all the pet# can 3e c*unted1 //: c"2:-etCount.Da*a // O#ing in#tanceof. i!port Da*a.uti .=3 pu$ ic c a## -etCount ; #tatic StringJK typena!e# 9 ; &-et&2 &:og&2 &-ug&2 &Cat&2

Cha"ter 1)* ?un time T4"e Identi$ication

56'

&Rodent&2 &_er$i &2 &Ua!#ter&2 <3 // +xception# thro.n out to con#o e: pu$ ic #tatic *oid !ain0StringJK arg#1 thro.# +xception ; )rrayLi#t pet# 9 ne. )rrayLi#t013 try ; C a##JK pet'ype# 9 ; C a##.forCa!e0&:og&12 C a##.forCa!e0&-ug&12 C a##.forCa!e0&Cat&12 C a##.forCa!e0&Rodent&12 C a##.forCa!e0&_er$i &12 C a##.forCa!e0&Ua!#ter&12 <3 for0int i 9 03 i W "P3 iRR1 pet#.add0 pet'ype#J 0int10Gath.rando!01=pet'ype#. ength1K .ne.5n#tance0113 < catch05n#tantiation+xception e1 ; Sy#te!.err.print n0&Cannot in#tantiate&13 thro. e3 < catch05 ega )cce##+xception e1 ; Sy#te!.err.print n0&Cannot acce##&13 thro. e3 < catch0C a##CotHound+xception e1 ; Sy#te!.err.print n0&Cannot find c a##&13 thro. e3 < Ua#hGap h 9 ne. Ua#hGap013 for0int i 9 03 i W typena!e#. ength3 iRR1 h.put0typena!e#JiK2 ne. Counter0113 for0int i 9 03 i W pet#.#iMe013 iRR1 ; O$Dect o 9 pet#.get0i13 if0o in#tanceof -et1 00Counter1h.get0&-et&11.iRR3 if0o in#tanceof :og1 00Counter1h.get0&:og&11.iRR3 if0o in#tanceof -ug1 00Counter1h.get0&-ug&11.iRR3

5#(

Thinking in C

www.ThinkingIn.!et

if0o in#tanceof Cat1 00Counter1h.get0&Cat&11.iRR3 if0o in#tanceof Rodent1 00Counter1h.get0&Rodent&11.iRR3 if0o in#tanceof _er$i 1 00Counter1h.get0&_er$i &11.iRR3 if0o in#tanceof Ua!#ter1 00Counter1h.get0&Ua!#ter&11.iRR3 < for0int i 9 03 i W pet#.#iMe013 iRR1 Sy#te!.out.print n0pet#.get0i1.getC a##0113 for0int i 9 03 i W typena!e#. ength3 iRR1 Sy#te!.out.print n0 typena!e#JiK R & 7uantity: & R 00Counter1h.get0typena!e#JiK11.i13 < < ///:8 There# a rather narr*! re#tricti*n *n instanceof1 y*u can c*+pare it t* a na+ed type *nly, and n*t t* a Class *34ect) -n the e;a+ple a3*ve y*u +ight 9eel that it# tedi*u# t* !rite *ut all *9 th*#e instanceof e;pre##i*n#, and y*ure right) But there i# n* !ay t* cleverly aut*+ate instanceof 3y creating an 'rrayList *9 Class *34ect# and c*+paring it t* th*#e in#tead G#tay tunedRy*ull #ee an alternativeH) Thi# i#nt a# great a re#tricti*n a# y*u +ight think, 3ecau#e y*ull eventually under#tand that y*ur de#ign i# pr*3a3ly 9la!ed i9 y*u end up !riting a l*t *9 instanceof e;pre##i*n#) O9 c*ur#e thi# e;a+ple i# c*ntrivedRy*ud pr*3a3ly put a static data +e+3er in each type and incre+ent it in the c*n#truct*r t* keep track *9 the c*unt#) :*u !*uld d* #*+ething like that i$ y*u had c*ntr*l *9 the #*urce c*de 9*r the cla## and c*uld change it) Since thi# i# n*t al!ay# the ca#e, RTT- can c*+e in handy)

>sing class literals


-t# intere#ting t* #ee h*! the !etCount6)ava e;a+ple can 3e re!ritten u#ing cla## literal#) The re#ult i# cleaner in +any !ay#1 //: c"2:-etCount2.Da*a // O#ing c a## itera #.

Cha"ter 1)* ?un time T4"e Identi$ication

5#1

i!port Da*a.uti .=3 pu$ ic c a## -etCount2 ; pu$ ic #tatic *oid !ain0StringJK arg#1 thro.# +xception ; )rrayLi#t pet# 9 ne. )rrayLi#t013 C a##JK pet'ype# 9 ; // C a## itera #: -et.c a##2 :og.c a##2 -ug.c a##2 Cat.c a##2 Rodent.c a##2 _er$i .c a##2 Ua!#ter.c a##2 <3 try ; for0int i 9 03 i W "P3 iRR1 ; // Off#et $y one to e i!inate -et.c a##: int rnd 9 " R 0int10 Gath.rando!01 = 0pet'ype#. ength 6 "113 pet#.add0 pet'ype#JrndK.ne.5n#tance0113 < < catch05n#tantiation+xception e1 ; Sy#te!.err.print n0&Cannot in#tantiate&13 thro. e3 < catch05 ega )cce##+xception e1 ; Sy#te!.err.print n0&Cannot acce##&13 thro. e3 < Ua#hGap h 9 ne. Ua#hGap013 for0int i 9 03 i W pet'ype#. ength3 iRR1 h.put0pet'ype#JiK.toString012 ne. Counter0113 for0int i 9 03 i W pet#.#iMe013 iRR1 ; O$Dect o 9 pet#.get0i13 if0o in#tanceof -et1 00Counter1h.get0&c a## -et&11.iRR3 if0o in#tanceof :og1 00Counter1h.get0&c a## :og&11.iRR3

5#)

Thinking in C

www.ThinkingIn.!et

if0o in#tanceof -ug1 00Counter1h.get0&c a## if0o in#tanceof Cat1 00Counter1h.get0&c a## if0o in#tanceof Rodent1 00Counter1h.get0&c a## if0o in#tanceof _er$i 1 00Counter1h.get0&c a## if0o in#tanceof Ua!#ter1 00Counter1h.get0&c a##

-ug&11.iRR3 Cat&11.iRR3 Rodent&11.iRR3 _er$i &11.iRR3 Ua!#ter&11.iRR3

< for0int i 9 03 i W pet#.#iMe013 iRR1 Sy#te!.out.print n0pet#.get0i1.getC a##0113 5terator %ey# 9 h.%eySet01.iterator013 .hi e0%ey#.ha#Cext011 ; String n! 9 0String1%ey#.next013 Counter cnt 9 0Counter1h.get0n!13 Sy#te!.out.print n0 n!.#u$#tring0n!. a#t5ndexOf0'.'1 R "1 R & 7uantity: & R cnt.i13 < < < ///:8 Here, the typenames array ha# 3een re+*ved in 9av*r *9 getting the type na+e #tring# 9r*+ the Class *34ect) *tice that the #y#te+ can di#tingui#h 3et!een cla##e# and inter9ace#) :*u can al#* #ee that the creati*n *9 pet+ypes d*e# n*t need t* 3e #urr*unded 3y a try 3l*ck #ince it# evaluated at c*+pileEti+e and thu# !*nt thr*! any e;cepti*n#, unlike Class6for,ame( )) ,hen the !et *34ect# are dyna+ically created, y*u can #ee that the rand*+ nu+3er i# re#tricted #* it i# 3et!een *ne and pet+ypes6length and d*e# n*t include 7er*) That# 3ecau#e 7er* re9er# t* !et6class, and pre#u+a3ly a generic !et *34ect i# n*t intere#ting) H*!ever, #ince !et6class i# part *9 pet+ypes the re#ult i# that all *9 the pet# get c*unted)

Cha"ter 1)* ?un time T4"e Identi$ication

5#3

) d5na#ic instanceof
The Class isBnstance +eth*d pr*vide# a !ay t* dyna+ically call the instanceof *perat*r) Thu#, all th*#e tedi*u# instanceof #tate+ent# can 3e re+*ved in the !etCount e;a+ple1 //: c"2:-etCountT.Da*a // O#ing i#5n#tance01. i!port Da*a.uti .=3 pu$ ic c a## -etCountT ; pu$ ic #tatic *oid !ain0StringJK arg#1 thro.# +xception ; )rrayLi#t pet# 9 ne. )rrayLi#t013 C a##JK pet'ype# 9 ; -et.c a##2 :og.c a##2 -ug.c a##2 Cat.c a##2 Rodent.c a##2 _er$i .c a##2 Ua!#ter.c a##2 <3 try ; for0int i 9 03 i W "P3 iRR1 ; // Off#et $y one to e i!inate -et.c a##: int rnd 9 " R 0int10 Gath.rando!01 = 0pet'ype#. ength 6 "113 pet#.add0 pet'ype#JrndK.ne.5n#tance0113 < < catch05n#tantiation+xception e1 ; Sy#te!.err.print n0&Cannot in#tantiate&13 thro. e3 < catch05 ega )cce##+xception e1 ; Sy#te!.err.print n0&Cannot acce##&13 thro. e3 < Ua#hGap h 9 ne. Ua#hGap013 for0int i 9 03 i W pet'ype#. ength3 iRR1 h.put0pet'ype#JiK.toString012

5#4

Thinking in C

www.ThinkingIn.!et

ne. Counter0113 for0int i 9 03 i W pet#.#iMe013 iRR1 ; O$Dect o 9 pet#.get0i13 // O#ing i#5n#tance to e i!inate indi*idua // in#tanceof expre##ion#: for 0int D 9 03 D W pet'ype#. ength3 RRD1 if 0pet'ype#JDK.i#5n#tance0o11 ; String %ey 9 pet'ype#JDK.toString013 00Counter1h.get0%ey11.iRR3 < < for0int i 9 03 i W pet#.#iMe013 iRR1 Sy#te!.out.print n0pet#.get0i1.getC a##0113 5terator %ey# 9 h.%eySet01.iterator013 .hi e0%ey#.ha#Cext011 ; String n! 9 0String1%ey#.next013 Counter cnt 9 0Counter1h.get0n!13 Sy#te!.out.print n0 n!.#u$#tring0n!. a#t5ndexOf0'.'1 R "1 R & 7uantity: & R cnt.i13 < < < ///:8 :*u can #ee that the isBnstance( ) +eth*d ha# eli+inated the need 9*r the instanceof e;pre##i*n#) -n additi*n, thi# +ean# that y*u can add ne! type# *9 pet# #i+ply 3y changing the pet+ypes arrayQ the re#t *9 the pr*gra+ d*e# n*t need +*di9icati*n Ga# it did !hen u#ing the instanceof e;pre##i*n#H)

instanceof vs. Class equivalence


,hen Duerying 9*r type in9*r+ati*n, there# an i+p*rtant di99erence 3et!een either 9*r+ *9 instanceof Gthat i#, instanceof *r isBnstance( ), !hich pr*duce eDuivalent re#ult#H and the direct c*+pari#*n *9 the Class *34ect#) Here# an e;a+ple that de+*n#trate# the di99erence1 //: c"2:Ha!i yN#+xact'ype.Da*a // 'he difference $et.een in#tanceof and c a##

Cha"ter 1)* ?un time T4"e Identi$ication

5#5

c a## Ba#e ;< c a## :eri*ed extend# Ba#e ;< pu$ ic c a## Ha!i yN#+xact'ype ; #tatic *oid te#t0O$Dect x1 ; Sy#te!.out.print n0&'e#ting x of type & R x.getC a##0113 Sy#te!.out.print n0&x in#tanceof Ba#e & R 0x in#tanceof Ba#e113 Sy#te!.out.print n0&x in#tanceof :eri*ed & R 0x in#tanceof :eri*ed113 Sy#te!.out.print n0&Ba#e.i#5n#tance0x1 & R Ba#e.c a##.i#5n#tance0x113 Sy#te!.out.print n0&:eri*ed.i#5n#tance0x1 & R :eri*ed.c a##.i#5n#tance0x113 Sy#te!.out.print n0 &x.getC a##01 99 Ba#e.c a## & R 0x.getC a##01 99 Ba#e.c a##113 Sy#te!.out.print n0 &x.getC a##01 99 :eri*ed.c a## & R 0x.getC a##01 99 :eri*ed.c a##113 Sy#te!.out.print n0 &x.getC a##01.e7ua #0Ba#e.c a##11 & R 0x.getC a##01.e7ua #0Ba#e.c a##1113 Sy#te!.out.print n0 &x.getC a##01.e7ua #0:eri*ed.c a##11 & R 0x.getC a##01.e7ua #0:eri*ed.c a##1113 < pu$ ic #tatic *oid !ain0StringJK arg#1 ; te#t0ne. Ba#e0113 te#t0ne. :eri*ed0113 < < ///:8 The test( ) +eth*d per9*r+# type checking !ith it# argu+ent u#ing 3*th 9*r+# *9 instanceof) -t then get# the Class re9erence and u#e# II and e%uals( ) t* te#t 9*r eDuality *9 the Class *34ect#) Here i# the *utput1 'e#ting x of type c a## Ba#e x in#tanceof Ba#e true x in#tanceof :eri*ed fa #e Ba#e.i#5n#tance0x1 true

5#6

Thinking in C

www.ThinkingIn.!et

:eri*ed.i#5n#tance0x1 fa #e x.getC a##01 99 Ba#e.c a## true x.getC a##01 99 :eri*ed.c a## fa #e x.getC a##01.e7ua #0Ba#e.c a##11 true x.getC a##01.e7ua #0:eri*ed.c a##11 fa #e 'e#ting x of type c a## :eri*ed x in#tanceof Ba#e true x in#tanceof :eri*ed true Ba#e.i#5n#tance0x1 true :eri*ed.i#5n#tance0x1 true x.getC a##01 99 Ba#e.c a## fa #e x.getC a##01 99 :eri*ed.c a## true x.getC a##01.e7ua #0Ba#e.c a##11 fa #e x.getC a##01.e7ua #0:eri*ed.c a##11 true Rea##uringly, instanceof and isBnstance( ) pr*duce e;actly the #a+e re#ult#, a# d* e%uals( ) and II) But the te#t# the+#elve# dra! di99erent c*nclu#i*n#) -n keeping !ith the c*ncept *9 type, instanceof #ay# Iare y*u thi# cla##, *r a cla## derived 9r*+ thi# cla##FJ On the *ther hand, i9 y*u c*+pare the actual Class *34ect# u#ing II, there i# n* c*ncern !ith inheritanceRit# either the e;act type *r it i#nt)

6--I s5nta&
"ava per9*r+# it# RTT- u#ing the Class *34ect, even i9 y*ure d*ing #*+ething like a ca#t) The cla## Class al#* ha# a nu+3er *9 *ther !ay# y*u can u#e RTT-) 5ir#t, y*u +u#t get a re9erence t* the appr*priate Class *34ect) One !ay t* d* thi#, a# #h*!n in the previ*u# e;a+ple, i# t* u#e a #tring and the Class6for,ame( ) +eth*d) Thi# i# c*nvenient 3ecau#e y*u d*nt need an *34ect *9 that type in *rder t* get the Class re9erence) H*!ever, i9 y*u d* already have an *34ect *9 the type y*ure intere#ted in, y*u can 9etch the Class re9erence 3y calling a +eth*d that# part *9 the ob)ect r**t cla##1 getClass( )) Thi# return# the Class re9erence repre#enting the actual type *9 the *34ect) Class ha# +any intere#ting +eth*d#, de+*n#trated in the 9*ll*!ing e;a+ple1 //: c"2:'oy'e#t.Da*a // 'e#ting c a## C a##.

Cha"ter 1)* ?un time T4"e Identi$ication

5##

interface Ua#Batterie# ;< interface Vaterproof ;< interface Shoot#'hing# ;< c a## 'oy ; // Co!!ent out the fo o.ing defau t // con#tructor to #ee // CoSuchGethod+rror fro! 0="=1 'oy01 ;< 'oy0int i1 ;< < c a## Hancy'oy extend# 'oy i!p e!ent# Ua#Batterie#2 Vaterproof2 Shoot#'hing# ; Hancy'oy01 ; #uper0"13 < < pu$ ic c a## 'oy'e#t ; pu$ ic #tatic *oid !ain0StringJK arg#1 thro.# +xception ; C a## c 9 nu 3 try ; c 9 C a##.forCa!e0&Hancy'oy&13 < catch0C a##CotHound+xception e1 ; Sy#te!.err.print n0&Can't find Hancy'oy&13 thro. e3 < print5nfo0c13 C a##JK face# 9 c.get5nterface#013 for0int i 9 03 i W face#. ength3 iRR1 print5nfo0face#JiK13 C a## cy 9 c.getSuperc a##013 O$Dect o 9 nu 3 try ; // Re7uire# defau t con#tructor: o 9 cy.ne.5n#tance013 // 0="=1 < catch05n#tantiation+xception e1 ; Sy#te!.err.print n0&Cannot in#tantiate&13 thro. e3 < catch05 ega )cce##+xception e1 ;

5#&

Thinking in C

www.ThinkingIn.!et

Sy#te!.err.print n0&Cannot acce##&13 thro. e3 < print5nfo0o.getC a##0113 < #tatic *oid print5nfo0C a## cc1 ; Sy#te!.out.print n0 &C a## na!e: & R cc.getCa!e01 R & i# interfaceY J& R cc.i#5nterface01 R &K&13 < < ///:8 :*u can #ee that class :ancy+oy i# Duite c*+plicated, #ince it inherit# 9r*+ +oy and implements the interface# *9 "asBatteries, =aterproof, and #hoots+hings) -n main( ), a Class re9erence i# created and initiali7ed t* the :ancy+oy Class u#ing for,ame( ) in#ide an appr*priate try 3l*ck) The Class6getBnterfaces( ) +eth*d return# an array *9 Class *34ect# repre#enting the inter9ace# that are c*ntained in the Class *34ect *9 intere#t) -9 y*u have a Class *34ect y*u can al#* a#k it 9*r it# direct 3a#e cla## u#ing get#uperclass( )) Thi#, *9 c*ur#e, return# a Class re9erence that y*u can 9urther Duery) Thi# +ean# that, at runEti+e, y*u can di#c*ver an *34ect# entire cla## hierarchy) The newBnstance( ) +eth*d *9 Class can, at 9ir#t, #ee+ like 4u#t an*ther !ay t* clone( ) an *34ect) H*!ever, y*u can create a ne! *34ect !ith newBnstance( ) without an e;i#ting *34ect, a# #een here, 3ecau#e there i# n* +oy *34ectR*nly cy, !hich i# a re9erence t* y# Class *34ect) Thi# i# a !ay t* i+ple+ent a Ivirtual c*n#truct*r,J !hich all*!# y*u t* #ay Id*nt kn*! e;actly !hat type y*u are, 3ut create y*ur#el9 pr*perly any!ay)J -n the e;a+ple a3*ve, cy i# 4u#t a Class re9erence !ith n* 9urther type in9*r+ati*n kn*!n at c*+pileEti+e) =nd !hen y*u create a ne! in#tance, y*u get 3ack an ob)ect reference) But that re9erence i# p*inting t* a +oy *34ect) O9 c*ur#e, 3e9*re y*u can #end any +e##age# *ther than th*#e accepted 3y ob)ect, y*u have t* inve#tigate it a 3it and d* #*+e ca#ting) -n additi*n, the cla## that# 3eing created !ith

Cha"ter 1)* ?un time T4"e Identi$ication

5#'

newBnstance( ) +u#t have a de9ault c*n#truct*r) -n the ne;t #ecti*n, y*ull #ee h*! t* dyna+ically create *34ect# *9 cla##e# u#ing any c*n#truct*r, !ith the "ava re$lection =P-) The 9inal +eth*d in the li#ting i# printBnfo( ), !hich take# a Class re9erence and get# it# na+e !ith get,ame( ), and 9ind# *ut !hether it# an inter9ace !ith isBnterface( )) The *utput 9r*+ thi# pr*gra+ i#1 C C C C C a## a## a## a## a## na!e: na!e: na!e: na!e: na!e: Hancy'oy i# interfaceY Jfa #eK Ua#Batterie# i# interfaceY JtrueK Vaterproof i# interfaceY JtrueK Shoot#'hing# i# interfaceY JtrueK 'oy i# interfaceY Jfa #eK

Thu#, !ith the Class *34ect y*u can 9ind *ut 4u#t a3*ut everything y*u !ant t* kn*! a3*ut an *34ect)

6e0lection, run;ti#e class in0or#ation


-9 y*u d*nt kn*! the preci#e type *9 an *34ect, RTT- !ill tell y*u) H*!ever, there# a li+itati*n1 the type +u#t 3e kn*!n at c*+pileEti+e in *rder 9*r y*u t* 3e a3le t* detect it u#ing RTT- and d* #*+ething u#e9ul !ith the in9*r+ati*n) Put an*ther !ay, the c*+piler +u#t kn*! a3*ut all the cla##e# y*ure !*rking !ith 9*r RTT-) Thi# d*e#nt #ee+ like that +uch *9 a li+itati*n at 9ir#t, 3ut #upp*#e y*ure given a re9erence t* an *34ect that# n*t in y*ur pr*gra+ #pace) -n 9act, the cla## *9 the *34ect i#nt even availa3le t* y*ur pr*gra+ at c*+pileEti+e) 5*r e;a+ple, #upp*#e y*u get a 3unch *9 3yte# 9r*+ a di#k 9ile *r 9r*+ a net!*rk c*nnecti*n and y*ure t*ld that th*#e 3yte# repre#ent a cla##) Since the c*+piler cant kn*! a3*ut the cla## !hile it# c*+piling the c*de, h*! can y*u p*##i3ly u#e #uch a cla##F -n a traditi*nal pr*gra++ing envir*n+ent thi# #ee+# like a 9arE9etched #cenari*) But a# !e +*ve int* a larger pr*gra++ing !*rld there are i+p*rtant ca#e# in !hich thi# happen#) The 9ir#t i# c*+p*nentE3a#ed

5&(

Thinking in C

www.ThinkingIn.!et

pr*gra++ing, in !hich y*u 3uild pr*4ect# u#ing ?a"id 5""lication Ce-elo"ment GR=?H in an applicati*n 3uilder t**l) Thi# i# a vi#ual appr*ach t* creating a pr*gra+ G!hich y*u #ee *n the #creen a# a I9*r+JH 3y +*ving ic*n# that repre#ent c*+p*nent# *nt* the 9*r+) The#e c*+p*nent# are then c*n9igured 3y #etting #*+e *9 their value# at pr*gra+ ti+e) Thi# de#ignEti+e c*n9igurati*n reDuire# that any c*+p*nent 3e in#tantia3le, that it e;p*#e# part# *9 it#el9, and that it all*!# it# value# t* 3e read and #et) -n additi*n, c*+p*nent# that handle >Uevent# +u#t e;p*#e in9*r+ati*n a3*ut appr*priate +eth*d# #* that the R=? envir*n+ent can a##i#t the pr*gra++er in *verriding the#e eventE handling +eth*d#) Re9lecti*n pr*vide# the +echani#+ t* detect the availa3le +eth*d# and pr*duce the +eth*d na+e#) "ava pr*vide# a #tructure 9*r c*+p*nentE3a#ed pr*gra++ing thr*ugh "avaBean# Gde#cri3ed in Chapter 0/H) =n*ther c*+pelling +*tivati*n 9*r di#c*vering cla## in9*r+ati*n at runE ti+e i# t* pr*vide the a3ility t* create and e;ecute *34ect# *n re+*te plat9*r+# acr*## a net!*rk) Thi# i# called ?emote .ethod In-ocation GRA-H and it all*!# a "ava pr*gra+ t* have *34ect# di#tri3uted acr*## +any +achine#) Thi# di#tri3uti*n can happen 9*r a nu+3er *9 rea#*n#1 9*r e;a+ple, perhap# y*ure d*ing a c*+putati*nEinten#ive ta#k and y*u !ant t* 3reak it up and put piece# *n +achine# that are idle in *rder t* #peed thing# up) -n #*+e #ituati*n# y*u +ight !ant t* place c*de that handle# particular type# *9 ta#k# Ge)g), IBu#ine## Rule#J in a +ultitier client<#erver architectureH *n a particular +achine, #* that +achine 3ec*+e# a c*++*n rep*#it*ry de#cri3ing th*#e acti*n# and it can 3e ea#ily changed t* a99ect every*ne in the #y#te+) GThi# i# an intere#ting devel*p+ent, #ince the +achine e;i#t# #*lely t* +ake #*9t!are change# ea#yKH =l*ng the#e line#, di#tri3uted c*+puting al#* #upp*rt# #peciali7ed hard!are that +ight 3e g**d at a particular ta#kR+atri; inver#i*n#, 9*r e;a+pleR3ut inappr*priate *r t** e;pen#ive 9*r general purp*#e pr*gra++ing) The cla## Class Gde#cri3ed previ*u#ly in thi# chapterH #upp*rt# the c*ncept *9 re$lection, and there# an additi*nal li3rary, )ava6lang6reflect, !ith cla##e# :ield, .ethod, and Constructor Geach *9 !hich i+ple+ent the .ember interfaceH) O34ect# *9 the#e type# are created 3y the "CA at runEti+e t* repre#ent the c*rre#p*nding +e+3er in the unkn*!n cla##) :*u can then u#e the Constructor# t*

Cha"ter 1)* ?un time T4"e Identi$ication

5&1

create ne! *34ect#, the get( ) and set( ) +eth*d# t* read and +*di9y the 9ield# a##*ciated !ith :ield *34ect#, and the invo(e( ) +eth*d t* call a +eth*d a##*ciated !ith a .ethod *34ect) -n additi*n, y*u can call the c*nvenience +eth*d# get:ields( ), get.ethods( ), getConstructors( ), etc), t* return array# *9 the *34ect# repre#enting the 9ield#, +eth*d#, and c*n#truct*r#) G:*u can 9ind *ut +*re 3y l**king up the cla## Class in y*ur *nline d*cu+entati*n)H Thu#, the cla## in9*r+ati*n 9*r an*ny+*u# *34ect# can 3e c*+pletely deter+ined at runE ti+e, and n*thing need 3e kn*!n at c*+pileEti+e) -t# i+p*rtant t* reali7e that there# n*thing +agic a3*ut re9lecti*n) ,hen y*ure u#ing re9lecti*n t* interact !ith an *34ect *9 an unkn*!n type, the "CA !ill #i+ply l**k at the *34ect and #ee that it 3el*ng# t* a particular cla## G4u#t like *rdinary RTT-H 3ut then, 3e9*re it can d* anything el#e, the Class *34ect +u#t 3e l*aded) Thu#, the 6class 9ile 9*r that particular type +u#t #till 3e availa3le t* the "CA, either *n the l*cal +achine *r acr*## the net!*rk) S* the true di99erence 3et!een RTT- and re9lecti*n i# that !ith RTT-, the c*+piler *pen# and e;a+ine# the 6class 9ile at c*+pileE ti+e) Put an*ther !ay, y*u can call all the +eth*d# *9 an *34ect in the In*r+alJ !ay) ,ith re9lecti*n, the 6class 9ile i# unavaila3le at c*+pileE ti+eQ it i# *pened and e;a+ined 3y the runEti+e envir*n+ent)

) class #ethod e&tractor


:*ull rarely need t* u#e the re9lecti*n t**l# directlyQ theyre in the language t* #upp*rt *ther "ava 9eature#, #uch a# *34ect #eriali7ati*n GChapter 00H, "avaBean# GChapter 0/H, and RA- GChapter 0'H) H*!ever, there are ti+e# !hen it# Duite u#e9ul t* 3e a3le t* dyna+ically e;tract in9*r+ati*n a3*ut a cla##) One e;tre+ely u#e9ul t**l i# a cla## +eth*d e;tract*r) =# +enti*ned 3e9*re, l**king at a cla## de9initi*n #*urce c*de *r *nline d*cu+entati*n #h*!# *nly the +eth*d# that are de9ined *r *verridden within that class de$inition) But there c*uld 3e d*7en# +*re availa3le t* y*u that have c*+e 9r*+ 3a#e cla##e#) T* l*cate the#e i# 3*th tedi*u# and ti+e c*n#u+ing0) 5*rtunately, re9lecti*n pr*vide# a !ay t* !rite a #i+ple t**l that !ill aut*+atically #h*! y*u the entire inter9ace) Here# the !ay it !*rk#1
0 E#pecially in the pa#t) H*!ever, Sun ha# greatly i+pr*ved it# HTAL "ava d*cu+entati*n

#* that it# ea#ier t* #ee 3a#eEcla## +eth*d#)

5&)

Thinking in C

www.ThinkingIn.!et

//: c"2:Sho.Gethod#.Da*a // O#ing ref ection to #ho. a the !ethod# of // a c a##2 e*en if the !ethod# are defined in // the $a#e c a##. i!port Da*a. ang.ref ect.=3 pu$ ic c a## Sho.Gethod# ; #tatic fina String u#age 9 &u#age: ^n& R &Sho.Gethod# 7ua ified.c a##.na!e^n& R &'o #ho. a !ethod# in c a## or: ^n& R &Sho.Gethod# 7ua ified.c a##.na!e .ord^n& R &'o #earch for !ethod# in*o *ing '.ord'&3 pu$ ic #tatic *oid !ain0StringJK arg#1 ; if0arg#. ength W "1 ; Sy#te!.out.print n0u#age13 Sy#te!.exit0013 < try ; C a## c 9 C a##.forCa!e0arg#J0K13 GethodJK ! 9 c.getGethod#013 Con#tructorJK ctor 9 c.getCon#tructor#013 if0arg#. ength 99 "1 ; for 0int i 9 03 i W !. ength3 iRR1 Sy#te!.out.print n0!JiK13 for 0int i 9 03 i W ctor. ength3 iRR1 Sy#te!.out.print n0ctorJiK13 < e #e ; for 0int i 9 03 i W !. ength3 iRR1 if0!JiK.toString01 .indexOf0arg#J"K1!9 6"1 Sy#te!.out.print n0!JiK13 for 0int i 9 03 i W ctor. ength3 iRR1 if0ctorJiK.toString01 .indexOf0arg#J"K1!9 6"1 Sy#te!.out.print n0ctorJiK13 < < catch0C a##CotHound+xception e1 ; Sy#te!.err.print n0&Co #uch c a##: & R e13 < <

Cha"ter 1)* ?un time T4"e Identi$ication

5&3

< ///:8 The Class +eth*d# get.ethods( ) and getConstructors( ) return an array *9 .ethod and Constructor, re#pectively) Each *9 the#e cla##e# ha# 9urther +eth*d# t* di##ect the na+e#, argu+ent#, and return value# *9 the +eth*d# they repre#ent) But y*u can al#* 4u#t u#e to#tring( ), a# i# d*ne here, t* pr*duce a #tring !ith the entire +eth*d #ignature) The re#t *9 the c*de i# 4u#t 9*r e;tracting c*++and line in9*r+ati*n, deter+ining i9 a particular #ignature +atche# !ith y*ur target #tring Gu#ing index1f( )H, and printing the re#ult#) Thi# #h*!# re9lecti*n in acti*n, #ince the re#ult pr*duced 3y Class6for,ame( ) cann*t 3e kn*!n at c*+pileEti+e, and there9*re all the +eth*d #ignature in9*r+ati*n i# 3eing e;tracted at runEti+e) -9 y*u inve#tigate y*ur *nline d*cu+entati*n *n re9lecti*n, y*ull #ee that there i# en*ugh #upp*rt t* actually #et up and +ake a +eth*d call *n an *34ect that# t*tally unkn*!n at c*+pileEti+e Gthere !ill 3e e;a+ple# *9 thi# later in thi# 3**kH) =gain, thi# i# #*+ething y*u +ay never need t* d* y*ur#el9Rthe #upp*rt i# there 9*r RA- and #* a pr*gra++ing envir*n+ent can +anipulate "avaBean#R3ut it# intere#ting) =n enlightening e;peri+ent i# t* run Da*a Sho.Gethod# Sho.Gethod# Thi# pr*duce# a li#ting that include# a public de9ault c*n#truct*r, even th*ugh y*u can #ee 9r*+ the c*de that n* c*n#truct*r !a# de9ined) The c*n#truct*r y*u #ee i# the *ne that# aut*+atically #ynthe#i7ed 3y the c*+piler) -9 y*u then +ake #how.ethods a n*nEpublic cla## Gthat i#, 9riendlyH, the #ynthe#i7ed de9ault c*n#truct*r n* l*nger #h*!# up in the *utput) The #ynthe#i7ed de9ault c*n#truct*r i# aut*+atically given the #a+e acce## a# the cla##) The *utput 9*r #how.ethods i# #till a little tedi*u#) 5*r e;a+ple, here# a p*rti*n *9 the *utput pr*duced 3y inv*king )ava #how.ethods )ava6lang6#tring1 pu$ ic $oo ean Da*a. ang.String.#tart#Vith0Da*a. ang.String2int1 pu$ ic $oo ean Da*a. ang.String.#tart#Vith0Da*a. ang.String1

5&4

Thinking in C

www.ThinkingIn.!et

pu$ ic $oo ean Da*a. ang.String.end#Vith0Da*a. ang.String1 -t !*uld 3e even nicer i9 the Duali9ier# like )ava6lang c*uld 3e #tripped *99) The #tream+o(eniTer cla## intr*duced in the previ*u# chapter can help create a t**l t* #*lve thi# pr*3le+1 //: co!:$ruceec%e :uti :StripQua ifier#.Da*a pac%age co!.$ruceec%e .uti 3 i!port Da*a.io.=3 pu$ ic c a## StripQua ifier# ; pri*ate Strea!'o%eniMer #t3 pu$ ic StripQua ifier#0String 7ua ified1 ; #t 9 ne. Strea!'o%eniMer0 ne. StringReader07ua ified113 #t.ordinaryChar0' '13 // aeep the #pace# < pu$ ic String getCext01 ; String # 9 nu 3 try ; int to%en 9 #t.next'o%en013 if0to%en !9 Strea!'o%eniMer.''X+OH1 ; #.itch0#t.ttype1 ; ca#e Strea!'o%eniMer.''X+OL: # 9 nu 3 $rea%3 ca#e Strea!'o%eniMer.''XCOGB+R: # 9 :ou$ e.toString0#t.n*a 13 $rea%3 ca#e Strea!'o%eniMer.''XVOR:: # 9 ne. String0#t.#*a 13 $rea%3 defau t: // #ing e character in ttype # 9 String.*a ueOf00char1#t.ttype13 < < < catch05O+xception e1 ; Sy#te!.err.print n0&+rror fetching to%en&13 < return #3

Cha"ter 1)* ?un time T4"e Identi$ication

5&5

< pu$ ic #tatic String #trip0String 7ua ified1 ; StripQua ifier# #7 9 ne. StripQua ifier#07ua ified13 String # 9 &&2 #i3 .hi e00#i 9 #7.getCext011 !9 nu 1 ; int a#t:ot 9 #i. a#t5ndexOf0'.'13 if0 a#t:ot !9 6"1 #i 9 #i.#u$#tring0 a#t:ot R "13 # R9 #i3 < return #3 < < ///:8 T* 9acilitate reu#e, thi# cla## i# placed in com6bruceec(el6util) =# y*u can #ee, thi# u#e# the #tream+o(eniTer and #tring +anipulati*n t* d* it# !*rk) The ne! ver#i*n *9 the pr*gra+ u#e# the a3*ve cla## t* clean up the *utput1 //: c"2:Sho.Gethod#C ean.Da*a // Sho.Gethod# .ith the 7ua ifier# #tripped // to !a%e the re#u t# ea#ier to read. i!port Da*a. ang.ref ect.=3 i!port co!.$ruceec%e .uti .=3 pu$ ic c a## Sho.Gethod#C ean ; #tatic fina String u#age 9 &u#age: ^n& R &Sho.Gethod#C ean 7ua ified.c a##.na!e^n& R &'o #ho. a !ethod# in c a## or: ^n& R &Sho.Gethod#C ean 7ua if.c a##.na!e .ord^n& R &'o #earch for !ethod# in*o *ing '.ord'&3 pu$ ic #tatic *oid !ain0StringJK arg#1 ; if0arg#. ength W "1 ; Sy#te!.out.print n0u#age13 Sy#te!.exit0013 < try ; C a## c 9 C a##.forCa!e0arg#J0K13

5&6

Thinking in C

www.ThinkingIn.!et

GethodJK ! 9 c.getGethod#013 Con#tructorJK ctor 9 c.getCon#tructor#013 // Con*ert to an array of c eaned String#: StringJK n 9 ne. StringJ!. ength R ctor. engthK3 for0int i 9 03 i W !. ength3 iRR1 ; String # 9 !JiK.toString013 nJiK 9 StripQua ifier#.#trip0#13 < for0int i 9 03 i W ctor. ength3 iRR1 ; String # 9 ctorJiK.toString013 nJi R !. engthK 9 StripQua ifier#.#trip0#13 < if0arg#. ength 99 "1 for 0int i 9 03 i W n. ength3 iRR1 Sy#te!.out.print n0nJiK13 e #e for 0int i 9 03 i W n. ength3 iRR1 if0nJiK.indexOf0arg#J"K1!9 6"1 Sy#te!.out.print n0nJiK13 < catch0C a##CotHound+xception e1 ; Sy#te!.err.print n0&Co #uch c a##: & R e13 < < < ///:8 The cla## #how.ethodsClean i# Duite #i+ilar t* the previ*u# #how.ethods, e;cept that it take# the array# *9 .ethod and Constructor and c*nvert# the+ int* a #ingle array *9 #tring) Each *9 the#e #tring *34ect# i# then pa##ed thr*ugh #trip_ualifiers6#trip( ) t* re+*ve all the +eth*d Duali9icati*n) Thi# t**l can 3e a real ti+eE#aver !hile y*ure pr*gra++ing, !hen y*u cant re+e+3er i9 a cla## ha# a particular +eth*d and y*u d*nt !ant t* g* !alking thr*ugh the cla## hierarchy in the *nline d*cu+entati*n, *r i9 y*u d*nt kn*! !hether that cla## can d* anything !ith, 9*r e;a+ple, Color *34ect#)

Cha"ter 1)* ?un time T4"e Identi$ication

5&#

Chapter 0/ c*ntain# a >U- ver#i*n *9 thi# pr*gra+ Gcu#t*+i7ed t* e;tract in9*r+ati*n 9*r S!ing c*+p*nent#H #* y*u can leave it running !hile y*ure !riting c*de, t* all*! Duick l**kup#)

'u##ar5
RTT- all*!# y*u t* di#c*ver type in9*r+ati*n 9r*+ an an*ny+*u# 3a#eE cla## re9erence) Thu#, it# ripe 9*r +i#u#e 3y the n*vice #ince it +ight +ake #en#e 3e9*re p*ly+*rphic +eth*d call# d*) 5*r +any pe*ple c*+ing 9r*+ a pr*cedural 3ackgr*und, it# di99icult n*t t* *rgani7e their pr*gra+# int* #et# *9 switch #tate+ent#) They c*uld acc*+pli#h thi# !ith RTT- and thu# l*#e the i+p*rtant value *9 p*ly+*rphi#+ in c*de devel*p+ent and +aintenance) The intent *9 "ava i# that y*u u#e p*ly+*rphic +eth*d call# thr*ugh*ut y*ur c*de, and y*u u#e RTT- *nly !hen y*u +u#t) H*!ever, u#ing p*ly+*rphic +eth*d call# a# they are intended reDuire# that y*u have c*ntr*l *9 the 3a#eEcla## de9initi*n 3ecau#e at #*+e p*int in the e;ten#i*n *9 y*ur pr*gra+ y*u +ight di#c*ver that the 3a#e cla## d*e#nt include the +eth*d y*u need) -9 the 3a#e cla## c*+e# 9r*+ a li3rary *r i# *ther!i#e c*ntr*lled 3y #*+e*ne el#e, a #*luti*n t* the pr*3le+ i# RTT-1 :*u can inherit a ne! type and add y*ur e;tra +eth*d) El#e!here in the c*de y*u can detect y*ur particular type and call that #pecial +eth*d) Thi# d*e#nt de#tr*y the p*ly+*rphi#+ and e;ten#i3ility *9 the pr*gra+ 3ecau#e adding a ne! type !ill n*t reDuire y*u t* hunt 9*r #!itch #tate+ent# in y*ur pr*gra+) H*!ever, !hen y*u add ne! c*de in y*ur +ain 3*dy that reDuire# y*ur ne! 9eature, y*u +u#t u#e RTT- t* detect y*ur particular type) Putting a 9eature in a 3a#e cla## +ight +ean that, 9*r the 3ene9it *9 *ne particular cla##, all *9 the *ther cla##e# derived 9r*+ that 3a#e reDuire #*+e +eaningle## #tu3 *9 a +eth*d) Thi# +ake# the inter9ace le## clear and ann*y# th*#e !h* +u#t *verride a3#tract +eth*d# !hen they derive 9r*+ that 3a#e cla##) 5*r e;a+ple, c*n#ider a cla## hierarchy repre#enting +u#ical in#tru+ent#) Supp*#e y*u !anted t* clear the #pit valve# *9 all the appr*priate in#tru+ent# in y*ur *rche#tra) One *pti*n i# t* put a clear#pitHalve( ) +eth*d in the 3a#e cla## Bnstrument, 3ut thi# i# c*n9u#ing 3ecau#e it i+plie# that !ercussion and &lectronic in#tru+ent# al#* have #pit valve#) RTT- pr*vide# a +uch +*re rea#*na3le

5&&

Thinking in C

www.ThinkingIn.!et

#*luti*n in thi# ca#e 3ecau#e y*u can place the +eth*d in the #peci9ic cla## G=ind in thi# ca#eH, !here it# appr*priate) H*!ever, a +*re appr*priate #*luti*n i# t* put a prepareBnstrument( ) +eth*d in the 3a#e cla##, 3ut y*u +ight n*t #ee thi# !hen y*ure 9ir#t #*lving the pr*3le+ and c*uld +i#takenly a##u+e that y*u +u#t u#e RTT-) 5inally, RTT- !ill #*+eti+e# #*lve e99iciency pr*3le+#) -9 y*ur c*de nicely u#e# p*ly+*rphi#+, 3ut it turn# *ut that *ne *9 y*ur *34ect# react# t* thi# general purp*#e c*de in a h*rri3ly ine99icient !ay, y*u can pick *ut that type u#ing RTT- and !rite ca#eE#peci9ic c*de t* i+pr*ve the e99iciency) Be !ary, h*!ever, *9 pr*gra++ing 9*r e99iciency t** #**n) -t# a #eductive trap) -t# 3e#t t* get the pr*gra+ !*rking $irst, then decide i9 it# running 9a#t en*ugh, and *nly then #h*uld y*u attack e99iciency i##ue#R!ith a pr*9iler)

%&ercises
S*luti*n# t* #elected e;erci#e# can 3e 9*und in the electr*nic d*cu+ent The Thinking in ,a-a 5nnotated @olution Duide, availa3le 9*r a #+all 9ee 9r*+ www.BruceEckel.com)

1.

=dd *homboid t* #hapes6)ava) Create a *homboid, upca#t it t* a #hape, then d*!nca#t it 3ack t* a *homboid) Try d*!nca#ting t* a Circle and #ee !hat happen#) A*di9y E;erci#e 0 #* that it u#e# instanceof t* check the type 3e9*re per9*r+ing the d*!nca#t) A*di9y #hapes6)ava #* that it can IhighlightJ G#et a 9lagH in all #hape# *9 a particular type) The to#tring( ) +eth*d 9*r each derived #hape #h*uld indicate !hether that #hape i# Ihighlighted)J A*di9y #weet#hop6)ava #* that each type *9 *34ect creati*n i# c*ntr*lled 3y a c*++andEline argu+ent) That i#, i9 y*ur c*++and line i# I)ava #weet#hop Candy,J then *nly the Candy *34ect i# created) *tice h*! y*u can c*ntr*l !hich Class *34ect# are l*aded via the c*++andEline argu+ent) =dd a ne! type *9 !et t* !etCount96)ava) Ceri9y that it i# created and c*unted c*rrectly in main( ))

2. 3.

!.

Cha"ter 1)* ?un time T4"e Identi$ication

5&'

". C. D. E. 1F.

,rite a +eth*d that take# an *34ect and recur#ively print# all the cla##e# in that *34ect# hierarchy) A*di9y E;erci#e . #* that it u#e# Class6get$eclared:ields( ) t* al#* di#play in9*r+ati*n a3*ut the 9ield# in a cla##) -n +oy+est6)ava, c*++ent *ut +oy# de9ault c*n#truct*r and e;plain !hat happen#) -nc*rp*rate a ne! kind *9 interface int* +oy+est6)ava and veri9y that it i# detected and di#played pr*perly) Create a ne! type *9 c*ntainer that u#e# a private 'rrayList t* h*ld the *34ect#) Capture the type *9 the 9ir#t *34ect y*u put in it, and then all*! the u#er t* in#ert *34ect# *9 *nly that type 9r*+ then *n) ,rite a pr*gra+ t* deter+ine !hether an array *9 char i# a pri+itive type *r a true *34ect) -+ple+ent clear#pitHalve( ) a# de#cri3ed in the #u++ary) -+ple+ent the rotate(#hape) +eth*d de#cri3ed in thi# chapter, #uch that it check# t* #ee i9 it i# r*tating a Circle Gand, i9 #*, d*e#nt per9*r+ the *perati*nH) -n +oy+est6)ava, u#e re9lecti*n t* create a +oy *34ect u#ing the n*nde9ault c*n#truct*r) L**k up the inter9ace 9*r )ava6lang6Class in the HTAL "ava d*cu+entati*n 9r*+ 3a-a.sun.com) ,rite a pr*gra+ that take# the na+e *9 a cla## a# a c*++andEline argu+ent, then u#e# the Class +eth*d# t* du+p all the in9*r+ati*n availa3le 9*r that cla##) Te#t y*ur pr*gra+ !ith a #tandard li3rary cla## and a cla## y*u create)

11. 12. 13.

1 . 1!.

5'(

Thinking in C

www.ThinkingIn.!et

13, Progra##ing Windows 7or#s


= 9unda+ental de#ign guideline i# I+ake #i+ple thing# ea#y, and di99icult thing# p*##i3le)J
0

There have 3een t!* antag*ni#tic 9*rce# at !*rk in the ,ind*!# >U- pr*gra++ing !*rld P the ea#e *9 u#e epit*+i7ed 3y Ci#ual Ba#ic and the c*ntr*l availa3le t* C pr*gra++er# u#ing the ,in/2 =P-) Rec*nciling the#e 9*rce# i# *ne *9 the great achieve+ent# *9 the ) ET 5ra+e!*rk) Ci#ual Studi* ) ET pr*vide# a CBElike t**l#et 9*r dra!ing 9*r+#, draggingEandEdr*pping !idget# *nt* the+, and rapidly #peci9ying their pr*pertie#, event, and re#p*n#e#) H*!ever, thi# ea#yEt*Eu#e t**l #it# *n t*p *9 ,ind*!# 5*r+# and >?-@, #y#te+# !h*#e *34ectE
0 = variati*n *n thi# i# called Ithe principle *9 lea#t a#t*ni#h+ent,J !hich e##entially #ay#1

Id*nt #urpri#e the u#er)J

5'1

*riented de#ign, c*n#i#tency, and 9le;i3ility are un#urpa##ed 9*r creating rich client inter9ace#)
The ai+ *9 thi# chapter i# t* give a g**d under#tanding *9 the underlying c*ncept# at play in i+ple+enting graphical u#er inter9ace# and t* c*uple th*#e c*ncept# !ith c*ncrete detail# *n the +*#t c*++*nlyEu#ed !idget#) 5*r "ava pr*gra++er#, the ea#e !ith !hich rich, highly re#p*n#ive inter9ace# and cu#t*+ c*+p*nent# can 3e created in C# !ill c*+e a# a revelati*n) "ava# U- +*del# have 3een 3a#ed *n the pre+i#e that *perating #y#te+ integrati*n i# #uper9lu*u# t* the ta#k *9 creating pr*gra+ inter9ace#) Thi# i# a3#urd, i9 9*r n* *ther rea#*n than it# vi*lati*n *9

4elegates
One *9 C## +*#t intere#ting language 9eature# i# it# #upp*rt 9*r delegates, an *34ectE*riented, +eth*d type) The line1 de egate #tring Hoo0int para!13 i# a t4"e declaration 4u#t a# i#1 c a## Bar; < =nd 4u#t a# t* 3e u#e9ul a cla## type ha# t* 3e in#tantiated Gunle## it 4u#t ha# static data and +eth*d#H, #* t** +u#t delegate type# 3e in#tantiated t* 3e *9 any u#e) = delegate can 3e in#tantiated !ith any +eth*d that

5')

+atche# the delegate# type #ignature) Once in#tantiated, the delegate re9erence can 3e u#ed directly a# a +eth*d) ?elegate# are *34ectE*riented in that they can 3e 3*und n*t 4u#t t* #tatic +eth*d#, 3ut t* in#tance +eth*d#Q in d*ing #*, a delegate !ill e;ecute the #peci9ied +eth*d *n the de#ignated *34ect) = #i+ple e;a+ple !ill #h*! the 3a#ic 9eature# *9 delegate#1 //:c"T:-rofe##ion.c# //:ec aration and in#tantiation of de egate# de egate *oid -rofe##ion013 c a## -rofe##ionSpea%er; #tatic *oid StaticSpea%er01; Sy#te!.Con#o e.VriteLine0&Gedicine&13 < #tatic int doctor5dCounter 9 03 int doctor5d 9 doctor5dCounterRR3 *oid 5n#tanceSpea%er01; Sy#te!.Con#o e.VriteLine0&:octor & R doctor5d13 < int :ifferentSignature01; Sy#te!.Con#o e.VriteLine0&Hirefighter&13 return 03 < pu$ ic #tatic *oid Gain01; //dec are de egate reference 099 nu 1 -rofe##ion p3 //in#tantiate de egate reference p 9 ne. -rofe##ion0 -rofe##ionSpea%er.StaticSpea%er13 p013 -rofe##ionSpea%er #" 9 ne. -rofe##ionSpea%er013 -rofe##ionSpea%er #2 9 ne. -rofe##ionSpea%er013

Cha"ter 13* Creating Gindows = 5""lets

5'3

//&in#tantiate& to #pecific in#tance# -rofe##ion p" 9 ne. -rofe##ion0 #".5n#tanceSpea%er13 -rofe##ion p2 9 ne. -rofe##ion0 #2.5n#tanceSpea%er13 p"013 p2013 //Von't co!pi e2 different #ignature //-rofe##ion pT 9 ne. -rofe##ion0 // #2.:ifferentSignature13 < <///:8 The !rofession delegate type i# declared t* take n* para+eter# and t* return void) The !rofession#pea(er ha# t!* +eth*d# !ith thi# #ignature1 a static #tatic#pea(er() +eth*d and an in#tance +eth*d called Bnstance#pea(er()) !rofession#pea(er ha# a #tatic doctorBdCounter !hich i# incre+ented every ti+e a ne! !rofession#pea(er i# in#tantiatedQ thu# Bnstance#pea(er() ha# di99erent *utput 9*r each !rofession#pea(er in#tance) !rofession#pea(er6.ain() declare# a delegate re9erence !rofession p) Like all declared 3ut n*t initiali7ed varia3le#, p i# null at thi# p*int) The ne;t line i# the delegate# Ic*n#truct*rJ and i# *9 the 9*r+1 ne. :e egate'ypeCa!e0 Ca!eOfGethod'o:e egate 13 Thi# 9ir#t delegate i# in#tantiated !ith the #tatic#pea(er() +eth*d Gn*te that the value pa##ed t* the delegate Ic*n#truct*rJ i# 4u#t the name *9 the +eth*d !ith*ut the parenthe#e# that !*uld #peci9y an actual +eth*d callH) Once the delegate i# initiali7ed, the re9erence -aria2le act# a# i9 it !a# an inE#c*pe +eth*d name) S* the line p() re#ult# in a call t* !rofession#pea(er6#tatic#pea(er()) .ain() then in#tantiate# t!* ne! !rofession#pea(er#Q *ne *9 !hich !ill have a doctorBd *9 $ and the *ther *9 0) ,e declare t!* ne! !rofession delegate#, 3ut thi# ti+e u#e a #light di99erent 9*r+1

5'4

Thinking in C

www.ThinkingIn.!et

ne. :e egate'ypeCa!e0 o$DectReference.GethodCa!e 13 :*u can think *9 thi# a# pa##ing Ithe in#tance *9 the +eth*dJ a##*ciated !ith the ob)ect*eference, even th*ugh Ithat# n*t h*! it really i#J in +e+*ry Gthere# a c*py *9 each piece *9 data 9*r an in#tance, 3ut methods are n*t duplicatedH) The t!* delegate# p7 and p8 can n*! 3e u#ed a# pr*;ie# 9*r the +eth*d# s76Bnstance#pea(er() and s86Bnstance#pea(er()) The delegatedEt* +eth*d +u#t have the e;act para+eter# and return t4"e *9 the delegate type declarati*n) Thu#, !e cant u#e $ifferent#ignature() G!hich return# an intH t* in#tantiate a !rofession delegate) ,hen run, the call# t* the delegate# p, p7, and p8 re#ult in thi# *utput1 Gedicine :octor 0 :octor "

4esigning With 4elegates


?elegate# are u#ed e;ten#ively in ,ind*!# 5*r+#, ) ET# *34ectE*riented 9ra+e!*rk 9*r >U- pr*gra++ing) H*!ever, they can 3e e99ectively u#ed in any #ituati*n !here varia3le# in 3ehavi*r are +*re i+p*rtant than varia3le# in #tate) ,eve already talked a3*ut the Strategy pattern G#re9#H1

Cha"ter 13* Creating Gindows = 5""lets

5'5

?elegate# pr*vide an alternate de#ign1

The Strategy pattern e;plicitly 3ind# the i+ple+entati*n t* it# u#e #ati#9ying the c*ntract *9 the inter9ace B#trategyQ any cla## !hich !ill 3e u#ed a# a #trategy +u#t declare it#el9 a# D B#trategy and i+ple+ent the +eth*d void #trategy()) ,ith delegate#, there i# n* e;plicit 3inding *9 the handler t* the delegate typeQ a ne! pr*gra++er c*+ing t* the #ituati*n !*uldnt nece##arily kn*! that 'nyClass6#trat"andler() !a# 3eing u#ed t* in#tantiate a #trategy delegate) Thi# +ight lead t* tr*u3le1 the ne! pr*gra++er c*uld change the 3ehavi*r *9 #trat"andler() in a !ay inappr*priate t* it# u#e a# a #trategy delegate and the change !*uld n*t 3e caught 3y either the c*+piler *r 3y 'nyClass# unit te#t#Q the pr*3le+ !*uldnt appear until Client# unit te#t# !ere run)

5'6

Thinking in C

www.ThinkingIn.!et

On the *ther hand, the delegate +*del i# #igni9icantly le## typing and can delegate handling t* a +eth*d in a type 9*r !hich y*u d*nt have #*urce c*de Galth*ugh there# n* *3vi*u# #cenari* that !*uld call 9*r thatH) .1*& "&*&

@ulticast 4elegates
?elegate# that return type v*id +ay de#ignate a series *9 +eth*d# that !ill 3e inv*ked !hen the delegate i# called) Such delegate# are called multicast delegates) Aeth*d# can 3e added and re+*ve 9r*+ the call chain 3y u#ing the *verl*aded @X and EX *perat*r#) Here# an e;a+ple1 //:c"T:Gu tica#t.c# //:e!on#trate# !u tica#t de egate# c a## Roo#ter; interna *oid Cro.01; Sy#te!.Con#o e.VriteLine0&Coc%6a6dood e6doo&13 < < c a## -aperBoy; interna *oid :e i*er-aper#01; Sy#te!.Con#o e.VriteLine0&'hro. paper on roof&13 < < c a## Sun; interna *oid Ri#e01; Sy#te!.Con#o e.VriteLine0&Spread ro#y finger#&13 < < c a## :a.nRoutine; de egate *oid :a.nBeha*ior013 :a.nBeha*ior !u tica#t3 :a.nRoutine01;

Cha"ter 13* Creating Gindows = 5""lets

5'#

!u tica#t 9 ne. :a.nBeha*ior0 ne. Roo#ter01.Cro.13 !u tica#t R9 ne. :a.nBeha*ior0 ne. -aperBoy01.:e i*er-aper#13 !u tica#t R9 ne. :a.nBeha*ior0 ne. Sun01.Ri#e13 < *oid Brea%01; !u tica#t013 < pu$ ic #tatic *oid Gain01; :a.nRoutine dr 9 ne. :a.nRoutine013 dr.Brea%013 < <///:8 =9ter declaring three cla##e# G*ooster, !aperBoy, and #unH that have +eth*d# a##*ciated !ith the da!n, !e declare a $awn*outine cla## and, !ithin it# #c*pe, declare a $awnBehavior delegate type and an in#tance varia3le multicast t* h*ld the in#tance *9 the delegate) The $awn*outine() c*n#truct*r# 9ir#t line in#tantiate# the delegate t* the Crow() +eth*d *9 a *ooster *34ect Gthe gar3age c*llect*r i# #+art en*ugh t* kn*! that alth*ugh !ere u#ing an anon4mous in#tance *9 *ooster, the in#tance !ill n*t 3e c*llected a# l*ng a# the delegate c*ntinue# t* h*ld a re9erence t* itH) e! in#tance# *9 $awnBehavior are in#tantiated !ith re9erence# t* Iin#tance#J *9 !aperBoy6$eliver!apers() and #un6*ise()) The#e ?a!nBehavi*r delegate# are added t* the multicast delegate !ith the @X *perat*r) Brea(() inv*ke# multicast() *nce, 3ut that #ingle call in turn i# multicast t* all the delegate#1 Coc%6a6dood e6doo 'hro. paper on roof Spread ro#y finger# Aultica#t delegate# are u#ed thr*ugh*ut ,ind*!# 5*r+# t* create eventE handling chain#, each *9 !hich i# re#p*n#i3le 9*r a particular a#pect *9 the t*tal de#ired 3ehavi*r Gperhap# di#playE*riented, perhap# l*gical, perhap# #*+ething that !rite# t* a l*g9ileH)

5'&

Thinking in C

www.ThinkingIn.!et

Aultica#t delegate# are #i+ilar t* the Chain o$ ?es"onsi2ilit4 de#ign pattern1

The *ne di99erence i# that the Chain o$ ?es"onsi2ilit4 i# u#ually i+ple+ented #* that an individual handler can decide t* end the pr*ce##ing chain Gthat i#, a handler +ay decide n*t t* call it# successor# "andle*e%uest() +eth*dH) -t i# n*t p*##i3le 9*r a delegatedEt* +eth*d t* have thi# #*+eti+e#Ede#ired *pti*n, #* there +ay 3e ti+e# !hen y*u i+ple+ent a Chain o$ ?es"onsi2ilit4 !ithin an inter9ace *n !hich y*u create #ingle *r +ultica#t delegate#1 //:c"T::e egatedChainOfRe#pon#i$i ity.c# //Sho.# po y!orphic de egation2 p u# CoR pattern u#ing Sy#te!3 interface Uand er; *oid Uand eRe7ue#t013 < c a## ConcreteUand er" : Uand er; Rando! r 9 ne. Rando!013 Uand er #ucce##or 9 ne. ConcreteUand er2013 pu$ ic *oid Uand eRe7ue#t01 ; if0r.Cext:ou$ e01 Z 0.P1; Sy#te!.Con#o e.VriteLine0 &CU": Uand ing inco!p ete&13 #ucce##or.Uand eRe7ue#t013 <e #e; Sy#te!.Con#o e.VriteLine0

Cha"ter 13* Creating Gindows = 5""lets

5''

&CU": Uand ing co!p ete&13 < < < c a## ConcreteUand er2 : Uand er; pu$ ic *oid Uand eRe7ue#t01 ; Sy#te!.Con#o e.VriteLine0&U2 hand ing&13 < < c a## C ient; de egate *oid -o y:e 013 pri*ate #tatic *oid ) #oUand er01; Sy#te!.Con#o e.VriteLine0&) #oUand er&13 < pu$ ic #tatic *oid Gain01; //Cote upca#t Uand er h 9 ne. ConcreteUand er"013 -o y:e de 9 ne. -o y:e 0h.Uand eRe7ue#t13 de R9 ne. -o y:e 0) #oUand er13 de 013 < < The "andler inter9ace and it# t!* #u3type# i+ple+ent the Chain o$ ?es"onsi2ilit4 pattern) Concrete"andler7 I9lip# a c*inJ in the 9*r+ *9 a rand*+ nu+3er and either call# successor6"andle*e%uest() *r n*t) The !oly$el delegate declared !ithin Client +atche# the inter9ace in "andler, #* !hen a ne! "andler i# in#tantiated in Client6.ain(), there i# n* pr*3le+ in u#ing that handle# "andle*e%uest +eth*d a# the argu+ent t* a ne! !oly$el delegate) Since delegate# are *34ectE *riented, there i# n* pr*3le+ u#ing a handle that# 3een upca#t t* an a3#tract data type in the c*n#tructi*n *9 a delegate) ,hen del() i# inv*ked, hal9 the ti+e the Concrete"andler7 !ill 9*r!ard a call t* it# Concrete"andler8 successor and hal9 the ti+e n*t) Becau#e !oly$el i# a +ultica#t handler, th*ugh, 'lso"andler() !ill al!ay# 3e called)

6((

Thinking in C

www.ThinkingIn.!et

%vents
The 3ehavi*r *9 a +ultica#t delegate can 3e interpreted a# a #ingle event Gthe +ultica#t +eth*d callH cau#ing +ultiple 3ehavi*r# Gthe call# *n the vari*u# delegatedEt* +eth*d#H) H*!ever, !ith a n*r+al delegate, the delegatedEt* +eth*d ha# n* !ay *9 kn*!ing anything a3*ut the c*nte;t in !hich it !a# inv*ked) -n *ur .ulticast e;a+ple, the #un6*ise() +eth*d G#ayH c*uld n*t have a99ected any change in the $awn*outine *34ect that inv*ked it) By c*nventi*n, +ultica#t delegate# that reDuire c*nte;t #h*uld 3e *9 type1 de egate *oid :e egateCa!e0 o$Dect #ource2 +*ent)rg#Su$type x13 The &vent'rgs cla## i# de9ined in the #ystem na+e#pace and, 3y de9ault, c*ntain# n*thing 3ut a #tatic read*nly pr*perty &mpty that i# de9ined a# returning an &vent'rg eDuivalent t* an &vent'rg created !ith a n*Earg# c*n#truct*r Gin *ther !*rd#, a generic, undi#tingui#ha3le, and there9*re IE+ptyJ argu+entH) Su3type# *9 &vent'rgs are e;pected t* de9ine and e;p*#e pr*pertie# that are the +*#t likely i+p*rtant piece# *9 c*nte;t) 5*r in#tance, the $awnBehavior delegate +ight 3e paired !ith a $awn&vent'rgs *34ect that c*ntained the !eather and ti+e *9 #unri#e) -9 a cla## !i#he# t* de9ine a +ultica#t delegate *9 thi# #*rt and e;p*#e it pu3licly a# a pr*perty, the n*r+al C# #ynta; !*uld 3e1 *oid :a.n:e egate0o$Dect #ource2 :a.n+*ent)rg# dea13 c a## :a.n+*ent)rg# : +*ent)rg#;< c a## :a.nBeha*ior; pri*ate :a.n:e egate d3 pu$ ic :a.n:e egate :a.n+*ent; get ; return d3 < #et ; d 9 *a ue3 < < < = #h*rtcut i# t* #i+ply declare an e-ent "ro"ert41 pu$ ic e*ent :a.n:e egate :a.n+*ent3

Cha"ter 13* Creating Gindows = 5""lets

6(1

:*u #till have t* de9ine the delegate and the #u3type *9 $awn&vent'rgs and there i# n* di99erence in 3ehavi*r 3et!een a pu3lic +ultica#t delegate e;p*#ed a# a n*r+al pr*perty and *ne e;p*#ed a# an event pr*perty) H*!ever, event pr*pertie# +ay 3e treated di99erently 3y devel*per t**l# #uch a# the d*cEc*++ent generat*r *r vi#ual 3uilder t**l# #uch a# the *ne in Ci#ual Studi*) ET) Thi# e;a+ple #h*!# event handler# that +*di9y their 3ehavi*r depending *n the c*nte;t1 //:c"T:+*ent-roperty.c# u#ing Sy#te!3 de egate *oid :a.n:e egate0 o$Dect #ource2 :a.n+*ent)rg# dea13 enu! Veather; #unny2 rainy <3 c a## :a.n+*ent)rg# : +*ent)rg#; //Uide $a#e c a## con#tructor pri*ate :a.n+*ent)rg#01 : $a#e01;< pu$ ic :a.n+*ent)rg#0Veather .1; thi#.. 9 .3 < pri*ate Veather .3 pu$ ic Veather GorningVeather; #et ; . 9 *a ue3 < get ; return .3 < < < c a## :a.nBeha*ior; pu$ ic e*ent :a.n:e egate :a.n+*ent3 pu$ ic #tatic *oid Gain01; :a.nBeha*ior d$ 9 ne. :a.nBeha*ior013 d$.:a.n+*ent 9 ne. :a.n:e egate0 ne. Roo#ter01.Cro.13 d$.:a.n+*ent R9 ne. :a.n:e egate0 ne. Sun01.Ri#e13

6()

Thinking in C

www.ThinkingIn.!et

:a.n+*ent)rg# dea 9 ne. :a.n+*ent)rg#0Veather.#unny13 d$.:a.n+*ent0typeof0:a.nBeha*ior12 dea13 dea 9 ne. :a.n+*ent)rg#0Veather.rainy13 d$.:a.n+*ent0typeof0:a.nBeha*ior12 dea13 < < c a## Roo#ter; interna *oid Cro.0o$Dect #rc2 :a.n+*ent)rg# dea1; if0dea.GorningVeather 99 Veather.#unny1; Sy#te!.Con#o e.VriteLine0 &Coc%6a6dood e6doo&13 <e #e; Sy#te!.Con#o e.VriteLine0&S eep in&13 < < < c a## Sun; interna *oid Ri#e0o$Dect #rc2 :a.n+*ent)rg# dea1; if0dea.GorningVeather 99 Veather.#unny1; Sy#te!.Con#o e.VriteLine0 &Spread ro#y finger#&13 <e #e; Sy#te!.Con#o e.VriteLine0 &Ca#t a grey pa &13 < < < -n thi# e;a+ple, the $awn&vent i# created in the #tatic .ain() +eth*d, #* !e c*uldnt #end this a# the #*urce n*r d*e# pa##ing in the db in#tance #ee+ appr*priate) ,e c*uld pa## null a# the #*urce, 3ut pa##ing null i# generally a 3ad idea) Since the event i# created 3y a #tatic +eth*d and a #tatic +eth*d i# a##*ciated !ith the cla##, it #ee+# rea#*na3le t* #ay that the #*urce i# the type in9*r+ati*n *9 the cla##, !hich i# retrieved 3y typeof($awnBehavior))

Cha"ter 13* Creating Gindows = 5""lets

6(3

6ecursive -ra$s
C*nceptually, eventEdriven pr*gra+# are a#ynchr*n*u# P !hen an event i# I9iredJ G*r Irai#edJ *r I#entJH, c*ntr*l return# t* the 9iring +eth*d and, #*+eti+e in the 9uture, the event handler get# called) -n reality, C## event# are #ynchr*n*u#, +eaning that c*ntr*l d*e# n*t return t* the 9iring +eth*d until the event handler ha# c*+pleted) Thi# c*nceptual gap can lead t* #eri*u# pr*3le+#) -9 the event handler *9 event H it#el9 rai#e# event#, and the handling *9 the#e event# re#ult# in a ne! event H, the #y#te+ !ill recur#e, eventually either cau#ing a #tack *ver9l*! e;cepti*n *r e;hau#ting #*+e n*nE+e+*ry re#*urce) -n thi# e;a+ple, a utility c*+pany #end# 3ill# *ut, a h*+e*!ner pay# the+, !hich trigger# a ne! 3ill) 5r*+ a c*nceptual #tandp*int, thi# #h*uld 3e 9ine, 3ecau#e the pay+ent and the ne! 3ill are #eparate event#) //:c"T:Recur#i*e+*ent#.c# //:e!on#trate# danger in C( e*ent !ode u#ing Sy#te!3 de egate *oid -ay!ent+*ent0o$Dect #rc2 Bi c a## Bi )rg#; interna Bi )rg#0dou$ e c1; co#t 9 c3 < pu$ ic dou$ e co#t3 < a$#tract c a## Boo%%eeper; pu$ ic e*ent -ay!ent+*ent 5n$ox3 pu$ ic #tatic *oid Gain01; Boo%%eeper ho 9 ne. Uo!eo.ner013 Oti ityCo uc 9 ne. Oti ityCo013 uc.BeginBi < interna *oid -o#t0o$Dect #rc2 dou$ e c1; 5n$ox0#rc2 ne. Bi )rg#0c113 ing0ho13 )rg# ea13

6(4

Thinking in C

www.ThinkingIn.!et

< < c a## Oti ityCo : Boo%%eeper; interna Oti ityCo01; 5n$ox R9 ne. -ay!ent+*ent0thi#.Recei*e-!t13 < interna *oid BeginBi ing0Boo%%eeper $%1; $%.-o#t0thi#2 E.013 < pu$ ic *oid Recei*e-!t0o$Dect #rc2 Bi )rg# ea1; Boo%%eeper #ender 9 #rc a# Boo%%eeper3 Sy#te!.Con#o e.VriteLine0&Recei*ed p!t fro! & R #ender13 #ender.-o#t0thi#2 "0.013 < < c a## Uo!eo.ner : Boo%%eeper; interna Uo!eo.ner01; 5n$ox R9 ne. -ay!ent+*ent0Recei*eBi 13 < pu$ ic *oid Recei*eBi 0o$Dect #rc2 Bi )rg# ea1; Boo%%eeper #ender 9 #rc a# Boo%%eeper3 Sy#te!.Con#o e.VriteLine0&Vriting chec% to & R #ender R & for & R ea.co#t13 #ender.-o#t0thi#2 ea.co#t13 < < 5ir#t, !e declare a delegate type called !ayment&vent !hich take# a# an argu+ent a Bill'rgs re9erence c*ntaining the a+*unt *9 the 3ill *r pay+ent) ,e then create an a3#tract Boo((eeper cla## !ith a !ayment&vent event called Bnbox) The .ain() 9*r the #a+ple create# a "ome1wner, a VtilityCo, and pa##e# the re9erence t* the "ome1wner t* the VtilityCo t* 3egin 3illing) Boo((eeper then

Cha"ter 13* Creating Gindows = 5""lets

6(5

de9ine# a +eth*d called !ost() !hich trigger# the !ayment&vent( )F !ell e;plain the rati*nale 9*r thi# +eth*d in a little 3it) VtilityCo6BeginBilling() take# a Boo((eeper Gthe h*+e*!nerH a# an argu+ent) -t call# that Boo((eeper# !ost( ) +eth*d, !hich in turn !ill call that Boo((eeper# Bnbox delegate) -n the ca#e *9 the "omeowner, that !ill activate the *eceiveBill( ) +eth*d) The h*+e*!ner I!rite# a checkJ and !ost( )# it t* the #*urce) -9 event# !ere a#ynchr*n*u#, thi# !*uld n*t 3e a pr*3le+) H*!ever, !hen run, thi# !ill run a# e;pected 9*r #everal hundred iterati*n#, 3ut then !ill cra#h !ith a #tack *ver9l*! e;cepti*n) either *9 the event handler# G*eceiveBill( ) and *eceive!ayment( ) H ever return#, they 4u#t recur#ively call each *ther in !hat !*uld 3e an in9inite l**p 3ut 9*r the 9inite #tack) A*re #u3tle recur#ive l**p# are a challenge !hen !riting eventEdriven c*de in C#) Perhap# in *rder t* di#c*urage 4u#t the#e type# *9 pr*3le+#, event pr*pertie# di99er 9r*+ delegate# in *ne very i+p*rtant !ay1 an event can *nly 3e inv*ked 3y the very cla## in !hich it i# declaredQ even de#cendant type# cann*t directly inv*ke an event) Thi# i# !hy !e needed t* !rite the !ost( ) +eth*d in Boo((eeper, "ome1wner and VtilityCo cann*t e;ecute Bnbox( ), atte+pting t* d* #* re#ult# in a c*+pilati*n err*r) Thi# language re#tricti*n i# a #yntactical !ay *9 #aying Irai#ing an event i# a 3ig deal and +u#t 3e d*ne !ith care)J EventEdriven de#ign# +ay reDuire +ultiple thread# in *rder t* av*id recur#ive l**p# G+*re *n thi# in chapter #threading#H) Or they +ay n*t) Thi# re#tricti*n *n event# d*e# n*t 9*rce y*u int* any particular de#ign deci#i*n# P a# !e #h*!ed in thi# e;a+ple, *ne can #i+ply create a pu3lic pr*;y +eth*d t* inv*ke the event)

-he Genesis o0 Windows 7or#s


,hile C# event# are n*t a#ynchr*n*u#, IrealJ ,ind*!# event# are) Behind the #cene#, ,ind*!# pr*gra+# have an event l**p that receive# un#igned integer# c*rre#p*nding t* #uch thing# a# +*u#e +*ve+ent# and click# and keypre##e#, and then #ay I-9 that nu+3er i# %, call 9uncti*n 4)J

6(6

Thinking in C

www.ThinkingIn.!et

Thi# !a# #tateE*9EtheEart #tu99 in the +idE06($# 3e9*re *34ectE*rientati*n 3eca+e p*pular) -n the early 066$#, pr*duct# #uch a# =ct*r, SML ,ind*!#, Ci#ual Ba#ic, and A5C 3egan hiding thi# c*+ple;ity 3ehind a variety *9 di99erent +*del#, *9ten trading *99 *34ectE*riented IpurityJ 9*r ea#e *9 devel*p+ent *r per9*r+ance *9 the re#ulting applicati*n) =lth*ugh pr*gra++ing li3rarie# 9r*+ c*+panie# *ther than Aicr*#*9t !ere #*+eti+e# #uperi*r, Aicr*#*9t# li3rarie# al!ay# had the edge in #h*!ca#ing ,ind*!# late#t capa3ilitie#) Aicr*#*9t parlayed that int* increa#ing +arket #hare in the devel*p+ent t**l# categ*ry, at lea#t until the e;pl*#i*n *9 the ,*rld ,ide ,e3 in the +idE066$#, !hen the thenE current !i#d*+ a3*ut u#er inter9ace# G#u++ary1 IU-# +u#t c*n#i#tently 9*ll*! plat9*r+ #tandard#, and U-# +u#t 3e 9a#tJH !a# le9t 3y the !ay#ide 9*r the ne! i+perative GI=ll applicati*n# +u#t run in#ide 3r*!#er#JH) One *9 the pr*gra++ing t**l# that had di99iculty gaining +arket#hare again#t Aicr*#*9t !a# B*rland# ?elphi, !hich c*+3ined a #ynta; derived 9r*+ Tur3* Pa#cal, a graphical 3uilder a la Ci#ual Ba#ic, and an *34ectE *riented 9ra+e!*rk 9*r 3uilding U-#) ?elphi !a# the 3rainchild *9 =nder# He4l#3erg, !h* #u3#eDuently le9t B*rland 9*r Aicr*#*9t, !here he devel*ped the predece##*r *9 ) ET# ,ind*!# 5*r+# li3rary 9*r Ci#ual "@ @) He4l#3erg !a# the chie9 de#igner *9 the C# language and C## delegate# trace their ance#try t* ?elphi) G-ncidentally, ?elphi re+ain# a great pr*duct and i# n*!, ir*nically, the 3e#t t**l 9*r pr*gra++ing native Linu; applicati*n#KH S* ,ind*!# 5*r+# i# an *34ectE*riented !rapper *9 the underlying ,ind*!# applicati*n) The d*u3ling and red*u3ling *9 pr*ce##*r #peed thr*ugh*ut the 066$# ha# +ade any per9*r+ance hit a##*ciated !ith thi# type *9 a3#tracti*n irrelevantQ ,ind*!# 5*r+# applicati*n# tran#late the ra! ,ind*!# event# int* call# t* +ultica#t delegate# Gi)e), event#H #* e99iciently that +*#t pr*gra++er# !ill never have a need t* #ideE#tep the li3rary)

Creating a 7or#
,ith ,ind*!# 5*r+#, the #tatic AainGH +eth*d call# the #tatic +eth*d =pplicati*n)RunGH, pa##ing t* it a re9erence t* a #u3type *9 :orm) =ll the 3ehavi*r a##*ciated !ith creating, di#playing, cl*#ing and *ther!i#e

Cha"ter 13* Creating Gindows = 5""lets

6(#

+anipulating a ,ind*! Gincluding repainting, a 9inicky p*int *9 the Ira!J ,ind*!# =P-H i# in the 3a#e type :orm and need n*t 3e *9 c*ncern t* the pr*gra++er) Here# a 9ully 9uncti*nal ,ind*!# 5*r+ pr*gra+1 //:c"T:Hir#tHor!.c# u#ing Sy#te!.Vindo.#.Hor!#3 c a## Hir#tHor! : Hor!; pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Hir#tHor!0113 < <///:8 that !hen run pr*duce# thi# !ind*!1

The 3a#e cla## :orm c*ntain# +*re than 0$$ pu3lic and pr*tected pr*pertie#, a #i+ilar nu+3er *9 +eth*d#, and +*re than %$ event# and c*rre#p*nding eventErai#ing +eth*d#) But it d*e#nt #t*p thereQ :orm i# a #u3type *9 a cla## called Control Gn*t a direct #u3type, it# actually :orm 1 ContainerControl 1 #crollableControl 1 ControlH) -n#tance# *9 Control have a pr*perty called Controls !hich c*ntain# a c*llecti*n *9 *ther c*ntr*l#) Thi# #tructure, an e;a+ple *9 the Com"osite de#ign pattern, all*!# everything 9r*+ #i+ple 3utt*n# t* the +*#t c*+ple; u#erE

6(&

Thinking in C

www.ThinkingIn.!et

inter9ace# t* 3e treated uni9*r+ly 3y pr*gra++er# and devel*p+ent t**l# #uch a# the vi#ual 3uilder t**l in Ci#ual Studi* ) ET)

G>I )rchitectures
=rchitecture# !ere pre#ented in chapter #architectur# a# an I*verall *rdering principleJ *9 a #y#te+ *r #u3#y#te+) ,hile the Controls pr*perty *9 Control i# an *rdering principle 9*r the #tatic #tructure *9 the !idget# in a ,ind*!# 5*r+# applicati*n, ,ind*!# 5*r+# d*e# n*t dictate an *rdering principle 9*r a##*ciating the#e !idget# !ith particular event# and pr*gra+ l*gic) Several architecture# are p*##i3le !ith ,ind*!# 5*r+#, and each ha# it# #trength# and !eakne##e#) -t# i+p*rtant t* have a c*n#i#tent U- architecture 3ecau#e, a# Larry C*n#tantine and Lucy L*ck!**d p*int *ut, !hile the U- i# 4u#t *ne, perhap# unintere#ting, part *9 the #y#te+ t* the pr*gra++er, t* the end u#er, the U- is the pr*gra+) The U- i# the entry p*int 9*r the va#t +a4*rity *9 change reDue#t#, #* y*ud 3etter +ake it ea#y t* change the U- !ith*ut changing the l*gical 3ehavi*r *9 the pr*gra+) ?ec*upling the pre#entati*n layer 9r*+ the 3u#ine## layer i# a 9unda+ental part *9 pr*9e##i*nal devel*p+ent)

>sing the 8isual 4esigner


Open Ci#ual Studi* ) ET, 3ring up the e! Pr*4ect !i7ard, and create a ,ind*!# =pplicati*n called 5*r+C*ntr*lEvent) The !i7ard !ill generate #*+e #*urce c*de and pre#ent a I?e#ign Cie!J pre#entati*n *9 a 3lank 9*r+) ?rag and dr*p a 3utt*n and la3el *nt* the 9*r+) :*u #h*uld #ee #*+ething like thi#1

Cha"ter 13* Creating Gindows = 5""lets

6('

-n the de#igner, d*u3leEclick the 3utt*n) Ci#ual Studi* !ill #!itch t* a c*deEediting vie!, !ith the cur#*r in#ide a +eth*d called button7AClic(()) =dd the lineQ a$e ".'ext 9 &C ic%ed&3 The re#ulting pr*gra+ #h*uld l**k a l*t like thi#1 //:c"T:Hor!Contro +*ent.c# //:e#igner6generated Hor!6Contro 6+*ent architecture u#ing Sy#te!3

61(

Thinking in C

www.ThinkingIn.!et

u#ing u#ing u#ing u#ing u#ing

Sy#te!.:ra.ing3 Sy#te!.Co ection#3 Sy#te!.Co!ponentGode 3 Sy#te!.Vindo.#.Hor!#3 Sy#te!.:ata3

na!e#pace Hor!Contro +*ent; /// W#u!!aryZ /// Su!!ary de#cription for Hor!". /// W/#u!!aryZ pu$ ic c a## Hor!" : Sy#te!.Vindo.#.Hor!#.Hor! ; pri*ate Sy#te!.Vindo.#.Hor!#.La$e a$e "3 pri*ate Sy#te!.Vindo.#.Hor!#.Button $utton"3 /// W#u!!aryZ /// Re7uired de#igner *aria$ e. /// W/#u!!aryZ pri*ate Sy#te!.Co!ponentGode .Container co!ponent# 9 nu 3 pu$ ic Hor!"01; // // Re7uired for Vindo.# Hor! :e#igner #upport // 5nitia iMeCo!ponent013 // // 'O:O: )dd any con#tructor code after // 5nitia iMeCo!ponent ca // < /// W#u!!aryZ /// C ean up any re#ource# $eing u#ed. /// W/#u!!aryZ protected o*erride *oid :i#po#e0 $oo di#po#ing 1; if 0 di#po#ing 1 ; if 0co!ponent# !9 nu 1 ; co!ponent#.:i#po#e013 < <

Cha"ter 13* Creating Gindows = 5""lets

611

$a#e.:i#po#e0 di#po#ing 13 < (region Vindo.# Hor! :e#igner generated code /// W#u!!aryZ /// Re7uired !ethod for :e#igner #upport /// 6 do not !odify the content# of thi# !ethod /// .ith the code editor. /// W/#u!!aryZ pri*ate *oid 5nitia iMeCo!ponent01; thi#. a$e " 9 ne. Sy#te!.Vindo.#.Hor!#.La$e 013 thi#.$utton" 9 ne. Sy#te!.Vindo.#.Hor!#.Button013 thi#.Su#pendLayout013 // // a$e " // thi#. a$e ".Location 9 ne. Sy#te!.:ra.ing.-oint0"T?2 2E13 thi#. a$e ".Ca!e 9 & a$e "&3 thi#. a$e ".SiMe 9 ne. Sy#te!.:ra.ing.SiMe0P?2 "?13 thi#. a$e ".'a$5ndex 9 03 thi#. a$e ".'ext 9 & a$e "&3 // // $utton" // thi#.$utton".Location 9 ne. Sy#te!.:ra.ing.-oint0T22 2E13 thi#.$utton".Ca!e 9 &$utton"&3 thi#.$utton".'a$5ndex 9 "3 thi#.$utton".'ext 9 &$utton"&3 thi#.$utton".C ic% R9 ne. Sy#te!.+*entUand er0thi#.$utton"XC ic%13 // // Hor!" // thi#.)utoSca eBa#eSiMe 9 ne. Sy#te!.:ra.ing.SiMe0P2 "T13 thi#.C ientSiMe 9

61)

Thinking in C

www.ThinkingIn.!et

ne. Sy#te!.:ra.ing.SiMe02>22 2??13 thi#.Contro #.)ddRange0 ne. Sy#te!.Vindo.#.Hor!#.Contro JK; thi#.$utton"2 thi#. a$e "<13 thi#.Ca!e 9 &Hor!"&3 thi#.'ext 9 &Hor!"&3 thi#.Re#u!eLayout0fa #e13 < (endregion /// W#u!!aryZ /// 'he !ain entry point for the app ication. /// W/#u!!aryZ JS')'hreadK #tatic *oid Gain01 ; )pp ication.Run0ne. Hor!"0113 < pri*ate *oid $utton"XC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1 ; a$e ".'ext 9 &C ic%ed&3 < < < The 9ir#t intere#ting detail i# the Uregion E Uendregion #tate+ent#) The#e prepr*ce##ing directive# G#ee Chapter #prepr*ce##ing#H delineate a c*de #ecti*n that Ci#ual Studi* ) ET +ay c*llap#e in it# I*utliningJ +*deQ indeed, !hen y*u 9ir#t #!itch t* c*de vie!, thi# area *9 the c*de !a# pr*3a3ly #*+e!hat hidden 9r*+ vie!) ,hile it# generally a g**d idea t* heed the !arning a3*ut n*t editing ?e#ignerEgenerated c*de, the c*de i# !ell !*rth taking a cl*#er l**k at) The la3el and 3utt*n that !e dragged *nt* the 9*r+ are initiali7ed a# ne! *34ect# 9r*+ the Sy#te+),ind*!#)5*r+# na+e#pace) The call t* #uspendLayout() indicate# that a #erie# *9 +anipulati*n# are c*+ing and that each individual *ne #h*uld n*t trigger the p*tentially e;pen#ive lay*ut calculati*n *n the Control and all *9 it# #u3EControls) S*+e *9 the 3a#ic pr*pertie# 9*r each c*ntr*l are then #et1

Cha"ter 13* Creating Gindows = 5""lets

613

Location #peci9ie# the p*int !here the upperEle9t c*rner *9 the c*ntr*l i# relative t* the upperEle9t c*rner *9 the c*ntaining c*ntr*l *r, i9 the Control i# a :orm Location i# the #creen c**rdinate# *9 the upperEle9t c*rner Gincluding the :orm# 3*rder i9 it ha# *ne, a# +*#t d*H) Thi# i# a value that y*u can 9reely +anipulate !ith*ut !*rrying a3*ut the #iTe i# +ea#ured in pi;el#) Like Location, thi# pr*perty return# a value, n*t a re9erence, #* t* +anipulate the Control, y*u +u#t a##ign any change t* the pr*perty t* have any a99ect1 SiMe # 9 !yContro .SiMe3 #.Vidth R9 "03 //not a reference2 no change to contro !yContro .SiMe 9 #3 //Co. contro .i change +abBndex #peci9ie# the *rder in !hich a c*ntr*l i# activated !hen the u#er pre##e# the Ta3 key) +ext i# di#played in vari*u# !ay#, depending up*n the Control# type) The +ext *9 the 9*r+, 9*r in#tance, i# di#played a# the ,ind*!# title, !hile the Button and Label have *ther pr*pertie# #uch a# +ext'lign and :ont t* 9ineEtune their appearance G:orm ha# a :ont pr*perty, t**, 3ut it 4u#t #et# the de9ault 9*nt 9*r it# #u3Ec*ntr*l#Q it d*e# n*t change the !ay the title *9 the :orm i# di#playedH) The ,ame pr*perty c*rre#p*nd# t* the na+ed varia3le that repre#ent# the c*ntr*l and i# nece##ary 9*r the vi#ual de#igner t* !*rkQ d*nt +anually change thi#) The 9inal part *9 the 3l*ck *9 c*de a##*ciated !ith button7 read#1 thi#.$utton".C ic% R9 ne. Sy#te!.+*entUand er0thi#.$utton"XC ic%13 5r*+ *ur previ*u# di#cu##i*n *9 +ultica#t delegate#, thi# #h*uld 3e 9airly ea#y t* interpret1 Button ha# an event pr*perty Clic( !hich #peci9ie# a +ultica#t delegate *9 type &vent"andler) The +eth*d this6button7AClic(() i# 3eing added a# a +ultica#t li#tener) =t the 3*tt*+ *9 the BnitialiTeComponent +eth*d, additi*nal pr*pertie# are #et 9*r the :orm7 it#el9) 'uto#caleBase#iTe #peci9ie# h*! the :orm !ill react i9 the :orm# 9*nt i# changed t* a di99erent #i7e Ga# can happen 3y de9ault in ,ind*!#H) Client#iTe i# the area *9 the Control in !hich *ther Control# can 3e placedQ in the ca#e *9 a !ind*!,

614

Thinking in C

www.ThinkingIn.!et

that e;clude# the title 3ar and 3*rder, #cr*ll3ar# are al#* n*t part *9 the client area) The +eth*d Controls6'dd*ange() place# an array *9 Control# in the c*ntaining Control) There i# al#* an 'dd() +eth*d !hich take# a #ingle c*ntr*l, 3ut the vi#ual de#igner al!ay# u#e# 'dd*ange()) 5inally, *esumeLayout(), the c*+ple+ent t* #uspendLayout(), reactivate# lay*ut 3ehavi*r) The vi#ual de#igner pa##e# a false para+eter, indicating that it# n*t nece##ary t* 9*rce an i++ediate reElay*ut *9 the Control) The .ain() +eth*d i# prepended !ith an <#+'+hread> attri3ute, !hich #et# the threading +*del t* I#ingleEthreaded apart+ent)J ,ell di#cu## threading +*del# in chapter #threading#) The la#t +eth*d i# the private +eth*d button7AClic((), !hich !a# attached t* button7# Clic( event pr*perty in the BnitialiTeComponent() +eth*d) -n thi# +eth*d !e directly +anipulate the +ext pr*perty *9 the label7 c*ntr*l) S*+e *3vi*u# *3#ervati*n# a3*ut the *utput *9 the vi#ual de#igner1 it !*rk# !ith c*de that i# 3*th reada3le and Gde#pite the !arningH edita3le, the vi#ual de#igner !*rk# !ithin the +*n*lithic BnitialiTeComponent() e;cept that it create# eventEhandler +eth*d# that are in the #a+e Control cla## 3eing de9ined, and the c*de i#nt ItrickyJ *ther than the <#+'+hread> attri3ute and the $ispose() +eth*d Ga +eth*d !hich i# n*t nece##ary unle## the Control *r *ne *9 it# #u3Ec*ntr*l# c*ntain# n*nE +anaged re#*urce#, a# di#cu##ed in chapter #di#p*#e#H) Le## *3vi*u#ly, taken t*gether, the vi#ual de#igner does i+plicitly i+p*#e Ian *verall *rdering principleJ t* the #y#te+) The vi#ual de#igner c*n#truct# applicati*n# that have a #tatically #tructured >U-, individual identity 9*r c*ntr*l# and handler#, and l*cali7ed eventEhandling) The pr*3le+ !ith thi# architecture, a# e;perienced Ci#ual Ba#ic pr*gra++er# can atte#t, i# that pe*ple can 3e 9**led int* thinking that the de#igner i# Id*ing the *34ect *rientati*nJ 9*r the+ and eventEhandling r*utine# 3ec*+e +*n*lithic pr*cedural c*de chunk#) Thi# can al#* lead t*

Cha"ter 13* Creating Gindows = 5""lets

615

pe*ple placing the d*+ain l*gic directly in handler#, thu# 9*reg*ing the !h*le c*ncept *9 dec*upling U- l*gic 9r*+ d*+ain l*gic) Thi# i# a pri+e e;a+ple *9 !here #a+ple c*de #uch a# i# #h*!n in article# *r thi# 3**k i# +i#leading) =uth*r# and teacher# !ill generally place d*+ain l*gic inline !ith a c*ntr*l event in *rder t* #ave #pace and #i+pli9y the e;planati*n Ga# !e did !ith the label76+ext I aClic(edb c*deH) H*!ever, in pr*9e##i*nal devel*p+ent, the #tructure *9 pretty +uch any de#ignerEgenerated event handler #h*uld pr*3a3ly 3e1 pri*ate *oid #o!eContro XC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1 ; #o!e:o!ainO$Dect.So!eLogica +*ent013 < Thi# #tructure #eparate# the c*ncept *9 the Control and >U- event# 9r*+ d*+ain *34ect# and l*gical event# and a >U- that u#e# thi# #tructure !ill 3e a3le t* change it# d*+ain l*gic !ith*ut !*rrying a3*ut the di#play detail#) Un9*rtunately, alerting d*+ain *34ect# t* >U- event# i# *nly hal9 the 3attle, the >U- +u#t #*+eh*! re9lect change# in the #tate *9 d*+ain *34ect#) Thi# challenge ha# #everal di99erent #*luti*n#)

7or#;%vent;Control
The 9ir#t >U- architecture !ell di#cu## c*uld 3e called I5*r+EEventE C*ntr*l)J The 5EC architecture u#e# a uni9ied eventEdriven +*del1 >U*34ect# create >U- event# that trigger d*+ain l*gic that create d*+ain event# that trigger >U- l*gic) Thi# i# d*ne 3y creating d*+ain event pr*pertie# and having c*ntr*l# #u3#cri3e t* the+, a# thi# e;a+ple #h*!#1 //:c"T:H+C:o!ain.c# u#ing Sy#te!.'ext.Regu ar+xpre##ion#3 de egate *oid StringSp itUand er0 o$Dect #rc2 Sp itString)rg# arg#13 c a## Sp itString)rg# : +*ent)rg# ; pri*ate Sp itString)rg#01;<

616

Thinking in C

www.ThinkingIn.!et

pu$ ic Sp itString)rg#0#tringJK #tring#1; thi#.#tring# 9 #tring#3 < #tringJK #tring#3 pu$ ic #tringJK String#; get ; return #tring#3< #et ; #tring# 9 *a ue3< < < c a## :o!ainSp itter ; Regex re 9 ne. Regex0&^^#&13 #tringJK #u$#tring#3 pu$ ic e*ent StringSp itUand er String#Sp it3 pu$ ic *oid Sp itString0#tring inStr1; #u$#tring# 9 re.Sp it0inStr13 String#Sp it0 thi#2 ne. Sp itString)rg#0#u$#tring#113 < <///:8 Thi# i# *ur d*+ain *34ect, !hich #plit# a #tring int* it# #u3#tring# !ith the *egex6#plit() +eth*d) ,hen thi# happen#, the $omain#plitter rai#e# a #trings#plit event !ith the ne!ly created #u3#tring# a# an argu+ent t* it# #plit#tring'rgs) *! t* create a ,ind*!# 5*r+ that interact# !ith thi# d*+ain *34ect1 //:c"T:H+C:o!ain2.c# //Co!pi e .ith c#c H+C:o!ain H+C:o!ain2 u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## H+C:o!ain : Hor! ; 'extBox t$ 9 ne. 'extBox013 Button $ 9 ne. Button013 La$e JK a$e #3 :o!ainSp itter do!ainO$Dect 9 ne. :o!ainSp itter013

Cha"ter 13* Creating Gindows = 5""lets

61#

H+C:o!ain01; t$.Location 9 ne. -oint0"02 "013 t$.'ext 9 &'he 7uic% $ro.n fox&3 $.Location 9 ne. -oint0"P02 "013 $.'ext 9 &Sp it text&3 $.C ic% R9 ne. +*entUand er0thi#._O5+*ent13 do!ainO$Dect.String#Sp it R9 ne. StringSp itUand er0thi#.:o!ain+*ent13 thi#.'ext 9 &Hor!6+*ent6Contro &3 thi#.Contro #.)dd0t$13 thi#.Contro #.)dd0$13 < *oid _O5+*ent0o$Dect #rc2 +*ent)rg# arg#1; do!ainO$Dect.Sp itString0t$.'ext13 < *oid :o!ain+*ent0o$Dect #rc2 Sp itString)rg# arg#1; #tringJK #tring# 9 arg#.String#3 if 0 a$e # !9 nu 1 ; foreach0La$e in a$e #1; thi#.Contro #.Re!o*e0 13 < < a$e # 9 ne. La$e J#tring#.LengthK3 int ro. 9 E03 for 0int i 9 03 i W a$e #.Length3 iRR1 ; a$e #JiK 9 ne. La$e 013 a$e #JiK.'ext 9 #tring#JiK3 a$e #JiK.Location 9 ne. -oint0"002 ro.13 ro. R9 203 < thi#.Contro #.)ddRange0 a$e #13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. H+C:o!ain0113 < <///:8

61&

Thinking in C

www.ThinkingIn.!et

O3vi*u#ly, !e didnt u#e Ci#ual Studi*# de#igner t* 3uild thi# 9*r+ 3ut have reverted t* !*rking directly 9r*+ !ithin a c*de edit*r) Our :&C$omain 9*r+ c*ntain# a te;t 3*;, a 3utt*n, an array *9 La3el c*ntr*l#, and a re9erence t* $omain#plitter) The 9ir#t part *9 the :&$omain() c*n#truct*r #peci9ie# the l*cati*n and te;t *9 the te;t 3*; and 3utt*n) ,e then #peci9y t!* delegate#1 VB&vent i# a delegate *9 type &vent"andler and i# attached t* the 3utt*n# Clic( event pr*perty and $omain&vent i# *9 type #tring#plit"andler and i# attached t* the $omain#plitter# #tring#plit event) The 9inal part *9 the c*n#truct*r add# the te;t3*; and 3utt*n t* the 9*r+) ,hen the 3utt*n i# pre##ed, the Clic( delegate inv*ke# the VB&vent() +eth*d, !hich pa##e# the te;t *9 the te;t3*; t* the domain1b)ect6#plit#tring() l*gical event) Thi# in turn !ill rai#e a #tring#plit event that call# 3ack t* the $omain&vent() +eth*d) The $omain&vent() +eth*d create# and di#play# a la3el 9*r each *9 the individual #tring#) The 9ir#t ti+e $omain&vent() i# called, the labels array !ill 3e null 3ecau#e !e d* n*t initiali7e it in the c*n#truct*r) -9, th*ugh, labels i# n*t null, !e re+*ve the e;i#ting la3el# 9r*+ the Controls c*llecti*n) ,e initiali7e the labels array t* 3e a3le t* h*ld a #u99icient nu+3er *9 re9erence# and then initiali7e individual la3el# !ith the appr*priate string and a ne! p*#iti*n) Once all the labels are created, Controls6'dd*ange() add# the+ t* the :&C$omain# client area) The 5EC architecture i# vulnera3le t* the recur#ive l**p# pr*3le+# di#cu##ed previ*u#ly) -9 a d*+ain event trigger# a >U- handler !hich in turn activate# the relevant d*+ain event, the #y#te+ !ill recur#e and cra#h G!hen dealing !ith >U-#, the cra#h e;cepti*n typically inv*lve# #tarvati*n *9 #*+e ,ind*!# re#*urce 3e9*re the #tack *ver9l*!#H) H*!ever, 5EC i# very #traight9*r!ard P alth*ugh in the tiny pr*gra+# that illu#trate a 3**k it i# +*re c*+ple; than 4u#t putting d*+ain l*gic directly int* a >U- event handler, in practice it !ill very likely 3e le## c*+ple; and pr*vide# 9*r a very clean and under#tanda3le #eparati*n *9 >U- and d*+ain l*gic)

Cha"ter 13* Creating Gindows = 5""lets

61'

Presentation;)+straction; Control
=n alternative >U- architecture t* 5EC pr*p*#e# that the !h*le c*ncept *9 #eparating d*+ain l*gic 9r*+ Control# i# *vere+pha#i7ed) -n thi# vie!, 9le;i3ility i# achieved 3y encap#ulating all the di#play, c*ntr*l, and d*+ain l*gic a##*ciated !ith a relatively 9ineEgrained a3#tracti*n) >r*up# *9 the#e #el9Ec*ntained c*+p*nent# are c*+3ined t* 3uild c*ar#erE grained a3#tracti*n# G!ith c*rre#p*ndingly +*re c*+ple; di#play#, perhap# panel# and entire 9*r+#H) The#e c*ar#erEgrained a3#tracti*n# are gathered t*gether t* +ake pr*gra+#) -n the P=C architecture, the l*!e#tElevel *34ect# are likely t* 3e #u3type# *9 #peci9ic c*ntr*l#Q 9*r in#tance, a Button that encap#ulate# a 3it *9 d*+ain l*gic relating t* a trigger *r #!itch) AidElevel *34ect# +ay de#cend 9r*+ VserControl Ge##entially, an inter9aceEle## ControlH and !*uld encap#ulate di#crete chunk# *9 3u#ine## l*gic) HigherElevel *34ect# !*uld likely de#cend 9r*+ :orm and are likely t* encap#ulate all the l*gic a##*ciated !ith a particular #cenari* *r u#eEca#e) -n thi# e;a+ple, !e have a type de#cended 9r*+ Button that kn*!# !hether it i# *n *r *99 and a type de#cended 9r*+ !anel that c*ntain# the#e +wo#tate 3utt*n# and kn*!# i9 all the +wo#tate# !ithin it are in #tate IOnJ1 //:c"T:-)C.c# //-re#entation6)$#traction6Contro u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!3 c a## '.oState : Button; #tatic int in#tanceCounter 9 03 int id 9 in#tanceCounterRR3 interna '.oState01; thi#.'ext 9 State3 Sy#te!.+*entUand er hnd r 9

6)(

Thinking in C

www.ThinkingIn.!et

ne. Sy#te!.+*entUand er0$uttonC ic%13 thi#.C ic% R9 hnd r3 < $oo #tate 9 true3 pu$ ic #tring State; get ; return 0#tate 99 true1 Y &On& : &Off&3 < #et; #tate 9 0*a ue 99 &On&1 Y true : fa #e3 OnStateChanged013 < < pri*ate *oid $uttonC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1; changeState013 < pu$ ic *oid changeState01; #tate 9 !#tate3 OnStateChanged013 < pu$ ic *oid OnStateChanged01; Sy#te!.Con#o e.VriteLine0 &'.oState id & R id R & #tate changed&13 thi#.'ext 9 State3 < < c a## Chri#t!a#'ree : -ane ; $oo a On3 interna $oo ) On; get ; return a On3 < < pu$ ic Chri#t!a#'ree01; '.oState t# 9 ne. '.oState013 t#.Location 9 ne. -oint0"02 "013

Cha"ter 13* Creating Gindows = 5""lets

6)1

'.oState t#2 9 ne. '.oState013 t#2.Location 9 ne. -oint0"202 "013 )dd0t#13 )dd0t#213 Bac%Co or 9 Co or._reen3 < pu$ ic *oid )dd0'.oState c1; Contro #.)dd0c13 c.C ic% R9 ne. +*entUand er0 thi#.'.oC ic%Changed13 < pu$ ic *oid )ddRange0'.oStateJK ca1; foreach0'.oState t# in ca1; t#.C ic% R9 ne. +*entUand er0 thi#.'.oC ic%Changed13 < Contro #.)ddRange0ca13 < pu$ ic *oid '.oC ic%Changed0 O$Dect #rc2 +*ent)rg# a1; a On 9 true3 foreach0Contro c in Contro #1; '.oState t# 9 c a# '.oState3 if0t#.State !9 &On&1; a On 9 fa #e3 < < if0a On1; Bac%Co or 9 Co or._reen3 <e #e; Bac%Co or 9 Co or.Red3 < < < c a## -)CHor! : Hor! ; Chri#t!a#'ree p" 9 ne. Chri#t!a#'ree013 Chri#t!a#'ree p2 9 ne. Chri#t!a#'ree013

6))

Thinking in C

www.ThinkingIn.!et

pu$ ic -)CHor!01; C ientSiMe 9 ne. SiMe0EP02 20013 'ext 9 &+*ent# @ Gode #&3 p".Location 9 ne. -oint0"02"013 p2.Location 9 ne. -oint02002 "013 Contro #.)dd0p"13 Contro #.)dd0p213 < #tatic *oid Gain01; )pp ication.Run0ne. -)CHor!0113 < < ///:8 ,hen run, i9 y*u #et 3*th the 3utt*n# !ithin an individual Christmas+ree panel t* IOn,J the Christmas+ree# 3ackgr*und c*l*r !ill 3ec*+e green, *ther!i#e, the 3ackgr*und c*l*r !ill 3e red) The !'C:orm kn*!# n*thing a3*ut the +wo#tate# !ithin the Christmas+ree) ,e c*uld Gand indeed it !*uld pr*3a3ly 3e l*gicalH change +wo#tate 9r*+ de#cending 9r*+ Button t* de#cending 9r*+ Chec(box and +wo#tate6#tate 9r*+ a string t* a bool and it !*uld +ake n* di99erence t* the !'C:orm that c*ntain# the t!* in#tance# *9 Christmas+ree) Pre#entati*nE=3#tracti*nEC*ntr*l i# *9ten the 3e#t architecture 9*r !*rking !ith ) ET) -t# killer advantage i# that it pr*vide# an encap#ulated c*+p*nent) = c*+p*nent i# a #*9t!are +*dule that can 3e depl*yed and c*+p*#ed int* *ther c*+p*nent# without source9code modi$ication) Ci#ual Ba#ic pr*gra++er# have en4*yed the 3ene9it# *9 #*9t!are c*+p*nent# 9*r +*re than a decade, !ith th*u#and# *9 thirdE party c*+p*nent# availa3le) Ci#ual Studi* ) ET #hip# !ith a 9e! c*+p*nent# that are at a higher level than 4u#t encap#ulating #tandard c*ntr*l#, 9*r in#tance, c*+p*nent# !hich encap#ulate =?O and an*ther !hich encap#ulate# the Cry#tal Rep*rt# t**l#) P=C c*+p*nent# need n*t really 3e !ritten a# a #ingle cla##Q rather, a #ingle Control cla## +ay pr*vide a #ingle public vie! *9 a +*re c*+ple;

Cha"ter 13* Creating Gindows = 5""lets

6)3

na+e#pace !h*#e +e+3er# are n*t vi#i3le t* the *ut#ide !*rld) Thi# i# called the +aIade de#ign pattern) The pr*3le+ !ith P=C i# that it# hard !*rk t* create a decent c*+p*nent) Our Christmas+ree c*+p*nent i# h*rri3le P it d*e#nt aut*+atically place the internal +wo#tate# rea#*na3ly, it d*e#nt re#i7e t* 9it ne! +wo#tate#, it d*e#nt e;p*#e 3*th l*gical and >U- event# and pr*pertie#L The li#t g*e# *n and *n) Reu#e i# the great un9ul9illed pr*+i#e *9 *34ect *rientati*n1 I?r*p a c*ntr*l *n the 9*r+, #et a c*uple *9 pr*pertie#, and 3**+K :*uve g*t a payr*ll #y#te+)J But the reality *9 devel*p+ent i# that at lea#t 6$^ *9 y*ur ti+e i# a3#*lutely c*ntr*lled 3y the pre##ing i##ue# *9 the current devel*p+ent cycle and there i# little *r n* ti+e t* #pend *n detail# n*t related t* the ta#k at hand) Plu#, it# di99icult en*ugh t* create an e99ective >U- !hen y*u have direct acce## t* y*ur endEu#er#Q creating an e99ective >U- c*+p*nent that !ill 3e appr*priate in #ituati*n# that havent yet ari#en i# al+*#t i+p*##i3le) everthele##, Ci#ual Studi* ) ET +ake# it #* ea#y t* create a reu#a3le c*+p*nent G4u#t c*+pile y*ur c*+p*nent t* a )?LL and y*u can add it t* the T**l3arKH that y*u #h*uld al!ay# at lea#t c*n#ider P=C 9*r y*ur >Uarchitecture) *te1 c*ntr*l cant 3e in t!* c*ntr*l c*llecti*n# at *nce)

@odel;8iew;Controller
A*delECie!EC*ntr*ller, c*++*nly re9erred t* #i+ply a# IACC,J !a# the 9ir#t !idely kn*!n architectural pattern 9*r dec*upling the graphical u#er inter9ace 9r*+ underlying applicati*n l*gic) Un9*rtunately, +any pe*ple c*n9u#e ACC !ith any architecture that #eparate# pre#entati*n l*gic 9r*+ d*+ain l*gic) S* !hen #*+e*ne #tart# talking a3*ut ACC, it# !i#e t* all*! 9*r Duite a 3it *9 i+preci#i*n) -n ACC, the A*del encap#ulate# the #y#te+# l*gical 3ehavi*r and #tate, the Cie! reDue#t# and re9lect# that #tate *n the di#play, and the C*ntr*ller interpret# l*!Elevel input# #uch a# +*u#e and key3*ard #tr*ke#, re#ulting in c*++and# t* either the A*del *r the Cie!)

6)4

Thinking in C

www.ThinkingIn.!et

ACC trade# *99 a l*t *9 #tatic #tructure EE the de9initi*n *9 *34ect# 9*r each *9 the vari*u# re#p*n#i3ilitie# P 9*r the advantage *9 3eing a3le t* independently vary the vie! and the c*ntr*ller) Thi# i# n*t +uch *9 an advantage in ,ind*!# pr*gra+#, !here the vie! i# al!ay# a 3it+apped t!*Edi+en#i*nal di#play and the c*ntr*ller i# al!ay# a c*+inati*n *9 a key3*ard and a +*u#eElike p*inting device) H*!ever, USB# !ide#pread #upp*rt ha# already led t* intere#ting ne! c*ntr*ller# and the n*tE#*E di#tant 9uture !ill 3ring 3*th v*ice and ge#ture c*ntr*l and Ihy3rid realityJ di#play# t* #ea+le##ly integrate c*+puterEgenerated data int* real vi#i*n Ge)g), gla##e# that #uperi+p*#e arr*!# and la3el# *n realityH) -9 y*u happen t* 3e lucky en*ugh t* 3e !*rking !ith #uch advanced techn*l*gie#, ACC +ay 3e 4u#t the thing) Even i9 n*t, it# !*rth di#cu##ing 3rie9ly a# an e;a+ple *9 dec*upling >U- c*ncern# taken t* the l*gical e;tre+e) -n *ur e;a+ple, *ur d*+ain #tate i# #i+ply an array *9 B**lean value#Q !e !ant the di#play t* #h*! the#e value# a# 3utt*n# and di#play, in the title 3ar, !hether all the value# are true *r !hether #*+e are 9al#e1 //:c"T:GNC.c# u#ing Sy#te!3 u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.:ra.ing3 c a## Gode ; interna $oo JK a interna Gode 01; Rando! r 9 ne. int iBoo # 9 2 a Boo # 9 ne. for0int i 9 03 a Boo #JiK < < < c a## Nie. : Hor!; Gode !ode 3 ButtonJK $utton#3 Boo #3 Rando!013 R r.Cext0T13 $oo JiBoo #K3 i W iBoo #3 iRR1; 9 r.Cext:ou$ e01 Z 0.P3

Cha"ter 13* Creating Gindows = 5""lets

6)5

interna Nie.0Gode thi#.!ode 9 !3

!2 Contro

er c1;

int $uttonCount 9 !.a Boo #.Length3 $utton# 9 ne. ButtonJ$uttonCountK3 C ientSiMe 9 ne. SiMe0T002 P0 R $uttonCount = P013 for0int i 9 03 i W $uttonCount3 iRR1; $utton#JiK 9 ne. Button013 $utton#JiK.Location 9 ne. -oint0"02 P R i = P013 c.GatchContro 'oGode 0$utton#JiK2 i13 $utton#JiK.C ic% R9 ne. +*entUand er0c.C ic%Uand er13 < Ref ectGode 013 Contro #.)ddRange0$utton#13 < interna *oid Ref ectGode 01; $oo a )re'rue 9 true3 for0int i 9 03 i W !ode .a Boo #.Length3 iRR1; $utton#JiK.'ext 9 !ode .a Boo #JiK.'oString013 if0!ode .a Boo #JiK 99 fa #e1; a )re'rue 9 fa #e3 < < if0a )re'rue1; 'ext 9 &) are true&3 <e #e; 'ext 9 &So!e are not true&3 < < < c a## Contro er; Gode !ode 3 Nie. *ie.3 Contro JK *ie.Co!ponent#3

6)6

Thinking in C

www.ThinkingIn.!et

Contro er0Gode !1; !ode 9 !3 *ie.Co!ponent# 9 ne. Contro J!.a < interna *oid GatchContro 'oGode 0Button $2 int index1; *ie.Co!ponent#JindexK 9 $3 < interna *oid )ttachNie.0Nie. *1; thi#.*ie. 9 *3 <

Boo #.LengthK3

interna *oid C ic%Uand er 0O$Dect #rc2 +*ent)rg# ea1; //Godify !ode in re#pon#e to input int !ode 5ndex 9 )rray.5ndexOf0*ie.Co!ponent#2 #rc13 !ode .a Boo #J!ode 5ndexK 9 !!ode .a Boo #J!ode 5ndexK3 //Ua*e *ie. ref ect !ode *ie..Ref ectGode 013 < pu$ ic #tatic *oid Gain01; Gode ! 9 ne. Gode 013 Contro er c 9 ne. Contro er0!13 Nie. * 9 ne. Nie.0!2 c13 c.)ttachNie.0*13 )pp ication.Run0*13 < <///:8 The .odel cla## ha# an array *9 bools that are rand*+ly #et in the .odel c*n#truct*r) 5*r de+*n#trati*n purp*#e#, !ere e;p*#ing the array directly, 3ut in real li9e the #tate *9 the .odel !*uld 3e re9lected in it# entire ga+ut *9 pr*pertie#) The Hiew *34ect i# a :orm that c*ntain# a re9erence t* a .odel and it# r*le i# #i+ply t* re9lect the #tate *9 that .odel) The Hiew() c*n#truct*r

Cha"ter 13* Creating Gindows = 5""lets

6)#

lay# *ut h*! thi# particular vie! i# g*ing t* d* that P it deter+ine# h*! +any bool# are in the .odel# allBools array and initiali7e# a Button<> array *9 the #a+e #i7e) 5*r each bool in allBools, it create# a c*rre#p*nding Button, and a##*ciate# thi# particular a#pect *9 the .odel# #tate Gthe inde; *9 thi# particular boolH !ith thi# particular a#pect *9 the Hiew Gthi# particular ButtonH) -t d*e# thi# 3y calling the Controller# .atchControl+o.odel( ) +eth*d and 3y adding t* the Button# Clic( event pr*perty a re9erence t* the Controller# Clic("andler( )) Once the Hiew ha# initiali7ed it# Controls, it call# it# *!n *eflect.odel( ) +eth*d) Hiew# *eflect.odel( ) +eth*d iterate# *ver all the bool# in .odel, #etting the te;t *9 the c*rre#p*nding 3utt*n t* the value *9 the B**lean 6 -9 all are true, the title *9 the :orm i# changed t* I=ll are true,J *ther!i#e, it declare# that IS*+e are 9al#e)J The Controller *34ect ulti+ately need# re9erence# t* 3*th the .odel and t* the Hiew, and the Hiew need# a re9erence t* 3*th the .odel and the Controller) Thi# lead# t* a little 3it *9 c*+ple;ity in the initiali7ati*n #h*!n in the .ain( ) +eth*dQ the .odel( ) i# created !ith n* re9erence# t* anything Gthe .odel i# acted up*n 3y the Controller and re9lected 3y the Hiew, the .odel it#el9 never need# t* call +eth*d# *r pr*pertie# in th*#e *34ect#H) The Controller i# then created !ith a re9erence t* the .odel) The Controller( ) c*n#truct*r #i+ply #t*re# a re9erence t* the .odel and initiali7e# an array *9 Control# t* #u99icient #i7e t* re9lect the #i7e *9 the .odel6allBools array) =t thi# p*int, the Controller6Hiew re9erence i# #till null, #ince the Hiew ha# n*t yet 3een initiali7ed) Back in the .ain( ) +eth*d, the 4u#tEcreated Controller i# pa##ed t* the Hiew( ) c*n#truct*r, !hich initiali7e# the Hiew a# de#cri3ed previ*u#ly) Once the Hiew i# initiali7ed, the Controller# 'ttachHiew( ) +eth*d #et# the re9erence t* the Hiew, c*+pleting the Controller# initiali7ati*n) G:*u c*uld a# ea#ily d* the *pp*#ite, creating a Hiew !ith 4u#t a re9erence t* the .odel, creating a Controller !ith a re9erence t* the Hiew and the .odel, and then 9ini#h the Hiew# initiali7ati*n !ith an 'ttachController( ) +eth*d)H

6)&

Thinking in C

www.ThinkingIn.!et

?uring the Hiew5# c*n#truct*r, it called the Controller# .atchControl+o.odel( ) +eth*d, !hich !e can n*! #ee #i+ply #t*re# a re9erence t* a Button in the viewComponents< > array) The Controller i# re#p*n#i3le 9*r interpreting event# and cau#ing update# t* the .odel and Hiew a# appr*priate) Clic("andler( ) i# called 3y the vari*u# Button# in the Hiew !hen they are clicked) The *riginating Control i# re9erenced in the src +eth*d argu+ent, and 3ecau#e the inde; in the viewComponents< > array !a# de9ined t* c*rre#p*nd t* the inde; *9 the .odel# allBools< > array, !e can learn !hat a#pect *9 the .odel# #tate !e !i#h t* update 3y u#ing the #tatic +eth*d 'rray6Bndex1f( )) ,e change the B**lean t* it# *pp*#ite u#ing the K *perat*r and then, having changed the .odel# #tate, !e call Hiew# *eflect.odel( ) +eth*d t* keep everything in #ynchr*ny) The clear delineati*n *9 dutie# in ACC i# appealing P the Hiew pa##ively re9lect# the .odel, the Controller +ediate# update#, and the .odel i# re#p*n#i3le *nly 9*r it#el9) :*u can have +any Hiew cla##e# that re9lect the #a+e .odel G#ay, *ne #h*!ing a graph *9 value#, the *ther #h*!ing a li#tH and dyna+ically #!itch 3et!een the+) H*!ever, the #tructural c*+ple;ity *9 ACC i# a c*n#idera3le 3urden and i# di99icult t* IintegrateJ !ith the Ci#ual ?e#igner t**l)

La5out
*! that !eve di#cu##ed the vari*u# architectural *pti*n# that #h*uld 3e *9 +a4*r i+p*rt in any real >U- de#ign di#cu##i*n, !ere g*ing t* +*ve 3ack t*!ard# the e;pedient I?* a# !e #ay, n*t a# !e d*J +*de *9 c*+3ining l*gic, event c*ntr*l, and vi#ual di#play in the #a+ple pr*gra+#) -t !*uld #i+ply c*n#u+e t** +uch #pace t* #eparate d*+ain l*gic int* #eparate cla##e# !hen, u#ually, *ur e;a+ple pr*gra+# are d*ing n*thing 3ut !riting *ut #i+ple line# *9 te;t t* the c*n#*le *r de+*n#trating the 3a#ic# *9 #*+e #i+ple !idget) =n*ther area !here the #a+ple pr*gra+# di99er +arkedly 9r*+ pr*9e##i*nal c*de i# in the lay*ut *9 Control#) S* 9ar, !e have u#ed the Location pr*perty *9 a Control, !hich deter+ine# the upperEle9t c*rner *9 this Control in the client area *9 it# c*ntaining Control G*r, in the

Cha"ter 13* Creating Gindows = 5""lets

6)'

ca#e *9 a :orm, the ,ind*!# di#play c**rdinate# *9 it# upperEle9t c*rnerH) A*re 9reDuently, y*u !ill u#e the $oc( and 'nchor pr*pertie# *9 a Control t* l*cate a Control relative t* *ne *r +*re edges *9 the c*ntainer in !hich it re#ide#) The#e pr*pertie# all*! y*u t* create Control# !hich pr*perly re#i7e the+#elve# in re#p*n#e t* change# in !ind*!# #i7e) -n *ur e;a+ple# #* 9ar, re#i7ing the c*ntaining 5*r+ d*e#nt change the Control p*#iti*n#) That i# 3ecau#e 3y de9ault, Control# have an 'nchor pr*perty #et t* the 'nchor#tyles value# +op and Left G'nchor#tyles are 3it!i#e c*+3ina3leH) -n thi# e;a+ple, a 3utt*n +*ve# relative t* the *pp*#ite c*rner1 //:c"T:)nchorNa ue#.c# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.:ra.ing3 c a## )nchorNa ue#: Hor!; )nchorNa ue#01; Button $ 9 ne. Button013 $.Location 9 ne. -oint0"02 "013 $.)nchor 9 )nchorSty e#.Right S )nchorSty e#.Botto!3 Contro #.)dd0$13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. )nchorNa ue#0113 < <///:8 -9 y*u c*+3ine *pp*#ite 'nchor#tyles GLe9t and Right, T*p and B*tt*+H the Control !ill re#i7e) -9 y*u #peci9y 'nchor#tyles),one, the c*ntr*l !ill +*ve hal9 the di#tance *9 the c*ntaining area# change in #i7e) Thi# e;a+ple #h*!# the#e t!* type# *9 3ehavi*r1 //:c"T:)nchorRe#iMing.c# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.:ra.ing3

63(

Thinking in C

www.ThinkingIn.!et

c a## )nchorRe#iMing: Hor!; )nchorRe#iMing01; Button $ 9 ne. Button013 $.Location 9 ne. -oint0"02 "013 $.)nchor 9 )nchorSty e#.Left S )nchorSty e#.Right S )nchorSty e#.'op3 $.'ext 9 &Left S Right S 'op&3 Contro #.)dd0$13 Button $2 9 ne. Button013 $2.Location 9 ne. -oint0"002 "013 $2.)nchor 9 )nchorSty e#.Cone3 $2.'ext 9 &Cot anchored&3 Contro #.)dd0$213 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. )nchorRe#iMing0113 < <///:8 -9 y*u run thi# e;a+ple and +anipulate the #creen, y*ull #ee t!* unde#ira3le 3ehavi*r#1 b can *3#cure b8, and b8 can 9l*at *99 the page) ,ind*!# 5*r+# lay*ut 3ehavi*r trade# *99 tr*u3le#*+e 3ehavi*r like thi# 9*r it# #traight9*r!ard +*del) =n alternative +echani#+ 3a#ed *n cell#, #uch a# that u#ed in HTAL *r #*+e *9 "ava# Layout.anagers, +ay 3e +*re r*3u#t in av*iding the#e type# *9 tr*u3le, 3ut any*ne !h*# tried t* get a c*+ple; cellE3a#ed U- t* re#i7e the !ay they !i#h i# likely t* agree !ith ,ind*!# 5*r+# phil*#*phyK = pr*perty c*+ple+entary t* 'nchor i# $oc() The $oc( pr*perty +*ve# the c*ntr*l 9lu#h again#t the #peci9ied edge *9 it# c*ntainer, and re#i7e# the c*ntr*l t* 3e the #a+e #i7e a# that edge) -9 +*re than *ne c*ntr*l in a client area i# #et t* $oc( t* the #a+e edge, the c*ntr*l# !ill lay*ut #ideE3yE#ide in the re-erse o$ the order in !hich they !ere added t* the c*ntaining Controls array Gtheir re-erse ;9orderH) The $oc( pr*perty *verride# the Location value) -n thi# e;a+ple, t!* 3utt*n# are created and d*cked t* the le9t #ide *9 their c*ntaining :orm)

Cha"ter 13* Creating Gindows = 5""lets

631

//:c"T::oc%.c# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.:ra.ing3 c a## :oc%: Hor!; :oc%01; Button $" 9 ne. Button013 $".:oc% 9 :oc%Sty e.Left3 $".'ext 9 &Button "&3 Contro #.)dd0$"13 Button $2 9 ne. Button013 $2.:oc% 9 :oc%Sty e.Left3 $2.'ext 9 &Button2&3 Contro #.)dd0$213 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. :oc%0113 < <///:8 ,hen y*u run thi#, y*ull #ee that b appear# to the right *9 b8 3ecau#e it !a# added t* $oc(# Controls 2e$ore b86 $oc(#tyle6:ill #peci9ie# that the Control !ill e;pand t* 9ill the client area 9r*+ the center t* the li+it# all*!ed 3y *ther $oc(ed Controls) $oc(#tyle6:ill !ill c*ver n*nE$oc(ed Controls that have a l*!er 7E *rder, a# thi# e;a+ple #h*!#1 //:c"T::oc%Hi .c# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.:ra.ing3 c a## :oc%Hi : Hor!; :oc%Hi 01; //Lo.er M6order Button *i#i$ e 9 ne. Button013 *i#i$ e.'ext 9 &Ni#i$ e&3 *i#i$ e.Location 9 ne. -oint0"02 "013 Contro #.)dd0*i#i$ e13

63)

Thinking in C

www.ThinkingIn.!et

//Vi co*er &5n*i#i$ e& Button doc%ed 9 ne. Button013 doc%ed.'ext 9 &:oc%ed&3 doc%ed.:oc% 9 :oc%Sty e.Hi 3 Contro #.)dd0doc%ed13 //Uigher M6order2 gonna' $e in*i#i$ e Button in*i#i$ e 9 ne. Button013 in*i#i$ e.'ext 9 &5n*i#i$ e&3 in*i#i$ e.Location 9 ne. -oint0"002 "0013 Contro #.)dd0in*i#i$ e13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. :oc%Hi 0113 < <///:8 ?evel*ping c*+ple; lay*ut# that lay the+#elve# *ut pr*perly !hen re#i7ed i# a challenge 9*r any #y#te+) ,ind*!# 5*r+# #traight9*r!ard +*del *9 c*ntain+ent, Location, 'nchor, and $oc( i# e#pecially #uited 9*r the P=C >U- architecture de#cri3ed previ*u#ly) Rather than trying t* create a +*n*lithic chunk *9 l*gic that atte+pt# t* re#i7e and rel*cate the hundred# *r d*7en# *9 !idget# that +ight c*+pri#e a c*+ple; U-, the P=C architecture !*uld encap#ulate the l*gic !ithin individual cu#t*+ c*ntr*l#)

(on;Code 6esources
,ind*!# 5*r+# !*uldnt 3e +uch *9 a graphical u#er inter9ace li3rary i9 it did n*t #upp*rt graphic# and *ther +edia) But !hile it# ea#y t* #peci9y a Button# l**k and 9eel !ith *nly a 9e! line# *9 c*de, i+age# are inherently dependent *n 3inary data #t*rage) -t# n*t #urpri#ing that y*u can l*ad an i+age int* a ,ind*!# 5*r+ 3y u#ing a #tream *r a 9ilena+e, a# thi# e;a+ple de+*n#trate#1 //:c"T:Si!p e-icture.c# //Loading i!age# fro! fi e #y#te!

Cha"ter 13* Creating Gindows = 5""lets

633

u#ing u#ing u#ing u#ing

Sy#te!3 Sy#te!.5O3 Sy#te!.Vindo.#.Hor!#3 Sy#te!.:ra.ing3

c a## Si!p e-icture : Hor! ; pu$ ic #tatic *oid Gain0#tringJK arg#1; Si!p e-icture #p 9 ne. Si!p e-icture0arg#J0K13 )pp ication.Run0#p13 < Si!p e-icture0#tring fCa!e1; -ictureBox p$ 9 ne. -ictureBox013 p$.5!age 9 5!age.Hro!Hi e0fCa!e13 p$.:oc% 9 :oc%Sty e.Hi 3 p$.SiMeGode 9 -ictureBoxSiMeGode.Stretch5!age3 Contro #.)dd0p$13 int i!gVidth 9 p$.5!age.Vidth3 int i!gUeight 9 p$.5!age.Ueight3 thi#.C ientSiMe 9 ne. SiMe0i!gVidth2 i!gUeight13 < <///:8 The .ain( ) +eth*d take# the 9ir#t c*++andEline argu+ent a# a path t* an i+age G9*r in#tance1 ISi+plePicture c1d!ind*!#dcl*ud#)3+pJH and pa##e# that path t* the #imple!icture( ) c*n#truct*r) The +*#t c*++*n Control u#ed t* di#play a 3it+ap i# the !ictureBox c*ntr*l, !hich ha# an Bmage pr*perty) The #tatic +eth*d Bmage6:rom:ile( ) generate# an Bmage 9r*+ the given path Gthere i# al#* an Bmage6:rom#tream( ) #tatic +eth*d !hich pr*vide# general acce## t* all the p*##i3le #*urce# *9 i+age dataH) The !ictureBox# $oc( pr*perty i# #et t* $oc(style6:ill and the Client#iTe *9 the 9*r+ i# #et t* the #i7e *9 the Bmage) ,hen y*u run thi# pr*gra+, the #imple!icture 9*r+ !ill #tart at the #a+e #i7e *9 the i+age) Becau#e pb6#iTe.ode !a# #et t* #tretchBmage, h*!ever, y*u

634

Thinking in C

www.ThinkingIn.!et

can re#i7e the 9*r+ and the i+age !ill #tretch *r #hrink appr*priately) =lternate !ictureBox#iTe.ode value# are ,ormal G!hich clip# the Bmage t* the !ictureBox# #i7eH, 'uto#iTe G!hich re#i7e# the !ictureBox t* acc*++*date the Bmage# #i7eH, and CenterBmage6 L*ading re#*urce# 9r*+ e;ternal 9ile# i# certainly appr*priate in +any circu+#tance#, e#pecially !ith i#*lated #t*rage G#re9#H, !hich give# y*u a perEu#er, c*n#i#tent virtual 9ile #y#te+) H*!ever, real applicati*n# !hich are intended 9*r internati*nal c*n#u+pti*n reDuire +any re#*urce# l*cali7ed t* the current culture P la3el#, +enu na+e#, and ic*n# +ay all have t* change) The ) ET 5ra+e!*rk pr*vide# a #tandard +*del 9*r e99iciently #t*ring #uch re#*urce# and l*ading the+) A*+entarily putting a#ide the Due#ti*n *9 h*! #uch re#*urce# are created, retrieving the+ i# the !*rk *9 the *esource.anager cla##) Thi# e;a+ple #!itche# l*cali7ed la3el# indicating I+anJ and I!*+an)J //:c"T:5nternationa .c# u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Re#ource#3 u#ing Sy#te!._ o$a iMation3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## 5nternationa : Hor!; Re#ourceGanager r!3 La$e !an3 La$e .o!an3 pu$ ic 5nternationa 01; r! 9 ne. Re#ourceGanager0typeof05nternationa 113 RadioButton eng 9 ne. RadioButton013 eng.Chec%ed 9 true3 eng.Location 9 ne. -oint0"02 "013 eng.'ext 9 &)!erican&3 eng.Chec%edChanged R9 ne. +*entUand er0LoadOSRe#ource#13 RadioButton #.a 9 ne. RadioButton013 #.a.Location 9 ne. -oint0"02 T013

Cha"ter 13* Creating Gindows = 5""lets

635

#.a.'ext 9 &S.ahi i&3 #.a.Chec%edChanged R9 ne. +*entUand er0LoadS.ahi iRe#ource#13 !an 9 ne. La$e 013 !an.Location 9 ne. -oint0"02 ?013 !an.'ext 9 &Gan&3 .o!an 9 ne. La$e 013 .o!an.Location 9 ne. -oint0"02 >013 .o!an.'ext 9 &Vo!an&3 Contro #.)ddRange0ne. Contro JK ; eng2 #.a2 !an2 .o!an<13 'ext 9 &5nternationa &3 < pu$ ic *oid LoadOSRe#ource# 0O$Dect #rc2 +*ent)rg# a1; if 0 00RadioButton1#rc1.Chec%ed 99 true1 ; Re#ourceSet r# 9 r!._etRe#ourceSet0 ne. Cu ture5nfo0&en6OS&12 true2 true13 SetLa$e #0r#13 < < pu$ ic *oid LoadS.ahi iRe#ource# 0O$Dect #rc2 +*ent)rg# a1; if 000RadioButton1#rc1.Chec%ed 99 true1 ; Re#ourceSet r# 9 r!._etRe#ourceSet0 ne. Cu ture5nfo0&#.&12 true2 true13 SetLa$e #0r#13 < < pri*ate *oid SetLa$e #0Re#ourceSet r#1; !an.'ext 9 r#._etString0&Gan&13 .o!an.'ext 9 r#._etString0&Vo!an&13

636

Thinking in C

www.ThinkingIn.!et

< pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. 5nternationa 0113 < < Here, !e !i#h t* create an applicati*n !hich u#e# la3el# in a l*cal culture Ga culture i# +*re #peci9ic than a languageQ 9*r in#tance, there i# a di#tincti*n 3et!een the culture *9 the United State# and the culture *9 the United Ningd*+H) The 3a#ic re9erence# !ell need are t* *esource.anager rm, !hich !ell l*ad t* 3e cultureE#peci9ic, and t!* la3el# 9*r the !*rd# IAanJ and I,*+an)J The 9ir#t line *9 the Bnternational c*n#truct*r initiali7e# rm t* 3e a re#*urce +anager 9*r the #peci9ied type) = *esource.anager i# a##*ciated !ith a #peci9ic type 3ecau#e ) ET u#e# a Ihu3 and #p*keJ +*del 9*r +anaging re#*urce#) The Ihu3J i# the a##e+3ly that c*ntain# the c*de *9 a #peci9ic type) The I#p*ke#J are 7er* *r +*re satellite assem2lies that c*ntain the re#*urce# 9*r #peci9ic culture#, and the *esource.anager i# the link that a##*ciate# a type Ga Ihu3JH !ith it# I#p*ke#J) Bnternational( ) then #h*!# the u#e *9 radi* 3utt*n# in ,ind*!# 5*r+#) The +*del i# #i+ple1 all radi* 3utt*n# !ithin a c*ntainer are +utually e;clu#ive) T* +ake +ultiple #et# *9 radi* 3utt*n# !ithin a #ingle 9*r+, y*u can u#e a roupBox *r !anel) Bnternational ha# t!* *adioButton#, eng ha# it# Chec(ed pr*perty #et t* true, and, !hen that pr*perty change#, the Load&nglish*esources +eth*d !ill 3e called) *adioButton swa i# #i+ilarly c*n9igured t* call Load#wahili*esources( ) and i# n*t initially checked) By de9ault, the man and woman la3el# are #et t* a hardEc*ded value) The Load"""*esources( ) +eth*d# are #i+ilarQ they check i9 their #*urce *adioButton i# checked G#ince they are handling the Chec(edChange event, the +eth*d# !ill 3e called !hen their #*urce 3ec*+e# deEchecked a# !ellH) -9 their #*urce is #et, the *esource.anager l*ad# *ne *9 the I#p*keJ *esource#et *34ect#) The *esource#et i# a##*ciated !ith a particular CultureBnfo in#tance, !hich i# initiali7ed !ith a language tag string c*+pliant !ith -ET5 R5C

Cha"ter 13* Creating Gindows = 5""lets

63#

0%.. Gy*u can 9ind a li#t *9 #tandard c*de# in the ) ET 5ra+e!*rk d*cu+entati*n and read the R5C at http1<<!!!)iet9)*rg<r9c<r9c0%..)t;tH) The et*esource#et( ) +eth*d al#* take# t!* bools, the 9ir#t #peci9ying i9 the *esource#et #h*uld 3e l*aded i9 it d*e# n*t yet e;i#t in +e+*ry, and the #ec*nd #peci9ying i9 the *esource.anager #h*uld try t* l*ad Iparent#J *9 the culture i9 the #peci9ied CultureBnfo d*e# n*t !*rkQ 3*th *9 the#e bool# !ill al+*#t al!ay# 3e true) Once the *esource#et i# retrieved, it i# u#ed a# a para+eter t* the #etLabels( ) +eth*d) #etLabels( ) u#e# *esource#et6 et#tring( ) t* retrieve the appr*priate cultureE#peci9ic string 9*r the #peci9ied key and #et# the a##*ciated Label6+ext) *esource#et# *ther +a4*r +eth*d i# et1b)ect( ) !hich can 3e u#ed t* retrieve any type *9 re#*urce) ,eve n*t yet created the #atellite a##e+3lie# !hich !ill #erve a# the I#p*ke#J t* *ur Bnternational Ihu3,J 3ut it i# intere#ting t* run the pr*gra+ in thi# #tate) -9 y*u run the a3*ve c*de and click the IS!ahiliJ radi* 3utt*n, y*u !ill #ee thi# dial*g1

Thi# i# n*t a dial*g y*ud ever !ant an endEu#er t* #ee and a real applicati*n# e;cepti*n handling !*uld hide it, 3ut it# an intere#ting e;a+ple *9 the kind *9 3ehavi*r that y*u c*uld p*tentially include in y*ur *!n c*+p*nent# t* aid /rd party devel*per# during de3ugging)

63&

Thinking in C

www.ThinkingIn.!et

Creating 'atellite )sse#+lies


5*r y*ur #atellite a##e+3ly t* !*rk, y*u +u#t 9*ll*! na+ing Gincluding capitali7ati*nH and direct*ry c*nventi*n#) 5ir#t, y*u !ill create a ne! #u3direct*ry 9*r each culture y*u !i#h t* #upp*rt and na+ed !ith the culture# language tag) -9 y*u c*+piled Bnternational6exe in the direct*ry c1dticdchap0/, y*u !ill create c1dticdchap0/d#! and c1dticdchap0/denEUS) -n the d#! #u3direct*ry, create a 9ile !ith the#e c*ntent#1 Gan9!.ana!u!e Vo!an9!.ana!%e =nd #ave the 9ile !ith a )t;t e;ten#i*n G#ay, a# IS!ahili)t;tJH) U#e the c*++andEline re#*urce generat*r t**l t* turn thi# 9ile int* a 3inary re#*urce 9ile that 9*ll*!# the na+ing c*nventi*n +ain)ssembly.languagetag4resources) 5*r thi# e;a+ple, the c*++and i#1 re#gen #.ahi i.txt 5nternationa .#..re#ource# The 6resources 9ile n*! ha# t* 3e c*nverted int* a #atellite a##e+3ly na+ed +ain)ssembly4resources6dll) Thi# i# d*ne !ith the assem2l4 linker t**l al) B*th *9 the#e line# #h*uld 3e typed a# a #ingle c*++and1 a /t: i$ /e!$ed:5nternationa .#..re#ource# /cu ture:#. /out:5nternationa .re#ource#.d The re#ulting )?LL #h*uld #till 3e in the d#! #u3direct*ry) ?* the #a+e pr*ce## in the denEUS direct*ry a9ter creating an appr*priate te;t 9ile1 re#gen a!erican.txt 5nternationa .en6OS.re#ource# a /t: i$ /e!$ed:5nternationa .en6OS.re#ource# /cu ture:en6OS /out:5nternationa .re#ource#.d S!itch 3ack t* the parent direct*ry and run Bnternational) *!, !hen y*u run the pr*gra+, the man and woman la3el# #h*uld #!itch 3et!een S!ahili and =+erican in re#p*n#e t* the radi* 3utt*n#)

Cha"ter 13* Creating Gindows = 5""lets

63'

Constant 6esources
,hile culturally appr*priate re#*urce# u#e #atellite a##e+3lie#, it +ay 3e the ca#e that y*u !i#h t* have certain re#*urce# #uch a# graphic# and ic*n# e+3edded directly in the +ain a##e+3ly) U#ing graphic# a# re#*urce# i# a little +*re di99icult than u#ing te;t 3ecau#e y*u +u#t u#e a utility cla## t* generate the re#*urce 9ile) Here# an e;a+ple c*++andE line cla## that take# t!* c*++andEline argu+ent#1 the na+e *9 a graphic# 9ile and the na+e *9 the de#ired re#*urce# 9ile1 //:c"T:_rafRe#_en.c# //_enerate# .re#ource fi e fro! a graphic# fi e //O#age: _rafRe#_en JinputHi eK JoutputHi eK u#ing Sy#te!.5O3 u#ing Sy#te!.Re#ource#3 u#ing Sy#te!.:ra.ing3 c a## _rafRe#_en ; _rafRe#_en0 #tring na!e2 Strea! inStr2 Strea! outStr1; Re#ourceVriter r. 9 ne. Re#ourceVriter0outStr13 5!age i!g 9 ne. Bit!ap0inStr13 r..)ddRe#ource0na!e2 i!g13 r.._enerate013 < pu$ ic #tatic *oid Gain0#tringJK arg#1; Hi eStrea! inH 9 nu 3 Hi eStrea! outH 9 nu 3 try ; #tring na!e 9 arg#J0K3 inH 9 ne. Hi eStrea!0na!e2 Hi eGode.Open13 #tring outCa!e 9 arg#J"K3 outH 9 ne. Hi eStrea!0outCa!e2 Hi eGode.Create13 _rafRe#_en g 9 ne. _rafRe#_en0na!e2 inH2 outH13 < fina y ; inH.C o#e013

64(

Thinking in C

www.ThinkingIn.!et

outH.C o#e013 < < <//:8 = *esource=riter generate# 3inary 6resource 9ile# t* a given #tream) = *es?*esource=riter Gn*t de+*n#tratedH can 3e u#ed t* create an BAL repre#entati*n *9 the re#*urce# that can then 3e c*+piled int* a 3inary 9ile u#ing the resgen pr*ce## de#cri3ed a3*ve Gan BAL repre#entati*n i# n*t very help9ul 9*r 3inary data, #* !e ch*#e t* u#e a *esource=riter directlyH) T* u#e thi# pr*gra+, c*py an i+age t* the l*cal direct*ry and run1 _rafRe#_en #o!ei!age.Dpg Con#tantRe#ource#.re#ource# Thi# !ill generate a 3inary re#*urce# 9ile that !ell e+3ed in thi# e;a+ple pr*gra+1 //:c"T:Con#tantRe#ource#.c# /= Co!pi e .ith: c#c /re#:Con#tantRe#ource#.re#ource# Con#tantRe#ource#.c# =/ //Load# re#ource# fro! the current a##e!$ y u#ing Sy#te!.Re#ource#3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Con#tantRe#ource#:Hor!; Con#tantRe#ource#01; -ictureBox p$ 9 ne. -ictureBox013 p$.:oc% 9 :oc%Sty e.Hi 3 Contro #.)dd0p$13 Re#ourceGanager r! 9 ne. Re#ourceGanager0thi#._et'ype0113 p$.5!age 9 05!age1 r!._etO$Dect0&#o!ei!age.Dpg&13 < pu$ ic #tatic *oid Gain01;

Cha"ter 13* Creating Gindows = 5""lets

641

)pp ication.Run0ne. Con#tantRe#ource#0113 < <//:8 The c*de in Constant*esources i# very #i+ilar t* the c*de u#ed t* l*ad cultural re#*urce# 9r*+ #atellite#, 3ut !ith*ut the et*esource#et( ) call t* l*ad a particular #atellite) -n#tead, the *esource.anager l**k# 9*r re#*urce# a##*ciated !ith the Constant*esources type) aturally, th*#e are #t*red in the Constant*esources6resources 9ile generated 3y the raf*es en utility 4u#t de#cri3ed) 5*r the *esource.anager t* 9ind thi# 9ile, th*ugh, the re#*urce 9ile +u#t 3e linked int* the +ain a##e+3ly in thi# +anner1 c#c /re#:Con#tantRe#ource#.re# Con#tantRe#ource#.c# =##u+ing that the re#*urce# have 3een pr*perly e+3edded int* the Constant*esources6exe a##e+3ly, the *esource.anager can l*ad the Isomeimage6)pgJ re#*urce and di#play it in the !ictureBox pb)

What )+out the TP Loo*<


-9 y*u have 3een running the #a+ple pr*gra+# under ,ind*!# BP, y*u +ay have 3een di#app*inted t* #ee that Control# d* n*t aut*+atically #upp*rt BP# graphical the+e#) -n *rder t* activate BPEthe+ed c*ntr*l#, y*u +u#t #et y*ur Control# :lat#tyle pr*perty t* :lat#tyle6#ystem and #peci9y that y*ur pr*gra+ reDuire# Aicr*#*9t# comctlZ a##e+3ly t* run) :*u d* that 3y creating an*ther type *9 n*nEc*de re#*urce 9*r y*ur 9ile1 a +ani9e#t) = +ani9e#t i# an BAL d*cu+ent that #peci9ie# all #*rt# *9 +etaEin9*r+ati*n a3*ut y*ur pr*gra+1 it# na+e, ver#i*n, and #* 9*rth) One thing y*u can #peci9y in a +ani9e#t i# a dependency *n an*ther a##e+3ly, #uch a# comctlZ) T* link t* comctlZ, y*ull need a +ani9e#t *9 thi# 9*r+1 W!66 ,-'he!ed.exe.!anife#t 66Z WYx! *er#ion9&".0& encoding9&O'H6I& #tanda one9&ye#& YZ Wa##e!$ y x! n#9&urn:#che!a#6!icro#oft6co!:a#!.*"& !anife#tNer#ion9&".0&Z Wa##e!$ y5dentity

64)

Thinking in C

www.ThinkingIn.!et

type9&.inT2& na!e9&'hin%ingin.C#harp.C"T.,-'he!e#& *er#ion9&".0.0.0& proce##or)rchitecture 9 &,I?& /Z Wde#criptionZ:e!on#trate ,- 'he!e#W/de#criptionZ W!66 Lin% to co!ct ? 66Z WdependencyZ Wdependent)##e!$ yZ Wa##e!$ y5dentity type9&.inT2& na!e9&Gicro#oft.Vindo.#.Co!!on6Contro #& *er#ion9&?.0.0.0& proce##or)rchitecture9&,I?& pu$ icaey'o%en9&?P>P$?E"EEccf"df& anguage9&=& /Z W/dependent)##e!$ yZ W/dependencyZ W/a##e!$ yZ The +ani9e#t 9ile i# an BALE9*r+atted #*urce *9 +etaEin9*r+ati*n a3*ut y*ur pr*gra+) -n thi# ca#e, a9ter #peci9ying *ur *!n assemblyBdentity, !e #peci9y the dependency *n Common-Controls ver#i*n .) a+e thi# 9ile "rogram!ame6exe6manifest and place it in the #a+e direct*ry a# y*ur pr*gra+) -9 y*u d*, the ) ET Runti+e !ill aut*+atically give the appr*priate Control# in y*ur pr*gra+ BP the+e#) Here# an e;a+ple pr*gra+1 //:c"T:,-'he!ed.c# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.:ra.ing3 c a## ,-'he!ed: Hor!; ,-'he!ed01; C ientSiMe 9 ne. SiMe02P02 "0013 Button $ 9 ne. Button013 $.'ext 9 &,- Sty e&3 $.Location 9 ne. -oint0"02 "013 $.H atSty e 9 H atSty e.Sy#te!3 Contro #.)dd0$13

Cha"ter 13* Creating Gindows = 5""lets

643

Button $2 9 ne. Button013 $2.'ext 9 &Standard&3 $2.Location 9 ne. -oint0"002 "013 Contro #.)dd0$213 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. ,-'he!ed0113 < <///:8 ,hen run !ith*ut an appr*priate +ani9e#t 9ile, 3*th 3utt*n# !ill have a de9ault gray #tyle1

,hen ?!+hemed6exe6manifest i# availa3le, b !ill u#e the current BP the+e, !hile b8, !h*#e :lat#tyle i# the de9ault :lat#tyle6#tandard, !ill n*t)

7anc5 3uttons
-n additi*n t* creating the+eEa!are 3utt*n#, it i# an ea#y +atter t* create 3utt*n# that have a variety *9 graphical 9eature# and that change their appearance in re#p*n#e t* event#) -n *rder t* run thi# e;a+ple pr*gra+,

644

Thinking in C

www.ThinkingIn.!et

y*ull have t* have 9*ur i+age# in the active direct*ry Gin the e;a+ple c*de, theyre a##u+ed t* 3e na+ed Itic)gi9J, Ia!ay)gi9J,Jin)gi9J, and Ih*ver)gi9JH) //:c"T:ButtonHor!.c# ///:e!on#trate# *ariou# type# of $utton# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 u#ing Sy#te!.:ra.ing3 c a## ButtonHor! : Hor! ; ButtonHor!01 ; C ientSiMe 9 ne. Sy#te!.:ra.ing.SiMe0E002 20013 'ext 9 &Button#2 in a their g ory&3 Button #i!p e 9 ne. Button013 #i!p e.'ext 9 &Si!p e&3 #i!p e.Location 9 ne. -oint0"02 "013 Button i!age 9 ne. Button013 i!age.5!age 9 5!age.Hro!Hi e0&.^^'iC.gif&13 i!age.'ext 9 &'ext&3 i!age.Location 9 ne. -oint0"202 "013 Button popup 9 ne. Button013 popup.Location 9 ne. -oint02T02 "013 popup.'ext 9 &-opup&3 popup.H atSty e 9 H atSty e.-opup3 H yO*erButton f yO*er 9 ne. H yO*erButton0&).ay&2 &5n&2 &Uo*ering&13 f yO*er.Location 9 ne. -oint0"02 E013 H yO*er5!age# f yO*er5!age# 9 ne. H yO*er5!age# 0&.^^a.ay.gif&2&.^^in.gif&2&.^^ho*er.gif&13 f yO*er5!age#.Location 9 ne. -oint02T02 E013 Contro #.)ddRange0ne. Contro JK;

Cha"ter 13* Creating Gindows = 5""lets

645

#i!p e2 i!age2 popup2 f yO*er2 f yO*er5!age#< 13 < pu$ ic #tatic *oid Gain01 ; )pp ication.Run0ne. ButtonHor!0113 < < c a## H yO*erButton : Button ; #tring a.ay3 #tring inStr3 #tring ho*er3 interna H yO*erButton0 #tring a.ay2 #tring inStr2 #tring ho*er1 ; thi#.a.ay 9 a.ay3 thi#.inStr 9 inStr3 thi#.ho*er 9 ho*er3 H atSty e 9 H atSty e.-opup3 'ext 9 a.ay3 Gou#e+nter R9 ne. +*entUand er0OnGou#e+nter13 Gou#eUo*er R9 ne. +*entUand er0OnGou#eUo*er13 Gou#eLea*e R9 ne. +*entUand er0OnGou#eLea*e13 < pri*ate *oid OnGou#e+nter0 o$Dect #ender2 Sy#te!.+*ent)rg# arg#1 ; 00Contro 1#ender1.'ext 9 inStr3 < pri*ate *oid OnGou#eUo*er0 o$Dect #ender2 Sy#te!.+*ent)rg# arg#1 ; 00Contro 1#ender1.'ext 9 ho*er3 < pri*ate *oid OnGou#eLea*e0 o$Dect #ender2 Sy#te!.+*ent)rg# arg#1 ; 00Contro 1#ender1.'ext 9 a.ay3 < < c a## H yO*er5!age# : Button ;

646

Thinking in C

www.ThinkingIn.!et

interna H yO*er5!age#0 #tring a.ay2 #tring inStr2 #tring ho*er1 ; 5!ageLi#t 9 ne. 5!ageLi#t013 5!ageLi#t.5!age#.)dd05!age.Hro!Hi e0a.ay113 5!ageLi#t.5!age#.)dd05!age.Hro!Hi e0inStr113 5!ageLi#t.5!age#.)dd05!age.Hro!Hi e0ho*er113 H atSty e 9 H atSty e.-opup3 5!age5ndex 9 03 Gou#e+nter R9 ne. +*entUand er0OnGou#e+nter13 Gou#eUo*er R9 ne. +*entUand er0OnGou#eUo*er13 Gou#eLea*e R9 ne. +*entUand er0OnGou#eLea*e13 < pri*ate *oid OnGou#e+nter0 o$Dect #ender2 Sy#te!.+*ent)rg# arg#1 ; 00Button1#ender1.5!age5ndex 9 "3 < pri*ate *oid OnGou#eUo*er0 o$Dect #ender2 Sy#te!.+*ent)rg# arg#1 ; 00Button1#ender1.5!age5ndex 9 23 < pri*ate *oid OnGou#eLea*e0 o$Dect #ender2 Sy#te!.+*ent)rg# arg#1 ; 00Button1#ender1.5!age5ndex 9 03 < <///:8 The 9ir#t 3utt*n created and placed *n the 9*r+ i# simple and it# appearance and 3ehavi*r #h*uld 3e 9a+iliar) The #ec*nd 3utt*n image, #et# it# Bmage pr*perty 9r*+ an Bmage l*aded 9r*+ a 9ile) The #a+e Bmage i# di#played at all ti+e#Q i9 the +ext pr*perty i# #et, the la3el !ill 3e dra!n o-er the Bmage) The third 3utt*n popup ha# a :lat#tyle *9 :lat#tyle6!opup) Thi# 3utt*n appear# 9lat until the +*u#e pa##e# *ver it, at !hich p*int it i# redra!n !ith a /E? l**k) The 9*urth and 9i9th 3utt*n# reDuire +*re c*de and #* are !ritten a# their *!n cla##e#1 :ly1verButton and :ly1verBmages) The :ly1verButton i# a regular 3utt*n, 3ut ha# event handler# 9*r

Cha"ter 13* Creating Gindows = 5""lets

64#

.ouse&nter, .ouse"over, and .ouseLeave !hich #et the +ext pr*perty a# appr*priate) :ly1verBmages take# advantage *9 the BmageList pr*perty *9 Button) Like :ly1verButton, :ly1verBmages u#e# +*u#e event# t* change the i+age di#played *n the 3utt*n, 3ut in#tead *9 +anipulating the Bmage pr*perty, it #et# the BmageBndex pr*perty, !hich c*rre#p*nd indice# in the BmageList c*n9igured in the :ly1verBmages( ) c*n#truct*r)

-oolti$s
The *ne I9ancyJ thing that the previ*u# e;a+ple did n*t #h*! i# pr*3a3ly the *ne y*u +*#t e;pect P the help te;t that appear# !hen the +*u#e h*ver# *ver a c*ntr*l 9*r +*re than a 9e! +*+ent#) Such t**ltip# are, #urpri#ingly, n*t a pr*perty *9 the Control a3*ve !hich they appear, 3ut rather are c*ntr*lled 3y a #eparate +ool+ip *34ect) Thi# !*uld #ee+ t* vi*late a de#ign ruleE*9Ethu+31 *34ect# #h*uld generally c*ntain a naviga3le re9erence t* all *34ect# e;ternally c*n#idered a##*ciated) =# a u#er *r pr*gra++er, *ne !*uld de9initely c*n#ider the t**ltip t* 3e Ipart *9J !hat di#tingui#he# *ne c*ntr*l 9r*+ an*ther, #* *ne #h*uld e;pect a +ooltip pr*perty in Control) =n*ther #urpri#e i# that the +ool+ip d*e# n*t c*n9*r+ t* the c*ntain+ent +*del *9 ,ind*!# 5*r+#, it i# n*t placed !ithin the Controls c*llecti*n *9 an*ther Control) Thi# i# an e;a+ple *9 h*! even the 3e#tEde#igned li3rarie# Gand ,ind*!# 5*r+# i# t*pEn*tchH c*ntain inc*n#i#tencie# and Duirk#Q !hile it can 3e very help9ul t* #tudy the de#ign *9 a g**d li3rary t* aid y*ur de#ign educati*n, all li3rarie# c*ntain Due#ti*na3le ch*ice#) =dding a +ool+ip t* a Control reDuire# that a re9erence t* the Control and it# de#ired te;t 3e pa##ed t* an in#tance *9 +ool+ip G!hich pre#u+a3ly +aintain# an internal B$ictionary, !hich 3eg# the Due#ti*n *9 !hy a +ool+ip in#tance i# reDuired rather than u#ing a #tatic +eth*dH) Here# an e;a+ple that #h*!# the 3a#ic u#e *9 a +ool+ip1 //:c"T:'oo tip:i#p ay.c# u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3

64&

Thinking in C

www.ThinkingIn.!et

c a## 'oo tip:i#p ay : Hor!; 'oo tip:i#p ay01; Button $ 9 ne. Button013 $.'ext 9 &Button&3 $.Location 9 ne. -oint0"02 "013 Contro #.)dd0$13 'oo 'ip t 9 ne. 'oo 'ip013 t.Set'oo 'ip0$2 &:oe# nothing&13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. 'oo tip:i#p ay0113 < <

4is$la5ing I %diting -e&t


One *9 the +*#t c*++*n ta#k# 9*r a >U- i# di#playing 9*r+atted te;t) -n ,ind*!# 5*r+#, 9*r+atted te;t i# the real+ *9 the *ich+extBox, !hich di#play# and +anipulate# te;t in Rich Te;t 5*r+at) The detail# *9 the RT5 #ynta; are thank9ully hidden 9r*+ the pr*gra++er, te;t appearance i# +anipulated u#ing vari*u# #election""" pr*pertie#, !hich +anipulate the ch*#en #u3#tring *9 the t*tal *ich+extBox6+ext) :*u can even, i9 y*ure #* inclined, get and #et the 9ull RT5 te;t G!hich i# actually help9ul !hen draggingEandEdr*pping 9r*+, #ay, ,*rd) ?ragEandEdr*p i# c*vered later in thi# chapter)H Thi# e;a+ple all*!# y*u t* add ar3itrary te;t t* a *ich+extBox !ith vari*u# 9*r+atting *pti*n# ch*#en #e+iErand*+ly1 //:c"T:'ext+diting.c# ///:e!on#trate# the 'extBox and Rich'extBox contro # u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 u#ing Sy#te!.:ra.ing3 c a## 'ext+diting : Hor! ; 'extBox t$3

Cha"ter 13* Creating Gindows = 5""lets

64'

Rich'extBox rt$3 Rando! rand 9 ne. Rando!013 'ext+diting01 ; C ientSiMe 9 ne. SiMe0EP02 E0013 'ext 9 &'ext +diting&3 t$ 9 ne. 'extBox013 t$.'ext 9 &So!e 'ext&3 t$.Location 9 ne. -oint0"02 "013 Button $o d 9 ne. Button013 $o d.'ext 9 &Bo d&3 $o d.Location 9 ne. -oint0TP02 "013 $o d.C ic% R9 ne. +*entUand er0$o dXC ic%13 Button co or 9 ne. Button013 co or.'ext 9 &Co or&3 co or.Location 9 ne. -oint0TP02 ?013 co or.C ic% R9 ne. +*entUand er0co orXC ic%13 Button #iMe 9 ne. Button013 #iMe.'ext 9 &SiMe&3 #iMe.Location 9 ne. -oint0TP02 ""013 #iMe.C ic% R9 ne. +*entUand er0#iMeXC ic%13 Button font 9 ne. Button013 font.'ext 9 &Hont&3 font.Location 9ne. -oint0TP02 "?013 font.C ic% R9 ne. +*entUand er0fontXC ic%13 rt$ 9 ne. Rich'extBox013 rt$.Location 9 ne. -oint0"02 P013 rt$.SiMe 9 ne. SiMe0T002 "I013 Contro #.)ddRange0 ne. Sy#te!.Vindo.#.Hor!#.Contro JK; t$2 rt$2 $o d2 co or2 #iMe2 font<13 <

65(

Thinking in C

www.ThinkingIn.!et

pri*ate *oid )dd)ndSe ect'ext01 ; #tring ne.'ext 9 t$.'ext R &^n&3 int in#ertion-oint 9 rt$.Se ectionStart3 rt$.)ppend'ext0ne.'ext13 rt$.Se ectionStart 9 in#ertion-oint3 rt$.Se ectionLength 9 ne.'ext.Length3 < pri*ate *oid Re#etSe ection)ndHont01 ; /= Setting $eyond end of text$ox p ace# in#ertion at end of text =/ rt$.Se ectionStart 9 5nt"?.GaxNa ue3 rt$.Se ectionLength 9 03 rt$.Se ectionHont 9 ne. Hont0&Nerdana&2 "02 HontSty e.Regu ar13 rt$.Se ectionCo or 9 Co or.B ac%3 < pri*ate *oid $o dXC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1 ; )dd)ndSe ect'ext013 rt$.Se ectionHont 9 ne. Hont0&Nerdana&2 "02 HontSty e.Bo d13 Re#etSe ection)ndHont013 < pri*ate *oid co orXC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1 ; )dd)ndSe ect'ext013 rt$.Se ectionCo or 9 0rand.Cext:ou$ e011 Z 0.P Y Co or.Red : Co or.B ue3 Re#etSe ection)ndHont013 < pri*ate *oid #iMeXC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1 ; )dd)ndSe ect'ext013 int fontSiMe 9 I R rand.Cext0"013 rt$.Se ectionHont 9 ne. Hont0&Nerdana&2 fontSiMe2

Cha"ter 13* Creating Gindows = 5""lets

651

HontSty e.Regu ar13 Re#etSe ection)ndHont013 < pri*ate *oid fontXC ic%0 o$Dect #ender2 Sy#te!.+*ent)rg# e1 ; )dd)ndSe ect'ext013 HontHa!i yJK fa!i ie# 9 HontHa!i y.Ha!i ie#3 int iHa!i y 9 rand.Cext0fa!i ie#.Length13 rt$.Se ectionHont 9 ne. Hont0fa!i ie#JiHa!i yK2 "02 HontSty e.Regu ar13 Re#etSe ection)ndHont013 < #tatic *oid Gain01 ; )pp ication.Run0ne. 'ext+diting0113 < <///:8 Everything in the +ext&diting( ) c*n#truct*r #h*uld 3e 9a+iliar1 a nu+3er *9 Button# are created, event handler# attached, and a +extBox and *ich+extBox are placed *n the :orm a# !ell) The +eth*d# 'dd'nd#elect+ext( ) and *eset#election'nd:ont( ) are u#ed 3y the vari*u# event handler#) -n 'dd'nd#elect+ext( ) the te;t t* 3e in#erted i# taken 9r*+ the +extBox tb and a ne!line added) The current rtb6#election#tart i# re+e+3ered, the ne! te;t appended t* the *ich+extBox, and the #electi*n i# #et t* 3egin !ith the re+e+3ered insertion!oint and #electionLength t* the length *9 the in#erted te;t) *eset#election'nd:ont( ) #et# the in#erti*n p*int at the end *9 the te;t 3y giving it an i+p*##i3ly high value) The #electi*n i# re#et t* u#e the de9ault 9*nt G0* pt) Cerdana in 3lackH u#ing the appr*priate pr*pertie#) The vari*u# event handler# call 'dd'nd#elect+ext( ) and then +anipulate vari*u# a#pect# *9 the #elected te;t P di99erent #i7e#, c*l*r#, and 9*nt# are rand*+ly ch*#en)

65)

Thinking in C

www.ThinkingIn.!et

Lin*ing -e&t
-n the pa#t decade, hyperte;t ha# g*ne 9r*+ an e#*teric t*pic t* pr*3a3ly the d*+inant 9*r+ *9 hu+anEc*+puter interacti*n) H*!ever, inc*rp*rating te;t link# int* a U- ha# 3een a 3ig challenge) ,ind*!# 5*r+# change# that !ith it# Lin(Label c*ntr*l) The Lin(Label ha# p*!er9ul #upp*rt 9*r linking, all*!ing any nu+3er *9 link# !ithin the la3el area) The Lin(Label 9acilitate# the creati*n *9 even c*+ple; linking #e+antic#, #uch a# the BLink #tandard G!!!)!/)*rg<TR<;link<H) ,hile it# p*##i3le t* u#e a Lin(Label t* activate *ther ,ind*!# 5*r+# 3ehavi*r, the +*#t c*++*n u#e i# likely t* 3e activating the 9ullE9eatured ,e3 3r*!#er) T* d* that, !e need t* intr*duce the !rocess cla## 9r*+ the #ystem6$iagnostics na+e#pace) The !rocess cla## pr*vide# th*r*ugh acce## t* l*cal and re+*te pr*ce##e#, 3ut the c*re 9uncti*nality i# #tarting a l*cal pr*ce##, i)e), launching an*ther applicati*n !hile y*ur applicati*n c*ntinue# t* run G*r #hut# d*!n P the launched pr*ce## i# independent *9 y*ur applicati*nH) There are three *verl*aded ver#i*n# *9 !rocess6#tart( ) that pr*vide vari*u# degree# *9 c*ntr*l *ver the launched applicati*n) The +*#t 3a#ic !rocess6#tart( ) +eth*d 4u#t take# a string and u#e# the OS# underlying +echani#+ t* deter+ine the appr*priate !ay t* run the reDue#tQ i9 the #tring #peci9ie# a n*nEe;ecuta3le 9ile, the e;ten#i*n +ay 3e a##*ciated !ith a pr*gra+ and, i9 #*, that pr*gra+ !ill *pen it) 5*r in#tance, !rocess#tart(G:oo6csG) !ill *pen the edit*r a##*ciated !ith the 6cs e;ten#i*n) The +*#t advanced !rocess6#tart( ) take# a !rocess#tartBnfo in9*) !rocess#tartBnfo c*ntain# pr*pertie# 9*r #etting envir*n+ent varia3le#, !hether a !ind*! #h*uld 3e #h*!n and in !hat #tyle, input and *utput redirecti*n, etc) Thi# e;a+ple u#e# the third *verl*ad *9 !rocess6#tart( ), !hich take# an applicati*n na+e and a #tring repre#enting the c*++andEline argu+ent#, t* launch -nternet E;pl*rer and #ur9 t* !!!)Thinking-n) et) //:c"T:Lin%La$e :e!o.c# //:e!on#trate# the Lin%La$e u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.:iagno#tic#3

Cha"ter 13* Creating Gindows = 5""lets

653

u#ing Sy#te!.Vindo.#.Hor!#3 c a## Lin%La$e :e!o : Hor! ; Lin%La$e :e!o01; Lin%La$e a$e " 9 ne. Lin%La$e 013 a$e ".'ext 9 &:o.n oad 'hin%ing in C(&3 a$e ".Lin%#.)dd0>2 "E2 &http://....thin%ingin.net/&13 a$e ".Lin%C ic%ed R9 ne. Lin%La$e Lin%C ic%ed+*entUand er0 5nternet+xp orerLaunch13 a$e ".Location 9 ne. -oint0"02 "013 a$e ".SiMe 9 ne. SiMe0"?02 T013 Contro #.)dd0 a$e "13 Lin%La$e a$e 2 9 ne. Lin%La$e 013 a$e 2.'ext 9 &Sho. !e##age&3 a$e 2.Lin%#.)dd002 E2 &Hoo&13 a$e 2.Lin%#.)dd0P2 I2 &Bar&13 a$e 2.Lin%C ic%ed R9 ne. Lin%La$e Lin%C ic%ed+*entUand er0 Ge##ageBoxSho.13 a$e 2.Location 9 ne. -oint0"02 ?013 Contro #.)dd0 a$e 213 < pu$ ic *oid 5nternet+xp orerLaunch 0o$Dect #rc2 Lin%La$e Lin%C ic%ed+*ent)rg# e1; #tring ur 9 0#tring1 e.Lin%.Lin%:ata3 -roce##.Start0&5+xp ore.exe&2 ur 13 e.Lin%.Ni#ited 9 true3 < pu$ ic *oid Ge##ageBoxSho. 0o$Dect #rc2 Lin%La$e Lin%C ic%ed+*ent)rg# e1; #tring !#g 9 0#tring1 e.Lin%.Lin%:ata3 Ge##ageBox.Sho.0!#g13 e.Lin%.Ni#ited 9 true3 < pu$ ic #tatic *oid Gain01;

654

Thinking in C

www.ThinkingIn.!et

)pp ication.Run0ne. Lin%La$e :e!o0113 < <//:8 *t all the Lin(Label6+ext need 3e a linkQ individual link# are added t* the Lin(s c*llecti*n 3y #peci9ying an *99#et and the length *9 the link) -9 y*u d* n*t need any in9*r+ati*n *ther than the 9act that the link !a# clicked, y*u d* n*t need t* include the third argu+ent t* Lin(s6'dd( ), 3ut typically y*u !ill #t*re #*+e data t* 3e u#ed 3y the event handler) -n the e;a+ple, the phra#e IThinking in C#J i# pre#ented underlined, in the c*l*r *9 the Lin(Color pr*perty G3y de9ault, thi# i# #et 3y the #y#te+ and i# u#ually 3lueH) Thi# link ha# a# it# a##*ciated data, a URL) Label8 ha# t!* link# !ithin it, *ne a##*ciated !ith the string I9**J and the *ther !ith I3ar)J ,hile a Lin(Label can have +any link#, all the link# #hare the #a+e event handler G*9 c*ur#e, it# a +ultica#t delegate, #* y*u can add a# +any +eth*d# t* the event handling chain a# de#ired, 3ut y*u cann*t directly a##*ciated a #peci9ic eventEhandling +eth*d !ith a #peci9ic linkH) The Lin( i# pa##ed t* the event handler via the event argu+ent#, #* the delegate i# the de#criptively na+ed Lin(LabelLin(Clic(ed&vent"andler) The Lin($ata Gi9 it !a# #peci9ied in the Lin(# c*n#truct*rH can 3e any ob)ect) -n the e;a+ple, !e d*!nca#t the Lin($ata t* string) The Bnternet&xplorerLaunch( ) +eth*d u#e# !rocess6#tart( ) t* launch Aicr*#*9t# ,e3 3r*!#er) .essageBox#how( ) de+*n#trate# the c*nvenient .essageBox cla##, !hich p*p# up a #i+ple alert dial*g) =t the end *9 the event handler#, the appr*priate Lin( i# #et t* Hisited, !hich redra!# the link in the Lin(Label)HisitedLin(Color)

Chec*+o&es and 6adio3uttons


=# 3rie9ly +enti*ned in the Bnternational e;a+ple, radi* 3utt*n# in ,ind*!# 5*r+# have the #i+ple +*del *9 3eing +utually e;clu#ive !ithin their c*ntaining Controls c*llecti*n) S*+eti+e# it i# #u99icient t* 4u#t plunk #*+e radi* 3utt*n# d*!n *n a :orm and 3e d*ne !ith it, 3ut

Cha"ter 13* Creating Gindows = 5""lets

655

u#ually y*u !ill u#e a !anel *r roupBox t* c*ntain a #et *9 l*gically related radi* 3utt*n# G*r *ther c*ntr*l#H) U#ually, a #et *9 related *adioButton# #h*uld have the #a+e event handler #ince generally the pr*gra+ need# t* kn*! I,hich *9 the radi* 3utt*n# in the gr*up i# #electedFJ Since &vent"andler delegate# pa## the #*urce ob)ect a# the 9ir#t para+eter in their argu+ent#, it i# ea#y 9*r a gr*up *9 3utt*n# t* #hare a #ingle delegate +eth*d and u#e the src argu+ent t* deter+ine !hich 3utt*n ha# 3een activated) The u#e *9 a roupBox and thi# 9*r+ *9 #haring a delegate +eth*d i# de+*n#trated in the ne;t e;a+ple) Chec(Box c*ntr*l# are n*t +utually e;clu#iveQ any nu+3er can 3e in any #tate !ithin a c*ntainer) Chec(Boxe# cycle 3et!een t!* #tate# GChec(#tate6Chec(ed and Chec(#tate6Vnchec(edH 3y de9ault, 3ut 3y #etting the +hree#tate pr*perty t* true, can cycle 3et!een Chec(ed, Vnchec(ed, and Chec(#tate6Bndeterminate) Thi# e;a+ple de+*n#trate# a #tandard Chec(Box, *ne that u#e# an Bmage in#tead *9 te;t Glike Button# and +any *ther Control#, the de9ault appearance can 3e changed u#ing a variety *9 pr*pertie#H, a threeE #tate Chec(Box, and gr*uped, delegateE#haring *adioButton#1 //:c"T:Chec%)ndRadio.c# //:e!on#trate# *ariou# type# of $utton# u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 u#ing Sy#te!.:ra.ing3 c a## Chec%)ndRadio : Hor! ; Chec%)ndRadio01 ; C ientSiMe 9 ne. Sy#te!.:ra.ing.SiMe0E002 20013 'ext 9 &Chec%$oxe# and Radio Button#&3 Chec%Box #i!p e 9 ne. Chec%Box013 #i!p e.'ext 9 &Si!p e&3 #i!p e.Location 9 ne. -oint0"02 "013 #i!p e.C ic% R9 ne. +*entUand er0OnSi!p eChec%BoxC ic%13 Chec%Box i!age 9 ne. Chec%Box013

656

Thinking in C

www.ThinkingIn.!et

i!age.5!age 9 5!age.Hro!Hi e0&.^^'iC.gif&13 i!age.Location 9 ne. -oint0"202 "013 i!age.C ic% R9 ne. +*entUand er0OnSi!p eChec%BoxC ic%13 Chec%Box threeState 9 ne. Chec%Box013 threeState.'ext 9 &'hree #tate&3 threeState.'hreeState 9 true3 threeState.Location 9 ne. -oint02T02 "013 threeState.C ic% R9 ne. +*entUand er0On'hreeStateChec%BoxC ic%13 -ane r$-ane 9 ne. -ane 013 r$-ane .Location 9 ne. -oint0"02 P013 r$-ane .SiMe 9 ne. SiMe0E202 P013 r$-ane .)utoScro 9 true3 RadioButton f" 9 ne. RadioButton013 f".'ext 9 &Nani a&3 f".Location 9 ne. -oint002 "013 f".Chec%edChanged R9 ne. +*entUand er0OnRadioButtonChange13 RadioButton f2 9 ne. RadioButton013 f2.'ext 9 &Choco ate&3 f2.Location 9 ne. -oint0"E02 "013 f2.Chec%edChanged R9 ne. +*entUand er0OnRadioButtonChange13 RadioButton fT 9 ne. RadioButton013 fT.'ext 9 &Chun%y Gon%ey&3 fT.Location 9 ne. -oint 02I02 "013 fT.Chec%edChanged R9 ne. +*entUand er0OnRadioButtonChange13 fT.Chec%ed 9 true3 r$-ane .Contro #.)ddRange0 ne. Contro JK; f"2 f22 fT<13 Contro #.)ddRange0 ne. Contro JK; #i!p e2 i!age2 threeState2 r$-ane <13 <

Cha"ter 13* Creating Gindows = 5""lets

65#

pri*ate *oid OnSi!p eChec%BoxC ic%0 o$Dect #ender2 +*ent)rg# arg#1; Chec%Box c$ 9 0Chec%Box1 #ender3 Sy#te!.Con#o e.VriteLine0 c$.'ext R & i# & R c$.Chec%ed13 < pri*ate *oid On'hreeStateChec%BoxC ic%0 o$Dect #ender2 +*ent)rg# arg#1; Chec%Box c$ 9 0Chec%Box1 #ender3 Sy#te!.Con#o e.VriteLine0 c$.'ext R & i# & R c$.Chec%State13 < pri*ate *oid OnRadioButtonChange0 o$Dect #ender2 +*ent)rg# arg#1; RadioButton r$ 9 0RadioButton1 #ender3 if 0r$.Chec%ed 99 true1 Sy#te!.Con#o e.VriteLine0 &H a*or i# & R r$.'ext13 < pu$ ic #tatic *oid Gain01 ; )pp ication.Run0ne. Chec%)ndRadio0113 < <//:8

List. Co#+o. and Chec*edList3o&es


Radi* 3utt*n# and check 3*;e# are appr*priate 9*r #electing a+*ng a #+all nu+3er *9 ch*ice#, 3ut the ta#k *9 #electing 9r*+ larger #et# *9 *pti*n# i# the !*rk *9 the ListBox, the ComboBox, and the Chec(edListBox) Thi# e;a+ple #h*!# the 3a#ic u#e *9 a ListBox) Thi# ListBox all*!# 9*r *nly a #ingle #electi*n t* 3e ch*#en at a ti+eQ i9 the #election.ode pr*perty i# #et t* .ulti#imple *r .ulti&xtended, +ultiple ite+# can

65&

Thinking in C

www.ThinkingIn.!et

3e ch*#en G.ulti&xtended #h*uld 3e u#ed t* all*! SH-5T, CTRL, and arr*! #h*rtcut#H) -9 the #electi*n +*de i# #election.ode6#ingle, the Btem pr*perty c*ntain# the *neEandE*nly #elected ite+, 9*r *ther +*de# the Btems pr*perty i# u#ed) //:c"T:Li#tBox:e!o.c# //:e!on#trate# Li#tBox #e ection u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Li#tBox:e!o : Hor!; Li#tBox:e!o01; Li#tBox $ 9 ne. Li#tBox013 for0int i 9 03 i W "03 iRR1; $.5te!#.)dd0i.'oString0113 < $.Location 9 ne. -oint0"02 "013 $.Se ectedNa ueChanged R9 ne. +*entUand er0OnSe ect13 Contro #.)dd0 $13 < pu$ ic *oid OnSe ect0o$Dect #rc2 +*ent)rg# ea1; Li#tBox $ 9 0Li#tBox1 #rc3 Con#o e.VriteLine0 $.Se ected5te!13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Li#tBox:e!o0113 < <///:8 The ComboBox i# #i+ilarly ea#y t* u#e, alth*ugh it can *nly 3e u#ed 9*r #ingle #electi*n) Thi# e;a+ple de+*n#trate# the ComboBox, including it# a3ility t* #*rt it# *!n c*ntent#1 //:c"T:Co!$oBox:e!o.c# ///:e!on#trate# the Co!$oBox u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3

Cha"ter 13* Creating Gindows = 5""lets

65'

c a## Co!$oBox:e!o : Hor! ; Co!$oBox pre#ident#3 Chec%Box #orted3 Co!$oBox:e!o01 ; C ientSiMe 9 ne. SiMe0T202 20013 'ext 9 &Co!$oBox :e!o&3 pre#ident# 9 ne. Co!$oBox013 pre#ident#.Location 9 ne. -oint0"02 "013 pre#ident#.5te!#.)ddRange0 ne. #tringJK; &Va#hington&2 &)da!# `&2 &`effer#on&2 &Gadi#on&2 &Gonroe&2 &)da!#2 `Q&2 &`ac%#on&2 &Nan Buren&2 &Uarri#on&2 &'y er&2 &-o %&2 &'ay or&2 &Hi !ore&2 &-ierce&2 &Buchanan&2 &Linco n&2 &`ohn#on )&2 &_rant&2 &Uaye#&2 &_arfie d&2 &)rthur&2 &C e*e and&2 &Uarri#on&2 &Gcain ey&2 &Roo#e*e t '&2 &'aft&2 &Vi #on&2 &Uarding&2 &Coo idge&2 &Uoo*er&2 &Roo#e*e t H:&2 &'ru!an&2 &+i#enho.er&2 &aennedy&2 &`ohn#on LB&2 &Cixon&2 &Hord&2 &Carter&2 &Reagan&2 &Bu#h _&2 &C inton&2 &Bu#h _V&<13 pre#ident#.Se ected5ndexChanged R9 ne. +*entUand er0On-re#identSe ected13 #orted 9 ne. Chec%Box013 #orted.'ext 9 &) pha$etica y #orted&3 #orted.Chec%ed 9 fa #e3 #orted.C ic% R9 ne. +*entUand er0ConRe*er#i$ eSort13 #orted.Location 9 ne. -oint0"P02 "013 Button $tn 9 ne. Button013 $tn.'ext 9 &Read #e ected&3 $tn.C ic% R9 ne. +*entUand er0_et-re#ident13 $tn.Location 9 ne. -oint0"P02 P013 Contro #.)ddRange0

66(

Thinking in C

www.ThinkingIn.!et

ne. Contro JK;pre#ident#2 #orted2 $tn<13 < pri*ate *oid ConRe*er#i$ eSort 0o$Dect #ender2 +*ent)rg# arg#1 ; //$ug2 #ince non6re*er#i$ e pre#ident#.Sorted 9 #orted.Chec%ed3 < pri*ate *oid On-re#identSe ected 0o$Dect #ender2 +*ent)rg# arg#1 ; int #e 5dx 9 pre#ident#.Se ected5ndex3 if 0#e 5dx Z 6"1 ; Sy#te!.Con#o e.VriteLine0 &Se ected pre#ident i#: & R pre#ident#.5te!#J#e 5dxK13 < e #e ; Sy#te!.Con#o e.VriteLine0 &Co pre#ident i# #e ected&13 < < pri*ate *oid _et-re#ident 0o$Dect #ender2 +*ent)rg# arg#1 ; //:oe#n't .or%2 #ince can $e $ an% // or gar$age *a ue Sy#te!.Con#o e.VriteLine0pre#ident#.'ext13 //So you ha*e to do #o!ething i%e thi#... #tring #ugge#tion 9 pre#ident#.'ext3 if0pre#ident#.5te!#.Contain#0#ugge#tion11; Sy#te!.Con#o e.VriteLine0 &Se ected pre#ident i#: & R #ugge#tion13 <e #e; Sy#te!.Con#o e.VriteLine0 &Co pre#ident i# #e ected&13 < < pu$ ic #tatic *oid Gain01 ; )pp ication.Run0ne. Co!$oBox:e!o0113 <

Cha"ter 13* Creating Gindows = 5""lets

661

<//:8 =9ter the na+e# *9 the pre#ident# are l*aded int* the ComboBox, a 9e! handler# are de9ined1 the check 3*; !ill trigger ,on*eversible#ort( ) and the 3utt*n !ill trigger et!resident( )) The i+ple+entati*n *9 ,on*eversible#ort( ) #et# the ComboBox# #orted pr*perty depending *n the #electi*n #tate *9 the sorted Chec(box) Thi# i# a de9ect a#, *nce #*rted, #etting the #orted pr*perty t* false !ill not return the ComboBox t* it# *riginal chr*n*l*gicallyE*rdered #tate) et!resident( ) reveal# an*ther Duirk) The value *9 ComboBox6+ext i# the value *9 the edita3le 9ield in the ComboBox, even i9 n* value ha# 3een ch*#en, *r i9 the u#er ha# typed in n*nEvalid data) -n *rder t* c*n9ir+ that the data in ComboBox6+ext i# valid, y*u have t* #earch the Btems c*llecti*n 9*r the te;t, a# de+*n#trated) The Chec(edListBox i# the +*#t c*+ple; *9 the li#tE#electi*n c*ntr*l#) Thi# e;a+ple let# y*u #peci9y y*ur +u#ical ta#te#, printing y*ur like# and di#like# t* the C*n#*le) //:c"T:Chec%edLi#tBox:e!o.c# ///:e!on#trate# the Chec%edLi#tBox u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Chec%edLi#tBox:e!o : Hor! ; Chec%edLi#tBox !u#ica 'a#te#3 Chec%edLi#tBox:e!o01; C ientSiMe 9 ne. SiMe0T202 20013 'ext 9 &Chec%edLi#tBox :e!o&3 !u#ica 'a#te# 9 ne. Chec%edLi#tBox013 !u#ica 'a#te#.Location 9 ne. -oint0"02 "013 !u#ica 'a#te#.5te!#.)dd0 &C a##ica &2 Chec%State.5ndeter!inate13 !u#ica 'a#te#.5te!#.)dd0 &`aMM&2 Chec%State.5ndeter!inate13 !u#ica 'a#te#.5te!#.)ddRange0 ne. #tringJK; &B ue#&2 &Roc%&2

66)

Thinking in C

www.ThinkingIn.!et

&-un%&2 &_runge&2 &Uip hop&<13 Ga%e) 5ndeter!inate013

Button get'a#te# 9 ne. Button013 get'a#te#.Location 9 ne. -oint02002 "013 get'a#te#.Vidth 9 "003 get'a#te#.'ext 9 &_et ta#te#&3 get'a#te#.C ic% R9 ne. +*entUand er0On_et'a#te#13 Contro #.)dd0!u#ica 'a#te#13 Contro #.)dd0get'a#te#13 < pri*ate *oid Ga%e) 5ndeter!inate01; Chec%edLi#tBox.O$DectCo ection ite!# 9 !u#ica 'a#t#.5te!#3 for 0int i 9 03 i W ite!#.Count3 iRR1 ; !u#ica 'a#te#.Set5te!Chec%State0i2 Chec%State.5ndeter!inate13 < < pri*ate *oid On_et'a#te#0o$Dect o2 +*ent)rg# arg#1; //Return# chec%ed X)C:X indeter!inate! Chec%edLi#tBox.Chec%ed5ndexCo ection chec%ed5ndice# 9 !u#ica 'a#te#.Chec%ed5ndice#3 foreach0int i in chec%ed5ndice#1; if 0!u#ica 'a#te#._et5te!Chec%State0i1 !9 Chec%State.5ndeter!inate1 ; Sy#te!.Con#o e.VriteLine0 &Li%e#: & R !u#ica 'a#te#.5te!#JiK13 < < //Or2 to iterate o*er the .ho e co ection for 0int i 9 03 i W !u#ica 'a#te#.5te!#.Count3 iRR1 ; if 0!u#ica 'a#te#._et5te!Chec%State0i1 99 Chec%State.Onchec%ed1 ;

Cha"ter 13* Creating Gindows = 5""lets

663

Sy#te!.Con#o e.VriteLine0 &:i# i%e: & R !u#ica 'a#te#.5te!#JiK13 < < < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Chec%edLi#tBox:e!o0113 < <//:8 The Chec(edListBox$emo( ) c*n#truct*r #h*!# that ite+# can 3e added either *ne at a ti+e, !ith their Chec(#tate pr*perty de9ined, *r en +a##e) The 1n et+astes( ) +eth*d #h*!# a de9ect in the Chec(edListBox c*ntr*lQ the Chec(edBndices pr*perty return# n*t 4u#t th*#e ite+# !ith Chec(#tate6Chec(ed, 3ut al#* th*#e !ith Chec(#tate6BndeterminateK =n e;plicit check +u#t 3e added t* +ake #ure that the value at the inde; really is checked) Once an appr*priate inde; i# in hand, the value can 3e retrieved 3y u#ing the Btems< > array *perat*r)

@ulti$lane dis$la5s with the Splitter control


-t i# *9ten de#ira3le t* all*! the u#er t* change the pr*p*rti*n *9 a !ind*! dev*ted t* vari*u# l*gical gr*up#Q !ind*!# !ith #uch #plit# are *9ten #aid t* 3e divided int* +ultiple Ipane#)J The #plitter c*ntr*l all*!# the u#er t* re#i7e c*ntr*l# +anually) ,e di#cu##ed the u#e *9 roupBox a# *ne !ay t* l*gically gr*up c*ntr*l# #uch a# *adioButton#) = +*re generalEpurp*#e gr*uping c*ntr*l i# the !anel, !hich 3y de9ault i# invi#i3le) By placing l*gically related Control# *n a !anel, and then a##*ciating a #plitter !ith the !anel, +ultipane U-# can 3e created ea#ily) = #plitter i# a##*ciated !ith a Control via the $oc( pr*perty P the #plitter re#i7e# the Control placed i++ediately a$ter it in the c*ntainer) The Control t* 3e re#i7ed and the #plitter #h*uld 3e a##igned the #a+e $oc( value)

664

Thinking in C

www.ThinkingIn.!et

-n thi# e;a+ple, !e u#e !anel# that !e +ake vi#i3le 3y #etting their Bac(Color pr*pertie#) //:c"T:Sp itter:e!o.c# u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Sp itter:e!o : Hor!; Sp itter:e!o01; -ane r 9 ne. -ane 013 r.Bac%Co or 9 Co or.Red3 r.:oc% 9 :oc%Sty e.Left3 r.Vidth 9 2003 -ane g 9 ne. -ane 013 g.Bac%Co or 9 Co or._reen3 g.:oc% 9 :oc%Sty e.Hi 3 -ane $ 9 ne. -ane 013 $.Bac%Co or 9 Co or.B ue3 $.:oc% 9 :oc%Sty e.Right3 $.Vidth 9 2003 Sp itter rg 9 ne. Sp itter013 //Set doc% to #a!e a# re#iMed contro rg.:oc% 9 :oc%Sty e.Left3 Sp itter g$ 9 ne. Sp itter013 //Set doc% to #a!e a# re#iMed contro g$.:oc% 9 :oc%Sty e.Right3 Contro #.)dd0g13 //Sp itter added X$eforeX pane Contro #.)dd0g$13 Contro #.)dd0$13 //Sp itter added X$eforeX pane Contro #.)dd0rg13 Contro #.)dd0r13 0p"1

0pT1

Cha"ter 13* Creating Gindows = 5""lets

665

Vidth 9 ?E03 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Sp itter:e!o0113 < <//:8 =9ter creating panel# r, g, and b and #etting their Bac(Color# appr*priately, !e create a #plitter rg !ith the #a+e $oc( value a# the r !anel and an*ther called gb !ith the #a+e $oc( value a# b) -t i# critical that the #plitter# are added t* the :orm i++ediately pri*r t* the !anel# they re#i7e) The e;a+ple #tart# !ith r and b at their pre9erred =idth *9 2$$ pi;el#, !hile the entire :orm i# #et t* take .&$) H*!ever, y*u can re#i7e the !anel# +anually)

-ree8iew I List8iew
Every*ne #ee+# t* have a di99erent idea *9 !hat the ideal +reeHiew c*ntr*l #h*uld l**k like and every di#cu##i*n gr*up 9*r every U- t**lkit i# regularly #!a+ped !ith the intricacie# *9 +reeHiew pr*gra++ing) ,ind*!# 5*r+# i# n* e;cepti*n, 3ut the general ea#e *9 pr*gra++ing ,ind*!# 5*r+# +ake# 3a#ic +reeHiew pr*gra++ing 9airly #traight9*r!ard) The c*re c*ncept *9 the +reeHiew i# that a +reeHiew c*ntain# +ree,odes, !hich in turn c*ntain *ther +ree,odes) Thi# +*del i# e##entially the #a+e a# the ,ind*!# 5*r+# +*del in !hich Control# c*ntain *ther Control#) S* 4u#t a# y*u #tart !ith a :orm and add Control# and Control# t* th*#e Control#, #* t** y*u create a +reeHiew and add +ree,ode# and +ree,ode# t* th*#e +ree,ode#) H*!ever, the general pr*gra++ing +*del 9*r ,ind*!# 5*r+# i# that event# are a##*ciated !ith the piece# that +ake up the !h*le Gthe Control# !ithin their c*ntainer#H, !hile the pr*gra++ing +*del 9*r the +reeHiew i# that event# are a##*ciated !ith the !h*leQ +ree,ode# have n* event#) Thi# e;a+ple #h*!# the #i+ple#t p*##i3le u#e *9 +reeHiew)

666

Thinking in C

www.ThinkingIn.!et

//:c"T:'reeNie.:e!o".c# //:e!on#trate# 'reeNie. contro u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## 'reeNie.:e!o" : Hor!; 'reeNie.:e!o"01; 'reeNie. t* 9 ne. 'reeNie.013 'reeCode root 9 ne. 'reeCode0&Hi#h&13 'reeCode cart 9 ne. 'reeCode0&Shar%# @ Ray#&13 'reeCode $ony 9 ne. 'reeCode0&Bony fi#he#&13 t*.Code#.)dd0root13 root.Code#.)dd0cart13 root.Code#.)dd0$ony13 t*.)fterSe ect R9 ne. 'reeNie.+*entUand er0)fterSe ectUand er13 Contro #.)dd0t*13 < pu$ ic *oid )fterSe ectUand er 0o$Dect #rc2 'reeNie.+*ent)rg# a1; 'reeCode #e 9 00'reeNie.1 #rc1.Se ectedCode3 Sy#te!.Con#o e.VriteLine0#e 13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. 'reeNie.:e!o"0113 < <//:8 -n the c*n#truct*r, a9ter a +reeHiew c*ntr*l i# initiali7ed, three +ree,ode# are created) The root n*de i# added t* the ,odes c*llecti*n *9 the +reeHiew) The 3ranch n*de# cart and bony are added t* the ,odes c*llecti*n, n*t *9 the +reeHiew, 3ut *9 the root n*de) = +reeHiew&vent"andler delegate i# created t* *utput the value *9 the #elected n*de t* the C*n#*le) The delegate i# added t* the +reeHiew# 'fter#elect event P the +reeHiew ha# a d*7en uniDue event# relating t* n*de #electi*n, c*llap#ing and e;panding, and change# t* the ite+# check3*; Git#el9 an *pti*nal pr*pertyH)

Cha"ter 13* Creating Gindows = 5""lets

66#

List8iew
ListHiew +ay 9inally replace +reeHiew a# I+*#t di#cu##ed U- !idget)J The ListHiew i# an in#anely cu#t*+i7a3le !idget that i# #i+ilar t* the rightEhand #ide *9 ,ind*!# E;pl*rer P ite+# placed !ithin a ListHiew can 3e vie!ed in a detail vie!, a# a li#t, and a# grid# *9 large *r #+all ic*n#) Like the +reeHiew, the ListHiew u#e# a 3a#ic c*ntain+ent +*del1 a +reeHiew c*ntain# a c*llecti*n *9 ListHiewBtem# !hich d* n*t the+#elve# have event#) The ListHiewBtem# are added t* the Btems pr*perty *9 the ListHiew) Cari*u# pr*pertie# *9 the ListHiew and the individual ListHiewBtem# c*ntr*l the vari*u# di#play#)

Icon 8iews
The ListHiew c*ntain# t!* BmageList#, !hich h*ld ic*n# G*r *ther #+all graphic#H that can 3e a##*ciated !ith di99erent type# *9 ListHiewBtem#) One BmageList #h*uld 3e a##igned t* the #mallBmageList and the *ther t* the LargeBmageList pr*perty *9 the ListHiew) C*rre#p*nding i+age# #h*uld 3e added t* 3*th BmageList# at the #a+e *99#et#, #ince the #electi*n *9 either BmageList i# deter+ined 3y the ListHiewBtem# BmageBndex pr*perty) -n *ther !*rd#, i9 the ListHiewBtem6BmageBndex i# #et t* /, i9 ListHiew6Hiew i# #et t* ListHiew6LargeBcon the &th i+age in LargeBmageList !ill 3e di#played 9*r that ListHiewBtem, !hile i9 ListHiew6Hiew II Hiew6#mallBcon, the &th i+age in #mallBmageList !ill 3e di#played)

4etails 8iew
The detail# vie! *9 a ListHiew c*n#i#t# *9 a #erie# *9 c*lu+n#, the 9ir#t *9 !hich di#play# the ListHiewBtem and it# a##*ciated ic*n 9r*+ the #mallBmageList) Su3#eDuent c*lu+n# di#play te;t de#cri3ing vari*u# a#pect# related t* the ListHiewBtem) The te;t di#played 3y the 2nd and #u3#eDuent c*lu+n# i# deter+ined 3y the c*llecti*n *9 ListHiew#ubBtem# in the ListHiewBtem# #ubBtems pr*perty) The c*lu+n header te;t i# #et !ith the ListHiew6Columns pr*perty) The pr*gra++er i# re#p*n#i3le 9*r c**rdinating the c*n#i#tency *9 c*lu+n header *99#et# and the indice# *9 ListHiew#ubBtem#)

66&

Thinking in C

www.ThinkingIn.!et

Thi# e;a+ple de+*n#trate# the ListHiew# vari*u# +*de#) //:c"T:Li#tNie.:e!o.c# //:e!on#trate# the Li#tNie. contro u#ing Sy#te!3 u#ing Sy#te!.5O3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Li#tNie.:e!o : Hor!; Li#tNie. *3 Li#tNie.:e!o01; //Set up contro pane -ane p 9 ne. -ane 013 RadioButtonJK $tn 9 ne. RadioButtonJK; ne. RadioButton012 ne. RadioButton012 ne. RadioButton012 ne. RadioButton01 <3 $tnJ0K.Chec%ed 9 true3 $tnJ0K.'ext 9 &:etai #&3 $tnJ"K.'ext 9 &Large 5con#&3 $tnJ2K.'ext 9 &Li#t&3 $tnJTK.'ext 9 &S!a 5con#&3 for0int i 9 03 i W E3 iRR1; $tnJiK.Location 9 ne. -oint0"02 20 = 0i R "113 $tnJiK.Chec%edChanged R9 ne. +*entUand er0Se ectNie.13 < p.Contro #.)ddRange0$tn13 p.:oc% 9 :oc%Sty e.Left3 p.Vidth 9 "003 Sp itter # 9 ne. Sp itter013 #.:oc% 9 :oc%Sty e.Left3 //Li#tNie. initia #tuff * 9 ne. Li#tNie.013 *.:oc% 9 :oc%Sty e.Hi 3

Cha"ter 13* Creating Gindows = 5""lets

66'

*.Co u!n#.)dd0 &Hi e Ca!e&2 "P02 UoriMonta ) ign!ent.Left13 *.Co u!n#.)dd0 &SiMe&2 "P02 UoriMonta ) ign!ent.Left13 *.Nie. 9 Nie..:etai #3 //Load i!age# 5!age #!a CS 9 5!age.Hro!Hi e0&c#X#!.$!p&13 5!age #!a +xe 9 5!age.Hro!Hi e0&exeX#!.$!p&13 5!ageLi#t i 9 ne. 5!ageLi#t013 i .5!age#.)dd0#!a CS13 i .5!age#.)dd0#!a +xe13 *.S!a 5!ageLi#t 9 i 3 5!age argeCS 9 5!age.Hro!Hi e0&c#X rg.$!p&13 5!age arge+xe 9 5!age.Hro!Hi e0&exeX rg.$!p&13 5!ageLi#t i 2 9 ne. 5!ageLi#t013 i 2.5!age#.)dd0 argeCS13 i 2.5!age#.)dd0 arge+xe13 *.Large5!ageLi#t 9 i 23 :irectory5nfo dir 9 ne. :irectory5nfo0&.&13 foreach0Hi e5nfo f in dir._etHi e#0&=.=&11; #tring fCa!e 9 f.Ca!e3 #tring #iMe 9 f.Length.'oString013 #tring ext 9 f.+xten#ion3 Li#tNie.5te! ite! 9 ne. Li#tNie.5te!0fCa!e13 if0ext 99 &.c#&1; ite!.5!age5ndex 9 03 <e #e; ite!.5!age5ndex 9 "3 < ite!.Su$5te!#.)dd0#iMe13 *.5te!#.)dd0ite!13 < Contro #.)dd0 *13 Contro #.)dd0#13 Contro #.)dd0p13 Vidth 9 ?E03

6#(

Thinking in C

www.ThinkingIn.!et

< pu$ ic *oid Se ectNie.0O$Dect #rc2 +*ent)rg# ea1; RadioButton r$ 9 0RadioButton1 #rc3 #tring *ie.:e#ired 9 r$.'ext3 #.itch0*ie.:e#ired1; ca#e &:etai #& : *.Nie. 9 Nie..:etai #3 $rea%3 ca#e &Large 5con#& : *.Nie. 9 Nie..Large5con3 $rea%3 ca#e &Li#t& : *.Nie. 9 Nie..Li#t3 $rea%3 ca#e &S!a 5con#& : *.Nie. 9 Nie..S!a 5con3 $rea%3 < < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Li#tNie.:e!o0113 < <//:8 The ListHiew$emo( ) c*n#truct*r de9ine# a !anel and *adioButton array t* #elect the vari*u# ListHiew6Hiew value#) = #plitter i# al#* de9ined t* all*! thi# panel t* 3e re#i7ed) The ListHiew lv i# created and it# $oc( pr*perty #et t* $oc(#tyle6:ill) ,e #peci9y that !hen the ListHiew i# #!itched t* detail# vie!, the t!* c*lu+n# !ill 3e la3eled I5ile a+eJ and ISi7e,J each !ill initially 3e 0'$ pi;el# !ide, and each !ill di#play it# te;t le9tEaligned) ,e then #et lv# initial vie! #tate t*, in 9act, 3e Hiew6$etails) The ne;t #ecti*n *9 the c*n#truct*r, la3eled IL*ad-+age#,J l*ad# #+all and then larger i+age#, and place# the c*rre#p*nding i+age# GcsAsm6bmp and csAlrg6bmp and exeAsm6bmp and exeAlrg6bmpH in BmageList# !hich are a##igned t* the ListHiew# #mallBmageList and LargeBmageList pr*pertie#)

Cha"ter 13* Creating Gindows = 5""lets

6#1

The ListHiew i# p*pulated !ith the 9ile# in the current direct*ry) 5*r each 9ile 9*und, !e deter+ine the na+e, 9ile length, and e;ten#i*n and create a ListHiewBtem !ith it# I+ainJ +ext #et t* the 9ile# na+e) -9 the e;ten#i*n i# I)c#J !e #et that ListHiewBtem# BconBndex t* c*rre#p*nd t* the C# i+age# in the ListHiew# BmageList#, *ther!i#e !e #et the inde; t* 0) The string value repre#enting the 9ile# length i# added t* the #ubBtems c*llecti*n *9 the ListHiewBtem) The ListHiewBtem it#el9 i# al!ay# the $irst ite+ in the #ubBtems li#tQ in thi# ca#e that !ill appear in the I5ile a+eJ c*lu+n *9 the +reeHiew) The siTe #tring !ill appear in the second c*lu+n *9 the +reeHiew, under the ISi7eJ heading) The la#t p*rti*n *9 the c*n#truct*r add# the Control# t* the ListHiew$emo 9*r+ in the appr*priate *rder Gre+e+3er, 3ecau#e there# a #plitter inv*lved, the #plitter +u#t 3e added t* the 9*r+ i++ediately 3e9*re the !anel it re#i7e#H) The #electHiew( ) delegate +eth*d, called 3y the #electionChanged event *9 the *adioButton#, #et# ListHiew6Hiew t* the appr*priate value 9r*+ the Hiew enu+erati*n)

Cli$+oard and 4rag;and; 4ro$


=n*ther perennially challenging inter9ace i##ue i# u#ing the Clip3*ard and #upp*rting dragEandEdr*p *perati*n#)

Cli$+oard
O34ect# *n the Clip3*ard are #upp*#ed t* 3e a3le t* tran#9*r+ the+#elve# int* a variety *9 9*r+at#, depending *n !hat the pa#ting applicati*n !ant#) 5*r in#tance, a vect*r dra!ing placed *n the Clip3*ard #h*uld 3e a3le t* tran#9*r+ it#el9 int* a 3it+ap 9*r Paint *r a Scala3le Cect*r >raphic# d*cu+ent 9*r an BAL edit*r) ?ata tran#9er in ,ind*!# 5*r+# i# +ediated 3y cla##e# !hich i+ple+ent the B$ata1b)ect inter9ace) = c*n#u+ing applicati*n *r Control 9ir#t get# a re9erence t* the Clipboard# current B$ata1b)ect 3y calling the #tatic +eth*d

6#)

Thinking in C

www.ThinkingIn.!et

Clipboard6 et$ata1b)ect( )) Once in hand, the B$ata1b)ect +eth*d et$ata!resent( ) i# called !ith the de#ired type in a string *r +ype argu+ent) -9 the B$ata1b)ect can tran#9*r+ it#el9 int* the reDue#ted type, et$ata!resent( ) return# true, and et$ata( ) can then 3e u#ed t* retrieve the data in the reDue#ted 9*r+) -n thi# e;a+ple, *ne Button place# a string *n the Clip3*ard, and the *ther 3utt*n put# the Clip3*ard# c*ntent Gi9 availa3le a# a stringH int* a Label) -9 y*u c*py an i+age *r *ther +edia that cann*t 3e tran#9*r+ed int* a string *nt* the Clip3*ard and atte+pt t* pa#te it !ith thi# pr*gra+, the la3el !ill di#play I *thing)J //:c"T:C ip$oard:e!o.c# //Cut# to and pa#te# fro! the #y#te! C ip$oard u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.'hreading3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## C ip$oard:e!o : Hor! ; La$e 3 C ip$oard:e!o01; Button $ 9 ne. Button013 $.Location 9 ne. -oint0"02 "013 $.'ext 9 &C ip&3 $.C ic% R9 ne. +*entUand er0)dd'oC ip$oard13 Contro #.)dd0$13 Button $2 9 ne. Button013 $2.Location 9 ne. -oint0"002 "013 $2.'ext 9 &-a#te&3 $2.C ic% R9 ne. +*entUand er0CopyHro!C ip13 Contro #.)dd0$213 9 ne. La$e 013 .'ext 9 &Cothing&3 .Location 9 ne. -oint0"002 P013 .SiMe 9 ne. SiMe02002 2013

Cha"ter 13* Creating Gindows = 5""lets

6#3

Contro #.)dd0 13 < pu$ ic *oid )dd'oC ip$oard0O$Dect #2 +*ent)rg# a1; C ip$oard.Set:ataO$Dect0&'ext. On c ip$oard.&13 < pu$ ic *oid CopyHro!C ip0O$Dect #2 +*ent)rg# a1; 5:ataO$Dect o 9 C ip$oard._et:ataO$Dect013 if0o._et:ata-re#ent0typeof0#tring111; .'ext 9 o._et:ata0typeof0#tring11.'oString013 <e #e; .'ext 9 &Cothing&3 < < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. C ip$oard:e!o0113 < <//:8 *thing unu#ual i# d*ne in the Clipboard$emo( ) c*n#truct*rQ the *nly thing #*+e!hat di99erent 9r*+ *ther de+*# i# that the Label l i# +ade an in#tance varia3le #* that !e can #et it# c*ntent# in the Copy:romClip( ) +eth*d) The 'dd+oClipboard( ) +eth*d take# an ob)ect, in thi# ca#e a string) -9 the Clip3*ard i# given a string *r Bmage, that value can 3e pa#ted int* *ther applicati*n# Gu#e *ich+extBox6*tf *r #elected*tf 9*r pa#ting int* Aicr*#*9t ,*rdH) Copy:romClip( ) +u#t 3e a little cauti*u#, a# there i# n* guarantee that the Clip3*ard c*ntain# data that can 3e turned int* a string Gevery ) ET 5ra+e!*rk ob)ect can 3e turned int* a string, 3ut the Clip3*ard +ay very !ell c*ntain data that i# n*t a ) ET 5ra+e!*rk ob)ectH) -9 the B$ata1b)ect in#tance can indeed 3e e;pre##ed a# a string, !e retrieve it, again #peci9ying string a# the type !ere l**king 9*r) Even th*ugh !eve #peci9ied the type in the argu+ent, !e #till need t* change the return value *9 et$ata( ) 9r*+ ob)ect t* string, !hich !e d* 3y calling the +o#tring( ) +eth*d G!e c*uld al#* have u#ed a (string) ca#tH)

6#4

Thinking in C

www.ThinkingIn.!et

4rag and 4ro$


?rag and dr*p i# a highly vi#ual 9*r+ *9 data tran#9er 3et!een c*+p*nent# and applicati*n#) -n ,ind*!# 5*r+#, drag and dr*p again u#e# the B$ata1b)ect inter9ace, 3ut al#* inv*lve# vi#ual 9eed3ack) -n thi# e;a+ple, !e de+*n#trate 3*th dragEandEdr*p and the creati*n *9 a cu#t*+ B$ata1b)ect that can tran#9*r+ it#el9 int* a variety *9 type#) =n e;e+plar *9 #*+ething that tran#9*r+# int* a variety *9 type# i#, *9 c*ur#e, Super>l*, the 9l**r!a; that ta#te# like a de##ert t*pping G*r i# it the de##ert t*pping that clean# like a 9l**r!a;F =ll !e kn*! 9*r #ure i# that it# delici*u# and practicalKH //:c"T:Super_ o.c# //Co!pi e .ith: //c#c :rag)nd:rop:e!o.c# Super_ o.c# Super_ oGo*er.c# //:o!ain o$Dect# for cu#to! drag6and6drop interface H oorVax; *oid -o i#h013 < interface :e##ert'opping; *oid +at013 < c a## Super_ o : H oorVax2 :e##ert'opping ; pu$ ic *oid -o i#h01 ; Sy#te!.Con#o e.VriteLine0 &Super_ o !a%e# your f oor #hine!&13 < pu$ ic *oid +at01 ; Sy#te!.Con#o e.VriteLine0 &Super_ o ta#te# great!&13 < <//:8 0exa!p e continue# .ith Super_ oGo*er.c#1 -n thi# li#ting, !e de9ine the d*+ain ele+ent# P a :loor=ax inter9ace !ith a !olish( ) +eth*d, a $essert+opping inter9ace !ith an &at( ) +eth*d, and the #uper lo cla##, !hich i+ple+ent# 3*th the inter9ace#

Cha"ter 13* Creating Gindows = 5""lets

6#5

3y !riting t* the C*n#*le) *! !e need t* de9ine an B$ata1b)ect i+ple+entati*n that i# ver#atile en*ugh t* de+*n#trate #uper lo1 //0continuation1 //:c"T:Super_ oGo*er.c# //Cu#to! 5:ataO$Dect2 can expo#e Super_ o a#: //H oorVax2 :e##ert'opping2 or text c a## Super_ oGo*er : 5:ataO$Dect ; //Concern ": Vhat for!at# are #upportedY pu$ ic #tringJK _etHor!at#01 ; return ne. #tringJK; &H oorVax&2 &:e##ert'opping&2 &Super_ o&<3 < pu$ ic #tringJK _etHor!at#0$oo autoCon*ert1 ; if 0autoCon*ert1 ; return ne. #tringJK; &H oorVax&2 &:e##ert'opping&2 &Super_ o&2 :ataHor!at#.'ext<3 < e #e ; return _etHor!at#013 < < //Concern 2: Setting the data //Storage Super_ o #uperg o3 pu$ ic *oid Set:ata0o$Dect o1 ; if 0o i# Super_ o1 ; #uperg o 9 0Super_ o1 o3 < < pu$ ic *oid Set:ata0#tring f!t2 o$Dect o1 ; if 0f!t 99 &H oorVax& SS f!t 99 &:e##ert'opping& SS f!t 99 &Super_ o&1 ; Set:ata0o13 < e #e ;

6#6

Thinking in C

www.ThinkingIn.!et

if 0f!t 99 :ataHor!at#.'ext1 ; #uperg o 9 ne. Super_ o013 < e #e ; Sy#te!.Con#o e.VriteLine0 &Can't #et data to type & R f!t13 < < < pu$ ic *oid Set:ata0'ype t2 o$Dect o1 ; Set:ata0t.Ca!e2 o13 < pu$ ic *oid Set:ata 0String f!t2 $oo con*ert2 o$Dect o1 ; if 0f!t 99 :ataHor!at#.'ext @@ con*ert 99 fa #e1 ; Sy#te!.Con#o e.VriteLine0 &Refu#ing to change a #tring & R &to a #uperg o&13 < e #e ; Set:ata0f!t2 o13 < < //Concern T: 5# there a for!at c ient can u#eY pu$ ic $oo _et:ata-re#ent0#tring f!t1 ; if 0f!t 99 &:e##ert'opping& SS f!t 99 &H oorVax& SS f!t 99 :ataHor!at#.'ext SS f!t 99 &Super_ o&1 ; return true3 < e #e ; return fa #e3 < < pu$ ic $oo _et:ata-re#ent0'ype t1 ; return0_et:ata-re#ent0t.Ca!e113 < pu$ ic $oo _et:ata-re#ent

Cha"ter 13* Creating Gindows = 5""lets

6##

0String f!t2 $oo con*ert1 ; if 0f!t 99 :ataHor!at#.'ext @@ con*ert 99 fa #e1 ; return fa #e3 < e #e ; return _et:ata-re#ent0f!t13 < < //Concern E: _et the data in re7ue#ted for!at pu$ ic o$Dect _et:ata0#tring f!t1 ; #.itch 0f!t1 ; ca#e &H oorVax& : return #uperg o3 ca#e &:e##ert'opping& : return #uperg o3 ca#e &Super_ o& : return #uperg o3 ca#e &'ext& : return &Super_ o 66 5t'# a H oorVax! & R &)nd a de##ert topping!&3 defau t : Con#o e.VriteLine0 &Super_ o i# !any thing#2 $ut not a & R f!t13 return nu 3 < < pu$ ic o$Dect _et:ata0'ype t1 ; #tring f!t 9 t.Ca!e3 return _et:ata0f!t13 < pu$ ic o$Dect _et:ata0#tring f!t2 $oo if 0f!t 99 :ataHor!at#.'ext @@ con*ert 99 fa #e1 ; return nu 3 < e #e ; return _et:ata0f!t13 < con*ert1 ;

6#&

Thinking in C

www.ThinkingIn.!et

< <//:8 0exa!p e continue# .ith :rag)nd:rop:e!o.c#1 T* i+ple+ent B$ata1b)ect, y*u +u#t addre## & c*ncern#1 !hat are the 9*r+at# that are #upp*rted, #etting the data, i# the data in a 9*r+at the client can u#e, and getting the data in the #peci9ic 9*r+at the client !ant#) The 9ir#t c*ncern i# addre##ed 3y the t!* *verl*aded et:ormats( ) +eth*d#) B*th return string array# !hich repre#ent the ) ET cla##e# int* !hich the #t*red data can 3e tran#9*r+ed) -n additi*n t* the type# !hich the #uper lo cla## actually in#tantiate#, !e al#* #peci9y that #uper lo can aut*+atically 3e c*nverted t*EandE9r*+ te;t) The $ata:ormats cla## c*ntain# al+*#t t!* d*7en #tatic pr*pertie# de9ining vari*u# Clip3*ard 9*r+at# that ,ind*!# 5*r+# already under#tand#) Setting the data i# d*ne, in the #i+ple#t ca#e, 3y pa##ing in an ob)ect, !hich i# #t*red in the in#tance varia3le superglo) -9 a per#*n atte+pt# t* #t*re a n*nE#uper lo *34ect, the reDue#t !ill 3e Duietly ign*red) The ) ET d*cu+entati*n i# #ilent *n !hether #et$ata( ) #h*uld thr*! an e;cepti*n i9 called !ith an argu+ent *9 the !r*ng typeQ and typically #ilence +ean# that *ne #h*uld not thr*! an e;cepti*n) Thi# g*e# again#t the grain *9 g**d pr*gra++ing practice Gu#ually, the argu+ent t* a +eth*d #h*uld al!ay# either a99ect the return value *9 the +eth*d, a99ect the #tate *9 the *34ect *r the #tate *9 the argu+ent, *r re#ult in an e;cepti*nH) The #ec*nd #et$ata( ) +eth*d take# a string repre#enting a data 9*r+at and an *34ect) -9 the string i# any *ne *9 the native type# *9 #uper lo GISuper>l*J, I?e##ertJ, *r I5l**r,a;JH, the *34ect i# pa##ed t* the #et$ata(ob)ect) +eth*d) -9 the string i# #et t* $ata:ormats6+ext, a ne! #uper lo i# in#tantiated and #t*red) -9 the string i# n*t *ne *9 the#e 9*ur value#, a diagn*#tic i# printed and the +eth*d 9ail#) The third #et$ata( ) +eth*d take# a +ype a# it# 9ir#t argu+ent and #i+ply pa##e# that argu+ent# ,ame pr*perty 9*r!ard t* #et$ata(string, ob)ect)) The 9*urthEandE9inal #et$ata( ) +eth*d take#, in additi*n t* a 9*r+at string and the data ob)ect it#el9, a bool that +ay 3e u#ed t* turn *99 aut*Ec*nver#i*n Gin thi# ca#e, the Ic*nver#i*nJ 9r*+ $ata:ormat6+ext that 4u#t in#tantiate# a ne! #uper loH)

Cha"ter 13* Creating Gindows = 5""lets

6#'

The et$ata!resent( ) +eth*d# return true i9 the argu+ent i# *ne *9 the #uper lo type# *r $ata+ypes6+ext Ge;cept i9 the convert argu+ent i# #et t* falseH) The et$ata( ) +eth*d return# a re9erence t* the #t*red #uper lo i9 the 9*r+at reDue#ted i# ISuper>l*J, I5l**r,a;J, *r I?e##ertT*pping)J -9 the 9*r+at reDue#ted i# ITe;t,J the +eth*d return# a pr*+*ti*nal re9erence) -9 anything el#e, et$ata( ) return# a null re9erence) *! that !e have the d*+ain *34ect# and #uper lo.over, !e can put it all t*gether vi#ually1 //0continuation1 //:c"T::rag)nd:rop:e!o.c# //:e!on#trate# drag6and6drop .ith Super_ o and //Super_ oGo*er u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## :rag)nd:rop:e!o : Hor! ; :rag)nd:rop:e!o01 ; C ientSiMe 9 ne. SiMe0?E02 T2013 'ext 9 &:rag @ :rop&3 Button $ 9 ne. Button013 $.'ext 9 &-ut Super_ o on c ip$oard&3 $.Location 9 ne. -oint0"02 E013 $.Vidth 9 "003 $.C ic% R9 ne. +*entUand er0On-utSuper_ o13 -ictureBox p$ 9 ne. -ictureBox013 p$.5!age 9 5!age.Hro!Hi e0\&.^#uperg o.Dpg&13 p$.SiMeGode 9 -ictureBoxSiMeGode.)utoSiMe3 p$.Location 9 ne. -oint02202 "0013 p$.Gou#e:o.n R9 ne. Gou#e+*entUand er0OnBegin:rag13 -ane f oor 9 ne. -ane 013 f oor.BorderSty e 9 BorderSty e.HixedT:3 f oor.Location 9 ne. -oint0"02 I013

6&(

Thinking in C

www.ThinkingIn.!et

La$e f 9 ne. La$e 013 f.'ext 9 &H oor&3 f oor.Contro #.)dd0f13 f oor.) o.:rop 9 true3 f oor.:rag+nter R9 ne. :rag+*entUand er0On:rag+nterH oorVax13 f oor.:rag:rop R9 ne. :rag+*entUand er0On:ropH oorVax13 -ane de##ert 9 ne. -ane 013 de##ert.BorderSty e 9 BorderSty e.HixedT:3 de##ert.Location 9 ne. -oint0T002 I013 La$e d 9 ne. La$e 013 d.'ext 9 &:e##ert&3 de##ert.Contro #.)dd0d13 de##ert.) o.:rop 9 true3 de##ert.:rag+nter R9 ne. :rag+*entUand er0 On:rag+nter:e##ert'opping13 de##ert.:rag:rop R9 ne. :rag+*entUand er0On:rop:e##ert'opping13 'extBox text'arget 9 ne. 'extBox013 text'arget.Vidth 9 E003 text'arget.Location 9 ne. -oint0"202 2P013 text'arget.) o.:rop 9 true3 text'arget.:rag+nter R9 ne. :rag+*entUand er0On:rag+nter'ext13 text'arget.:rag:rop R9 ne. :rag+*entUand er0On:rop'ext13 Contro #.)ddRange0 ne. Contro JK; $2 p$2 f oor2 de##ert2 text'arget<13 < pri*ate *oid On-utSuper_ o0o$Dect #2 +*ent)rg# a1; Super_ o #uperg o 9 ne. Super_ o013 Super_ oGo*er !o*er 9 ne. Super_ oGo*er013 !o*er.Set:ata0#uperg o13

Cha"ter 13* Creating Gindows = 5""lets

6&1

C ip$oard.Set:ataO$Dect0!o*er13 < pri*ate *oid OnBegin:rag 0o$Dect #2 Gou#e+*ent)rg# arg#1 ; Super_ oGo*er #g! 9 ne. Super_ oGo*er013 #g!.Set:ata0ne. Super_ o0113 00Contro 1 #1.:o:rag:rop0 #g!2 :rag:rop+ffect#.Copy 13 < pri*ate *oid On:rag+nterH oorVax 0o$Dect #2 :rag+*ent)rg# arg#1 ; if 0arg#.:ata._et:ata-re#ent0&H oorVax&11 ; arg#.+ffect 9 :rag:rop+ffect#.Copy3 < < pri*ate *oid On:ropH oorVax 0o$Dect #2 :rag+*ent)rg# arg#1 ; H oorVax f 9 0H oorVax1 arg#.:ata._et:ata0&H oorVax&13 f.-o i#h013 < pri*ate *oid On:rag+nter:e##ert'opping 0o$Dect #2 :rag+*ent)rg# arg#1 ; if0arg#.:ata._et:ata-re#ent0&:e##ert'opping&11 ; arg#.+ffect 9 :rag:rop+ffect#.Copy3 < < pri*ate *oid On:rop:e##ert'opping 0o$Dect #2 :rag+*ent)rg# arg#1 ; :e##ert'opping d 9 0:e##ert'opping1 arg#.:ata._et:ata 0&:e##ert'opping&13 d.+at013 <

6&)

Thinking in C

www.ThinkingIn.!et

pri*ate *oid On:rag+nter'ext 0o$Dect #2 :rag+*ent)rg# arg#1 ; if 0arg#.:ata._et:ata-re#ent0&'ext&11 ; arg#.+ffect 9 :rag:rop+ffect#.Copy3 < < pri*ate *oid On:rop'ext 0o$Dect #ender2 :rag+*ent)rg# arg#1 ; #tring # 9 0#tring1 arg#.:ata._et:ata0&'ext&13 00Contro 1#ender1.'ext 9 #3 < pu$ ic #tatic *oid Gain01 ; )pp ication.Run0ne. :rag)nd:rop:e!o0113 < < //:8 ,hen run, thi# applicati*n l**k# like thi#1

-9 y*u click *n the i+age, y*u can drag it t* either *9 the t!* !anel#, the +ext&dit di#play, *r int* a te;t edit*r #uch a# Aicr*#*9t ,*rd) =# y*u drag, the +*u#e cur#*r !ill change t* indicate !hether *r n*t the

Cha"ter 13* Creating Gindows = 5""lets

6&3

#uper lo can 3e dr*pped) -9 y*u dr*p the #uper lo *n the I5l**rJ panel y*ull #ee *ne +e##age *n the c*n#*le, i9 *n the I?e##ertJ panel an*ther, and i9 in the +ext&dit 3*; *r in an*ther applicati*n, the pr*+*ti*nal +e##age !ill 3e pa#ted) -9 y*u click *n the 3utt*n, y*u can put a ne! #uper lo *n the Clip3*ard) The $rag'nd$rop$emo( ) c*n#truct*r #h*uld have n* #urpri#e# until !e add a .ouse&vent"andler *n 9*r the .ouse$own event *9 the !ictureBox c*ntr*l) That event !ill trigger the creati*n *9 a ne! #uper lo.over Ga# !ill the pre##ing *9 the Button)6 The !anel# 3*th have their 'llow$rop pr*perty #et t* true, #* !hen the +*u#e enter# the+ !hile dragging an *34ect, the +*u#e !ill give vi#ual 9eed3ack that a dr*p target i# 3eing traver#ed) =dditi*nally, the !anel# $rag&nter and $rag$rop event# are !ired t* event handler#) ,hen the 3utt*n i# pre##ed, it end# up calling 1n!ut#uper lo( )) = ne! #uper lo d*+ain *34ect i# created, a# i# a ne! #uper lo.over) The mover# data i# #et t* the 4u#tEcreated #uper lo and the mover i# placed *n the #y#te+ Clip3*ard) -n an*ther applicati*n #uch a# a te;t edit*r that accept# Clip3*ard te;t data, y*u #h*uld 3e a3le t* pa#te data) That *ther applicati*n !ill end up calling #uper lo.over6 et$ata( ) reDue#ting $ata+ype6+ext, re#ulting in the +e##age ISuper>l* P -t# a 5l**r,a;K =nd a de##ert t*ppingKJ 3eing pa#ted int* the *ther applicati*n) The +eth*d 1nBegin$rag( ) i# pretty #i+ilar t* 1n!ut#uper lo( ) 3ut a9ter the #uper lo.over i# in#tantiated, the +eth*d $o$rag$rop( ) i# called *n the originating Control) Thi# i# #*+e!hat c*n9u#ing, a# y*u +ight think that the de#tinati*n #h*uld 3e in charge, 3ut *n re9lecti*n it +ake# #en#e that the *riginat*r kn*!# the +*#t a3*ut the data, even !hen the data i# I9ar a!ayJ *n the #creen) There are #everal di99erent $rag$rop&ffects, !hich are 3it!i#e c*+3ina3leQ in thi# ca#e, the e99ect !e !ant i# t* c*py the data t* the target) B*th !anel# have very #i+ilar 1n$rag&nter"""( ) +eth*d#) The $rag&vent'rgs args ha# a $ata pr*perty that c*ntain# the #uper lo.over created in 1nBegin$rag( )6 Thi# $ata i# checked t* +ake #ure that it can pre#ent the appr*priate type GI5l**r,a;J *r

6&4

Thinking in C

www.ThinkingIn.!et

I?e##ertT*ppingJH and i9 #*, #etting the args6&ffect pr*perty +ake# the +*u#e #h*! the appr*priate vi#ual cue 9*r $rag$rop&ffects6Copy) Si+ilarly, 3*th !anel# have #i+ilar 1n$rop"""( ) +eth*d#) The $ata pr*perty Gthe #uper lo.overH ha# it# et$ata( ) +eth*d called !ith the de#ired type, either a :loor=ax *r $essert+opping) Thi# !ill return the #uper lo) Either :loor=ax6!olish( ) *r $essert+opping6&at( ) i# called, and the appr*priate +e##age printed *n the C*n#*le) The +extBox ha# #i+ilar 1n$rag&nter+ext( ) and 1n$rop+ext( ) +eth*d#, e;cept the #uper lo.over i# Dueried 9*r the ITe;tJ type)

4ata;+ound Controls
,ind*!# 5*r+# and =?O) ET c*+3ine t* +ake dataEdriven u#er inter9ace# very ea#y t* pr*gra+) -n Chapter #re9#, !e #a! h*! =?O) ET #eparate# the c*ncern# *9 +*ving data in and *ut 9r*+ a per#i#tent data#t*re 9r*+ the c*ncern# *9 +anipulating the inE+e+*ry $ata#et) Once a $ata#et i# p*pulated, in#tance# *9 the $ataBinding cla## +ediate 3et!een Control# and $ata#et#) One *9 the +*re i+pre##ive Control# 9*r di#playing data i# the $ata rid, !hich can di#play all the c*lu+n# in a ta3le) Thi# e;a+ple revi#it# the I *rth!ind)+d3J =cce## data3a#e1 //:c"T::ataBound:e!o.c# //:e!on#trate# the $a#ic# of data6$inding u#ing Sy#te!3 u#ing Sy#te!.:ata3 u#ing Sy#te!.:ata.O e:$3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## :ataBound:e!o : Hor! ; O e:$:ata)dapter adapter3 :ataSet e!p#3 :ataBound:e!o01; :ata_rid dg 9 ne. :ata_rid013 dg.:oc% 9 :oc%Sty e.Hi 3

Cha"ter 13* Creating Gindows = 5""lets

6&5

Contro #.)dd0dg13 Read+!p oyee#0&CVind.!d$&13 dg.Set:ataBinding0e!p#2 &'a$ e&13 < pri*ate *oid Read+!p oyee#0#tring path'o)cce##:B1; O e:$Connection cnctn 9 ne. O e:$Connection013 cnctn.ConnectionString9 &-ro*ider9Gicro#oft.`+'.OL+:B.E.03& R &data #ource9& R path'o)cce##:B3 cnctn.Open013 #tring #e Str 9 &S+L+C' = HROG +G-LO/++S&3 adapter 9 ne. O e:$:ata)dapter0#e Str2 cnctn13 ne. O e:$Co!!andBui der0adapter13 e!p# 9 ne. :ataSet0&+!p oyee#&13 adapter.Hi 0e!p#13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. :ataBound:e!o0113 < <//:8 = $ata rid dg c*ntr*l i# created and #et #* that it !ill 9ill the entire client area *9 the $ataBound$emo 9*r+) Then, the *ead&mployees( ) +eth*d 9ill# the $ata#et emps, 4u#t a# in the e;a+ple# in Chapter #re9#) Once emps i# 9illed, the dg)#et$ataBinding( ) a##*ciate# the $ata rid !ith the ITa3leJ ta3le in emps, !hich in thi# ca#e i# the *nly ta3le in the $ata#et) The re#ult #h*!# the c*ntent# *9 the *rth!ind data3a#e1

6&6

Thinking in C

www.ThinkingIn.!et

Even +*re p*!er9ully, the Binding.anagerBase cla## can c**rdinate a #et *9 Binding#, all*!ing y*u t* have #everal Control# !h*#e data3*und pr*pertie# are #i+ultane*u#ly and tran#parently changed t* c*rre#p*nd t* a #ingle rec*rd in the $ata#et) Thi# e;a+ple all*!# y*u t* navigate thr*ugh the e+pl*yee data1 //:c"T:Corre#ponder.c# //:e!on#trate# ho. $ound contro # can $e !ade to !atch u#ing u#ing u#ing u#ing u#ing Sy#te!3 Sy#te!.:ra.ing3 Sy#te!.Vindo.#.Hor!#3 Sy#te!.:ata3 Sy#te!.:ata.O e:$3

c a## Corre#ponder : Hor! ; O e:$:ata)dapter adapter3 :ataSet e!p#3 Corre#ponder01; Read+!p oyee#0&CVind.!d$&13

Cha"ter 13* Creating Gindows = 5""lets

6&#

La$e fCa!e 9 ne. La$e 013 fCa!e.Location 9 ne. -oint0"02 "013 Binding fBound 9 ne. Binding0&'ext&2 e!p#2 &'a$ e.Hir#tCa!e&13 fCa!e.:ataBinding#.)dd0fBound13 Contro #.)dd0fCa!e13 La$e Ca!e 9 ne. La$e 013 //! Ca!e.:ataBinding#.)dd0fBound13 Ca!e.Location 9 ne. -oint0"02 E013 Binding Bound 9 ne. Binding0&'ext&2 e!p#2 &'a$ e.La#tCa!e&13 Ca!e.:ataBinding#.)dd0 Bound13 Contro #.)dd0 Ca!e13 Button next 9 ne. Button013 next.Location 9 ne. -oint0"002 F013 next.'ext 9 &Z&3 next.C ic% R9 ne. +*entUand er0OnCext13 Contro #.)dd0next13 Button pre* 9 ne. Button013 pre*.Location 9 ne. -oint0"02 F013 pre*.'ext 9 &W&3 pre*.C ic% R9 ne. +*entUand er0On-re*13 Contro #.)dd0pre*13 < *oid OnCext0o$Dect #rc2 +*ent)rg# ea1; BindingGanagerBa#e !gr 9 BindingContextJe!p#2 &'a$ e&K3 !gr.-o#itionRR3 < *oid On-re*0o$Dect #rc2 +*ent)rg# ea1; BindingGanagerBa#e !gr 9 BindingContextJe!p#2 &'a$ e&K3 !gr.-o#ition663 <

6&&

Thinking in C

www.ThinkingIn.!et

pri*ate *oid Read+!p oyee#0 #tring path'o)cce##:B1; O e:$Connection cnctn 9 ne. O e:$Connection013 cnctn.ConnectionString9 &-ro*ider9Gicro#oft.`+'.OL+:B.E.03& R &data #ource9& R path'o)cce##:B3 cnctn.Open013 #tring #e Str 9 &S+L+C' = HROG +G-LO/++S&3 adapter 9 ne. O e:$:ata)dapter0#e Str2 cnctn13 ne. O e:$Co!!andBui der0adapter13 e!p# 9 ne. :ataSet0&+!p oyee#&13 adapter.Hi 0e!p#13 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Corre#ponder0113 < <//:8 =9ter p*pulating the $ata#et emps 9r*+ the data3a#e, !e create a Label t* h*ld the 9ir#t na+e *9 the current e+pl*yee) = ne! Binding *34ect i# createdQ the 9ir#t para+eter #peci9ie# the na+e *9 the Pr*perty t* !hich the data !ill 3e 3*und G*9ten, thi# !ill 3e the ITe;tJ pr*pertyH , the #ec*nd the $ata#et that !ill 3e the data #*urce, and the third the #peci9ic c*lu+n in the $ata#et t* 3ind t*) Once the Binding i# created, adding it t* f,ame6Bindings #et# the Label# +ext pr*perty t* the $ata#et value) The c*++entedE*ut line i++ediately a9ter l,ame# c*n#truct*r call i# a call that !ill lead t* a runti+e e;cepti*n P Binding# cann*t 3e #hared 3et!een Control#) -9 y*u !i#h +ultiple c*ntr*l# t* re9lect the #a+e $ata#et value, y*u have t* create +ultiple Binding#, *ne 9*r each Control) = #i+ilar pr*ce## i# u#ed t* c*n9igure the l,ame la3el 9*r the la#t na+e, and t!* Button# are created t* pr*vide rudi+entary navigati*n) The Button# event handler# u#e the BindingContext# #tatic < > *perat*r *verl*ad !hich take# a $ata#et and a string repre#enting a data +e+3er) The data +e+3er in thi# ca#e i# the ITa3leJ re#ult) The

Cha"ter 13* Creating Gindows = 5""lets

6&'

re#ulting Binding.anagerBase6!roperty value i# then incre+ented *r decre+ented !ithin the event handler) =# that happen#, the Binding.anagerBase update# it# a##*ciated Binding#, !hich in turn update their 3*und Control# !ith the appr*priate data 9r*+ the Binding# $ata#et6 Thi# diagra+ illu#trate# the #tatic #tructure *9 the relati*n#hip#)

:*ull n*tice that the Binding.anagerBase i# an a3#tract cla## in#tantiated 3y Currency.anager and !roperty.anager) -9 the call t* BindingContext<ob)ect, string> return# an ob)ect that i+ple+ent# BList, y*ull get a Currency.anager !h*#e !osition pr*perty +*ve# 3ack and 9*rth 3et!een ite+# in the BList Gthi# i# !hat !a# #h*!n in the e;a+pleQ +anipulating the !osition in the event handler #!itche# 3et!een e+pl*yee#H) -9 the call t* BindingContext<ob)ect, string> d*e# n*t return an *34ect i+ple+enting BList, a !roperty.anager i# returned)

%diting 4ata 0ro# 3ound Controls


O34ect# *9 the Binding cla## +anipulate the $ata#et) =# di#cu##ed in Chapter #=?O) ET#, changing the $ata#et d*e# n*t a99ect the 3acking

6'(

Thinking in C

www.ThinkingIn.!et

#t*re, the B$ata'dapter i# re#p*n#i3le 9*r +ediating 3et!een the inE +e+*ry $ata#tore and the B$bConnection) Thi# e;a+ple de+*n#trate# updating the data3a#e, pr*vide# a +*re detailed l**k at the event# that *ccur during data 3inding, and illu#trate# a u#e9ul U- technigue 9*r +anipulating data3a#e# *r *ther large data #tructure#) The U- techniDue i# 3a#ed *n the pre+i#e that it +ay 3e e;pen#ive in ter+# *9 +e+*ry *r re#*urce# *r redra!ing t* have every edita3le p*rti*n *9 the #creen actually 2e edita3leQ rather, the Control that +anage# the editing pr*ce## i# dyna+ically p*#iti*ned *n the #creen at the in#erti*n p*int G*r, in thi# ca#e, !hen the +*u#e click# *n a dataE 3*und Label !hich !e !i#h t* editH) Thi# techniDue i# n*t !*rth the e99*rt *n #i+ple #creen#, 3ut really c*+e# int* it# *!n *n c*+ple; U-# #uch a# y*u +ight have *n a !*rd pr*ce##*r, #pread#heet, *r a !*rk9l*! applicati*n) -9 y*u u#e thi# techniDue, y*u #h*uld i+ple+ent it u#ing the P=C >U- architecture #* that the re#ult appear# a# a #ea+le## c*+p*nent) //:c"T:Hor!+dit.c# //:e!on#trate# data .rite fro! Hor! u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 u#ing Sy#te!.:ata3 u#ing Sy#te!.:ata.O e:$3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Hor!+dit : Hor!; Ua#hta$ e co HorLa$e 9 ne. Ua#hta$ e013 $oo editVindo.)cti*e 9 fa #e3 'extBox editVindo. 9 ne. 'extBox013 La$e a$e Being+dited 9 nu 3 O e:$:ata)dapter adapter3 :ataSet e!p#3 Hor!+dit01; Read+!p oyee#0&CVind.!d$&13 5nit:ataStructure013 5nitLa$e #013

Cha"ter 13* Creating Gindows = 5""lets

6'1

5nitCo!!itter013 < pri*ate *oid 5nit:ataStructure01; co HorLa$e Jne. La$e 01K 9 &Hir#tCa!e&3 co HorLa$e Jne. La$e 01K 9 &La#tCa!e&3 < pri*ate *oid 5nitLa$e #01; int x 9 "03 int y 9 "03 int y5ncre!ent 9 TP3 foreach0#tring co Ca!e in co HorLa$e .Na ue#1; //Biha#hta$ e . aeyHorNa ue01 not in i$rary foreach0La$e $ in co HorLa$e .aey#1; #tring aCo Ca!e 9 0#tring1 co HorLa$e J $ K3 if 0aCo Ca!e 99 co Ca!e1 ; //Right %ey 0 a$e 1 for *a ue 0co Ca!e1 5nitLa$e 0 $ 2 co Ca!e2 x2 y13 y R9 y5ncre!ent3 < < < < pri*ate *oid 5nitLa$e 0La$e $ 2 #tring co Ca!e2 int x2 int y1; $ .Location 9 ne. -oint0x2 y13 $ .C ic% R9 ne. +*entUand er0OnLa$e C ic%13 $ .'extChanged R9 ne. +*entUand er0On'extChange13 Contro #.)dd0 $ 13 #tring na*-ath 9 &'a$ e.& R co Ca!e3 Binding $ 9 ne. Binding0&'ext&2 e!p#2 na*-ath13 $.-ar#e R9 ne. Con*ert+*entUand er0OnBound:ataChange13 $ .:ataBinding#.)dd0$13

6')

Thinking in C

www.ThinkingIn.!et

< pri*ate *oid 5nitCo!!itter01; Button $ 9 ne. Button013 $.Vidth 9 "203 $.Location 9 ne. -oint0"P02 "013 $.'ext 9 &Co!!it change#&3 $.C ic% R9 ne. +*entUand er0OnCo!!it13 Contro #.)dd0$13 < pu$ ic *oid OnLa$e C ic%0O$Dect #rc2 +*ent)rg# ea1; La$e #rcLa$e 9 0La$e 1 #rc3 if0editVindo.)cti*e1 Hina iMe+dit013 - ace+ditVindo.O*erLa$e 0#rcLa$e 13 )##ociate+ditorVithLa$e 0#rcLa$e 13 < pri*ate *oid - ace+ditVindo.O*erLa$e 0La$e $ 1; editVindo..Location 9 $ .Location3 editVindo..SiMe 9 $ .SiMe3 if0Contro #.Contain#0editVindo.1 99 fa #e1; Contro #.)dd0editVindo.13 < editVindo..Ni#i$ e 9 true3 editVindo..Bring'oHront013 editVindo..Hocu#013 editVindo.)cti*e 9 true3 < pri*ate *oid )##ociate+ditorVithLa$e 0La$e editVindo..'ext 9 .'ext3 a$e Being+dited 9 3 < 1;

pu$ ic *oid Hina iMe+dit01; Sy#te!.Con#o e.VriteLine0&Hina iMing edit&13 a$e Being+dited.'ext 9 editVindo..'ext3 Sy#te!.Con#o e.VriteLine0&'ext changed&13 //Ceeded to trigger $inding e*ent

Cha"ter 13* Creating Gindows = 5""lets

6'3

a$e Being+dited.Hocu#013 editVindo..Ni#i$ e 9 fa #e3 editVindo..Send'oBac%013 editVindo.)cti*e 9 fa #e3 < pu$ ic *oid On'extChange0O$Dect #rc2 +*ent)rg# ea1; La$e $ 9 0La$e 1 #rc3 #tring co Ca!e 9 0#tring1 co HorLa$e J $ K3 Sy#te!.Con#o e.VriteLine0 co Ca!e R & ha# changed&13 < pu$ ic *oid OnBound:ataChange 0O$Dect #rc2 Con*ert+*ent)rg# ea1; Sy#te!.Con#o e.VriteLine0&Bound data changed&13 < pri*ate *oid OnCo!!it0O$Dect #rc2 +*ent)rg# ea1; Hina iMe+dit013 adapter.Opdate0e!p#13 < pri*ate *oid Read+!p oyee# 0#tring path'o)cce##:B1; O e:$Connection cnctn 9 ne. O e:$Connection013 cnctn.ConnectionString9 &-ro*ider9Gicro#oft.`+'.OL+:B.E.03& R &data #ource9& R path'o)cce##:B3 cnctn.Open013 #tring #e Str 9 &S+L+C' = HROG +G-LO/++S&3 adapter 9 ne. O e:$:ata)dapter0#e Str2 cnctn13 ne. O e:$Co!!andBui der0adapter13 e!p# 9 ne. :ataSet0&+!p oyee#&13 adapter.Hi 0e!p#13 < pu$ ic #tatic *oid Gain01;

6'4

Thinking in C

www.ThinkingIn.!et

)pp ication.Run0ne. Hor!+dit0113 < <//:8 The :orm&dit cla## ha# #everal in#tance varia3le#1 col:orLabel i# a "ashtable that i# u#ed t* e#ta3li#h a c*rre#p*ndence 3et!een a $ata#et c*lu+n na+e and a Label c*ntr*l) The ne;t / in#tance varia3le#, edit=indow'ctive, edit=indow, and labelBeing&dited are u#ed in the Idyna+icJ editing #che+e P all editing i# d*ne in the edit=indow +extBox, !hile a re9erence t* the editing target i# held in the labelBeing&dited varia3le) The adapter and emps varia3le# are the 9a+iliar varia3le# h*lding the B$ata'dapter and $ata#et a##*ciated !ith the *rth!ind data3a#e) The :orm&dit( ) c*n#truct*r initiali7e# emps and adapter in *ead&mployees( ), !hich d*e# n*t di99er 9r*+ the previ*u# e;a+ple#) Bnit$ata#tructure( ) initiali7e# the col:orLabel data #tructureQ an an*ny+*u# Label i# u#ed a# the key and the c*lu+n# na+e i# the value) One can i+agine a +*re #*phi#ticated ver#i*n *9 thi# +eth*d that iterate# *ver the $ata#et, creating a# +any Control# a# are nece##ary) BnitLabels( ) i# re#p*n#i3le 9*r #etting up the di#play *9 the data #tructure initiali7ed in Bnit$ata#tructure( )) Becau#e the ) ET 5ra+e!*rk d*e# n*t have a 3idirecti*nal ver#i*n *9 the B$ictionary inter9ace that can l**k up a key 3a#ed *n the value, !e have t* u#e a ne#ted l**p t* 9ind the Label a##*ciated !ith the col,ame) Once 9*und, BnitLabels( ) call# BnitLabel( ) t* c*n9igure the #peci9ic Label) =gain, a +*re #*phi#ticated ver#i*n *9 thi# +eth*d +ight d* a +*re #*phi#ticated 4*3 *9 laying *ut the di#play) BnitLabel( ) i# re#p*n#i3le 9*r !iring up the Label t* the $ata#et# c*lu+n na+e) T!* event handler# are added t* the Label1 1nLabelClic(( ) and 1n+extChange( )) The +eth*d al#* a##*ciate# 1nBound$ataChange( ) !ith the Binding# !arse event, !hich *ccur# !hen the value *9 a data3*und c*ntr*l change#) The Binding i# created 9r*+ the c*lu+n na+e that !a# pa##ed in a# an argu+ent and a##*ciated !ith the Label that !a# al#* pa##ed in) The la#t +eth*d called 3y the c*n#truct*r i# BnitCommitter( ), !hich initiali7e# a Button that !ill 3e u#ed t* trigger a data3a#e update)

Cha"ter 13* Creating Gindows = 5""lets

6'5

=9ter the c*n#truct*r run#, the $ata#et emps i# 9illed !ith *rth!ind# e+pl*yee data and the Label# *n the &dit:orm #h*! the 9ir#t and la#t na+e *9 the 9ir#t rec*rd Gthi# e;a+ple d*e#nt have any navigati*nH) ,hen the u#er click# *n *ne *9 the#e la3el#, they activate 1nLabelClic(( )) =ll Label# *n the 9*r+ #hare the 1nLabelClic(( ) event handler, 3ut #i+ply ca#ting the src t* Label give# u# the needed in9*r+ati*n t* +anipulate the edit=indow) The 9ir#t ti+e thr*ugh 1nLabelClic(( ), the edit=indow'ctive B**lean !ill 3e false, #* let# +*+entarily delay di#cu##i*n *9 the :inaliTe&dit( ) +eth*d) Our dyna+ic editing techniDue i# t* place the editing c*ntr*l *n the U- at the appr*priate place, and then t* a##*ciate the editing c*ntr*l !ith the underlying data) !lace&dit=indow1verLabel( ) #et# the edit=indow t* *verlay the Label the u#er clicked *n, +ake# it vi#i3le, and reDue#t# the 9*cu#) 'ssociate&ditor=ithLabel( ) #et# the te;t *9 the editor=indow t* !hat i# in the underlying Label and #et# the labelBeing&dited in#tance varia3le t* the clickedE*n Label) The vi#ual e99ect *9 all thi# i# that !hen #*+e*ne click# *n either Label, it appear# a# i9 the Label turn# int* an &ditBox) =gain, thi# i# n* 3ig deal !ith t!* la3el# *n the 9*r+, 3ut i9 there !ere a c*uple d*7en 9ield# 3eing# di#played *n the #creen, there can 3e a #igni9icant re#*urce and #peed i+pr*ve+ent 3y having a #ingle, dyna+ic editing c*ntr*l) Since !lace&dit=indow1verLabel( ) #et edit=indow'ctive t* true, #u3#eDuent call# t* 1nLabelClic(( ) !ill call :inaliTe&dit( )) :inaliTe&dit( ) put# the te;t 9r*+ the edit=indow int* the underlying labelBeing&dited) Thi# al*ne does not u"date the $ataBinding, y*u +u#t give the la3el the 9*cu#, even 9*r a +*+ent, in *rder t* update the data) 1nBound$ataChanged( ) i# called #u3#eDuent t* the data update, and !hen run, y*ull #ee1 Hina iMing edit Hir#tCa!e ha# changed 'ext changed Bound data changed -ndicating thi# #eDuence1

6'6

Thinking in C

www.ThinkingIn.!et

The a3*ve diagra+ i# a UAL acti-it4 diagram and i# *ne *9 the +*#t help9ul diagra+# 9*r !hite3*ard #e##i*n# Ga# argued e99ectively 3y Sc*tt =+3ler at !!!)agile+*diling)*rg, y*u !ill derive +*re 3ene9it 9r*+ l*!E tech +*deling !ith *ther# than y*u can ever derive 9r*+ highEtech +*deling 3y y*ur#el9H) The activity diagra+ ha# ti+e *n the vertical a;i# and +e##age# and *34ect# *n the h*ri7*ntal) The 3*;e# *n the vertical line# c*rre#p*nd t* +eth*d inv*cati*n# and the call #tack) Thu#, this61nBound$ataChanged( ) i# called 9r*+ an an*ny+*u# Binding1b)ect# Vpdate( )8 +eth*d, !hich i# called 9r*+ labelBeing&dited6:ocus(), !hich !e call in this6:inaliTe&dit( )) =lth*ugh :inaliTe&dit( ) +*di9ie# the $ata#et emps, the call t* adapter6Vpdate( ) in 1nCommit( ) i# reDuired t* actually +*ve the data 3ack int* the data3a#e) Be #ure t* 3e 9a+iliar !ith =?O) ET#
2 =ctually, the na+e# and #eDuence *9 event# that happen in Control6:ocus( ) i#

c*n#idera3ly +*re c*+ple; than !hat i# p*rtrayed here, 3ut gl*##ing *ver detail# n*t relevant t* the ta#k at hand i# *ne *9 the great 3ene9it# *9 diagra++ing) Thi# i# *ne *9 the rea#*n# diagra++ing t**l# that dyna+ically 3ind t* actual #*urce c*de are *9ten le## u#e9ul than, #ay, a piece *9 paper)

Cha"ter 13* Creating Gindows = 5""lets

6'#

*pti+i#tic c*ncurrency 3ehavi*r, a# di#cu##ed in chapter #ad*)net# 3e9*re engaging in any data3a#e pr*4ect#)

@enus
U#er inter9ace e;pert# #ay that +enu# are *verrated) Pr*gra++er#, !h* are trained t* think in ter+# *9 hierarchie#, and !h*#e career# are c*+puterEcentric, d*nt 3at an eye at ca#cading +enu *pti*n# and 9*ndly recall the ?OS day# !hen y*u c*uld #peci9y incredi3ly c*+ple; #pread#heet and !*rd pr*ce##ing 3ehavi*r# 3y rattling *99 the 9ir#t letter# *9 +enu #eDuence# Gn*!aday#, y*u have t* #ay IS* are y*u #eeing a dial*g that #ay# T?i#play Pr*pertie# and that ha# a 3unch *9 ta3#F Okay, 9ind the ta3 that #ay# T=ppearance and click *n it) ?* y*u #ee the 3utt*n that read# T=dvancedF -t #h*uld 3e in the l*!erEright c*rnerLJH) 5*r +any u#er#, th*ugh, +enu# are #urpri#ingly di99icult t* navigate) everthele##, unle## y*ure creating a purely ,e3E3a#ed inter9ace, the *dd# are Duite g**d that y*ull !ant t* add +enu# and c*nte;t +enu# t* y*ur U-#) There are t!* type# *9 +enu in ,ind*!# 5*r+#, a .ain.enu that di#play# acr*## the t*p *9 a :orm, and a Context.enu that can 3e a##*ciated !ith any Control and i# typically di#played *n a rightE3utt*n +*u#e click *ver the Control) B*th 9*r+# *9 +enu c*ntain .enuBtem# and .enuBtem# +ay, in turn, c*ntain *ther .enuBtem# G*nce again, the 9a+iliar c*ntain+ent +*del *9 ,ind*!# 5*r+#H ) ,hen #elected, the .enuBtem trigger# a Clic( event, even i9 the .enuBtem !a# ch*#en via a #h*rtcut *r acce## key) Thi# e;a+ple #h*!# 3*th type# *9 +enu# and h*! t* create ca#cading +enu#1 //:c"T:Genu:e!o.c# //:e!on#trate# !enu# u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Genu:e!o : Hor! ; Genu:e!o01;

6'&

Thinking in C

www.ThinkingIn.!et

'ext 9 &Genu :e!o&3 GainGenu cour#eGenu 9 ne. GainGenu013 Genu5te! appetiMer# 9 ne. Genu5te!013 appetiMer#.'ext 9 &@)ppetiMer#&3 Genu5te!JK #tarter# 9 ne. Genu5te!JTK3 #tarter#J0K 9 ne. Genu5te!013 #tarter#J0K.'ext 9 &@-ot #tic%er#&3 #tarter#J"K 9 ne. Genu5te!013 #tarter#J"K.'ext 9 &@Spring ro #&3 #tarter#J2K 9 ne. Genu5te!013 //Cote e#caped &@& #tarter#J2K.'ext 9 &@Uot @@ Sour Soup&3 appetiMer#.Genu5te!#.)ddRange0#tarter#13 foreach0Genu5te! i in #tarter#1; i.C ic% R9 ne. +*entUand er0OnCo!$ina$ eGenuSe ected13 < Genu5te! !ainCour#e 9 ne. Genu5te!013 !ainCour#e.'ext 9 &@Gain Cour#e&3 Genu5te!JK !ain 9 ne. Genu5te!JEK3 !ainJ0K 9 ne. Genu5te!013 !ainJ0K.'ext 9 &@S.eet @@ Sour -or%&3 !ainJ"K 9 ne. Genu5te!013 !ainJ"K.'ext 9 &@Goo #hu&3 !ainJ2K 9 ne. Genu5te!013 !ainJ2K.'ext 9 &@aung -ao Chic%en&3 //Out of aung -ao Chic%en !ainJ2K.+na$ ed 9 fa #e3 !ainJTK 9 ne. Genu5te!013 !ainJTK.'ext 9 &_enera '# Chic%en&3 !ainCour#e.Genu5te!#.)ddRange0!ain13 foreach0Genu5te! i in !ain1; i.RadioChec% 9 true3 i.C ic% R9 ne. +*entUand er0On+xc u#i*eGenuSe ected13 < Genu5te! *eg 9 ne. Genu5te!013

Cha"ter 13* Creating Gindows = 5""lets

6''

*eg.'ext 9 &Negetarian&3 *eg.RadioChec% 9 true3 *eg.C ic% R9 ne. +*entUand er0On+xc u#i*eGenuSe ected13 Genu5te! por% 9 ne. Genu5te!013 por%.'ext 9 &-or%&3 por%.RadioChec% 9 true3 por%.C ic% R9 ne. +*entUand er0On+xc u#i*eGenuSe ected13 !ainJ"K.Genu5te!#.)ddRange0 ne. Genu5te!JK;*eg2por%<13 cour#eGenu.Genu5te!#.)dd0appetiMer#13 cour#eGenu.Genu5te!#.)dd0!ainCour#e13 ContextGenu contextGenu 9 ne. ContextGenu013 foreach0Genu5te! a in #tarter#1; contextGenu.Genu5te!#.)dd0a.C oneGenu0113 < contextGenu.Genu5te!#.)dd0 ne. Genu5te!01.'ext 9 &6&13 foreach0Genu5te! ! in !ain1; contextGenu.Genu5te!#.)dd0!.C oneGenu0113 < Genu 9 cour#eGenu3 ContextGenu 9 contextGenu3 < pri*ate *oid OnCo!$ina$ eGenuSe ected 0o$Dect #ender2 +*ent)rg# arg#1; Genu5te! #e ection 9 0Genu5te!1 #ender3 #e ection.Chec%ed 9 !#e ection.Chec%ed3 < pri*ate *oid On+xc u#i*eGenuSe ected 0o$Dect #ender2 +*ent)rg# arg#1; Genu5te! #e ection 9 0Genu5te!1 #ender3 $oo #e ect)fterC ear 9 !#e ection.Chec%ed3 //Gu#t i!p e!ent radio6$utton functiona ity progra!!atica y Genu parent 9 #e ection.-arent3

#((

Thinking in C

www.ThinkingIn.!et

foreach0Genu5te! i in parent.Genu5te!#1; i.Chec%ed 9 fa #e3 < #e ection.Chec%ed 9 #e ect)fterC ear3 < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Genu:e!o0113 < <//:8 The .enu$emo( ) c*n#truct*r create# a #erie# .enuBtem#) The a+per#and G8H in the .enuBtem6+ext pr*perty #et# the accelerat*r key 9*r the ite+ G#* I=ltE=J !ill activate the I=ppeti7er#J +enu and I=ltEAJ the IAain C*ur#eJ +enuH) T* include an a+per#and in the +enu te;t, y*u +u#t u#e a d*u3le a+per#and G9*r in#tance, I"ot LL #our #oupJH) Each .enuBtem created i# added t* either the main.enu).enuBtems c*llecti*n *r t* the .enuBtems c*llecti*n *9 *ne *9 the *ther .enuBtem#) The .enuBtem# in the appetiTers .enu have the de9ault false value 9*r their *adioChec( pr*perty) Thi# +ean# that i9 their #election6Chec(ed pr*perty i# #et t* true, they !ill di#play a #+all check+ark) The .enuBtem# in mainCourse have *adioChec( #et t* true, and !hen they have #elected6Chec(ed #et t* true, they di#play a #+all circle) H*!ever, thi# i# a di#play *pti*n *nly, the +utual e;clu#i*n l*gic *9 a radi* 3utt*n +u#t 3e i+ple+ented 3y the pr*gra++er, a# i# #h*!n in the 1n&xclusive.enu#elected( ) +eth*d) = .enuBtem i# deactivated 3y #etting it# &nabled pr*perty t* 9al#e, a# i# d*ne !ith the INung Pa* ChickenJ entree) T* duplicate a .enu, y*u u#e n*t Clone( ) 3ut Clone.enu( ), a# #h*!n in the l**p# that p*pulate the context.enu) The context.enu al#* de+*n#trate# that a .enuBtem !ith it# +ext pr*perty #et t* a #ingle da#h i# di#played a# a #eparat*r 3ar in the re#ulting +enu)

Cha"ter 13* Creating Gindows = 5""lets

#(1

'tandard 4ialogs
,ind*!# 5*r+# pr*vide# #everal #tandard dial*g# 3*th t* ea#e c*++*n ch*re# and +aintain c*n#i#tency 9*r the endEu#er) The#e dial*g# include 9ile *pen and #ave, c*l*r ch*ice, 9*nt dial*g#, and print previe! and print dial*g#) ,ere g*ing t* h*ld *99 *n the di#cu##i*n *9 the printing dial*g# until the #ecti*n *n printing in the >?-@ chapter, 3ut thi# e;a+ple #h*!# the ea#e !ith !hich the *ther# are u#ed1 //:c"T:Std:ia og#.c# u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 c a## Std:ia og# : Hor!; La$e a$e 9 ne. La$e 013 Std:ia og#01; GainGenu !enu 9 ne. GainGenu013 Genu 9 !enu3 Genu5te! fGenu 9 ne. Genu5te!0&@Hi e&13 !enu.Genu5te!#.)dd0fGenu13 Genu5te! oGenu 9 ne. Genu5te!0&@Open...&13 oGenu.C ic% R9 ne. +*entUand er0OnOpen13 fGenu.Genu5te!#.)dd0oGenu13 Genu5te! cGenu 9 ne. Genu5te!0&@Sa*e...&13 cGenu.C ic% R9 ne. +*entUand er0OnC o#e13 fGenu.Genu5te!#.)dd0cGenu13 fGenu.Genu5te!#.)dd0ne. Genu5te!0&6&113 Genu5te! opGenu 9 ne. Genu5te!0&@Option#&13 !enu.Genu5te!#.)dd0opGenu13 Genu5te! c rGenu 9 ne. Genu5te!0&@Co or...&13 c rGenu.C ic% R9 ne. +*entUand er0OnCo or13 opGenu.Genu5te!#.)dd0c rGenu13

#()

Thinking in C

www.ThinkingIn.!et

Genu5te! fntGenu 9 ne. Genu5te!0&@Hont...&13 fntGenu.C ic% R9 ne. +*entUand er0OnHont13 opGenu.Genu5te!#.)dd0fntGenu13 a$e .'ext 9 &So!e text&3 a$e .:oc% 9 :oc%Sty e.Hi Contro #.)dd0 a$e 13 < pu$ ic *oid OnOpen0o$Dect #rc2 +*ent)rg# ea1; OpenHi e:ia og ofd 9 ne. OpenHi e:ia og013 ofd.Hi ter 9 &C( fi e# 0=.c#1S=.c#S) fi e# 0=.=1S=.=&3 ofd.Hi ter5ndex 9 23 :ia ogRe#u t fi eCho#en 9 ofd.Sho.:ia og013 if0fi eCho#en 99 :ia ogRe#u t.Oa1; foreach0#tring fCa!e in ofd.Hi eCa!e#1; Con#o e.VriteLine0fCa!e13 < <e #e; Sy#te!.Con#o e.VriteLine0&Co fi e cho#en&13 < < pu$ ic *oid OnC o#e0o$Dect #rc2 +*ent)rg# ea1; Sa*eHi e:ia og #fd 9 ne. Sa*eHi e:ia og013 :ia ogRe#u t #a*eCho#en 9 #fd.Sho.:ia og013 if0#a*eCho#en 99 :ia ogRe#u t.Oa1; Con#o e.VriteLine0#fd.Hi eCa!e13 < < pu$ ic *oid OnCo or0o$Dect #rc2 +*ent)rg# ea1; Co or:ia og cd 9 ne. Co or:ia og013 if0cd.Sho.:ia og01 99 :ia ogRe#u t.Oa1; Co or c 9 cd.Co or3 a$e .HoreCo or 9 c3 Opdate013 < < 3

Cha"ter 13* Creating Gindows = 5""lets

#(3

pu$ ic *oid OnHont0o$Dect #rc2 +*ent)rg# ea1; Hont:ia og fd 9 ne. Hont:ia og013 if0fd.Sho.:ia og01 99 :ia ogRe#u t.Oa1; Hont f 9 fd.Hont3 a$e .Hont 9 f3 Opdate013 < < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. Std:ia og#0113 < <//:8 The #td$ialogs( ) c*n#truct*r initiali7e# a +enu #tructure and place# a Label *n the 9*r+) 1n1pen( ) create# a ne! 1pen:ile$ialog and #et# it# :ilter pr*perty t* #h*! either all 9ile# *r 4u#t th*#e !ith 6cs e;ten#i*n#) 5ile dial*g 9ilter# are c*n9u#ing) They are #peci9ied !ith a l*ng #tring, deli+ited !ith the pipe #y+3*l G[H) The di#played na+e# *9 the 9ilter# are placed in the *dd p*#iti*n#, !hile the 9ilter# the+#elve# are placed in the even p*#iti*n#) The :ilterBndex i# one92ased5 S* 3y #etting it# value t* 2, !ere #etting# it# value t* the b)b 9ilter, the 9*urth ite+ in the li#t) Like all the dial*g#, the 1pen:ile$ialog i# #h*!n !ith the #how$ialog( ) +eth*d) Thi# *pen# the dial*g in modal 9*r+Q the u#er +u#t cl*#e the +*dal dial*g 3e9*re returning t* any *ther kind *9 input t* the #y#te+) ,hen the dial*g i# cl*#ed, it return# a value 9r*+ the $ialog*esult enu+erati*n) $ialog*esult61E i# the h*pedE9*r valueQ *ther# are1 =3*rt Cancel -gn*re * *ne

#(4

Thinking in C

www.ThinkingIn.!et

Retry :e# O3vi*u#ly, n*t all dial*g# !ill return all G*r +*#tH *9 the#e value#) B*th the 1pen:ile$ialog and the #ave:ile$ialog have 1pen:ile( ) +eth*d# that *pen the #peci9ied 9ile G9*r reading *r !riting, re#pectivelyH, 3ut in the e;a+ple, !e 4u#t u#e the :ile,ames and :ile,ame pr*pertie# t* get the li#t *9 #elected 9ile# Gin 1n1pen( ) H and the #peci9ied 9ile t* 3e !ritten t* in 1n#ave( )) The #ave:ile$ialog61verwrite!rompt pr*perty, !hich de9ault# t* true, #peci9ie# !hether the dial*g !ill aut*+atically a#k the u#er I=re y*u #ureLFJ 1nColor( ) and 1n:ont( ) 3*th have appr*priate pr*pertie# GColor and :ontH that can 3e read a9ter the dial*g# cl*#e) The label i# changed t* u#e that value and then the Vpdate( ) +eth*d i# called in *rder t* redra! and relay*ut the #td$ialogs 9*r+)

>sage;Centered 4esign
-n the di#cu##i*n *9 >U- =rchitecture#, !e +enti*ned the adage that IT* the end u#er, the U- is the applicati*n)J Thi# i# *ne *9 the tenet# *9 usage9 centered design, an appr*ach t* #y#te+ devel*p+ent that 9it# very !ell !ith the +*ve t*!ard# agile de-elo"ment that pr*p*#e that #h*rter pr*duct cycle# Ga# #h*rt a# a 9e! !eek# 9*r internal pr*4ect#H that are inten#ely 9*cu#ed *n delivering reDue#ted endEu#er value are +uch +*re #ucce##9ul than the traditi*nal appr*ach *9 creating a 3alance *9 9uncti*nal, n*nE9uncti*nal, and +arketEdriven 9eature# that are relea#ed in I+a4*r r*llE*ut#)J 5ar t** +any di#cu##i*n# *9 #*9t!are devel*p+ent 9ail t* include the endE u#er, +uch le## acc*rd the+ the appr*priate re#pect a# the driver *9 !hat the applicati*n #h*uld d* and h*! it #h*uld appear) -+agine that *ne day y*u !ere given a #urvey *n y*ur eating ha3it# a# part *9 a +a4*r initiative t* pr*vide y*u a !*rldEcla## diet) Eighteen +*nth# later, !hen y*ud 9*rg*tten a3*ut the !h*le thing, y*ure given a #peci9ic 3reak9a#t, lunch, and dinner and t*ld that thi# !a# all y*u c*uld eat 9*r the ne;t eighteen

Cha"ter 13* Creating Gindows = 5""lets

#(5

+*nth#) =nd that the +eal# !ere prepared 3y dietician#, n*t che9#, and that the +eal# had never actually 3een ta#ted 3y any*ne) That# h*! +*#t #*9t!are i# devel*ped) * inter9ace li3rary i# en*ugh t* +ake a u#a3le inter9ace) :*u must actively !*rk !ith end u#er# t* di#c*ver their need# Gy*ull *9ten help them di#c*ver the !*rd# t* e;pre## a need they a##u+ed c*uld n*t 3e 9i;edH , y*u must #ilently !atch endEu#er# u#ing y*ur #*9t!are Ga hu+3ling e;perienceH, and y*u must ev*lve the u#er inter9ace 3a#ed *n the need# *9 the u#er, n*t the ae#thetic !hi+# *9 a graphic de#igner/) One *9 u# GLarryH had the *pp*rtunity t* !*rk *n a pr*4ect that u#ed u#ageEcentered de#ign t* create ne! type# *9 cla##r**+ +anage+ent t**l# 9*r NE02 teacher# Ga gr*up that i# right9ully di#tru#t9ul *9 the technical Ig*lden 3ullet#J that are regularly 9*i#ted up*n the+H) The U- had l*t# *9 #tandard c*+p*nent#, and three cu#t*+ c*ntr*l#) T!* *9 the cu#t*+ c*ntr*l# !ere ne-er noticed 3y endEu#er# Gthey 4u#t u#ed the+, n*t reali7ing that they !ere #eeing c*+ple;, n*nE#tandard 3ehavi*rH) ,e c*uld al!ay# tell !hen u#er# #a! the third, th*ugh, 3ecau#e they literally gas"ed !hen they #a! it) -t !a# a heck *9 a g**d inter9ace&)

'u##ar5
C# ha# an *34ectE*riented 3*und +eth*d type called delegate) ?elegate# are 9ir#tEcla## type#, and can 3e in#tantiated 3y any +eth*d !h*#e #ignature e;actly +atche# the delegate type) There are #everal architecture# that +ay 3e u#ed t* #tructure the >U-, either a# an independent #u3#y#te+ *r 9*r the pr*gra+ a# a !h*le) The Ci#ual ?e#igner t**l in Ci#ual Studi* ) ET 9acilitate# an architecture called 5*r+EEventEC*ntr*l, !hich pr*vide# a +ini+al #eparati*n *9 the inter9ace 9r*+ the d*+ain l*gic) A*delECie!EC*ntr*ller pr*vide# the
/ Thi# i# n*t t* di#parage graphic de#igner# *r their !*rk) But creating a u#a3le inter9ace i#

nothing like creating a reada3le page *r an eyeEcatching adverti#e+ent) -9 y*u cant get a de#igner !ith a 3ackgr*und in C*+puterEHu+an -nteracti*n GCH-H, at lea#t u#e a de#igner !ith a 3ackgr*und in indu#trial de#ign)
& Un9*rtunately, the CEO #a! 9it t* #pend *ur U0',$$$,$$$ in venture capital *n

pr*#titute#, drug#, and a "aguar #edan !ith #atellite navigati*n 9*r the c*+pany car) Oh yeah, !e al#* had 9ree #*da)

#(6

Thinking in C

www.ThinkingIn.!et

+a;i+u+ #eparati*n *9 inter9ace, input, and d*+ain l*gic, 3ut i# *9ten +*re tr*u3le than it# !*rth) Pre#entati*nE=3#tracti*nEC*ntr*l i# an architecture that create# #el9Ec*ntained c*+p*nent# that are re#p*n#i3le 9*r 3*th their *!n di#play and d*+ain l*gicQ it i# *9ten the 3e#t ch*ice 9*r !*rking in ,ind*!# 5*r+#) ,ind*!# 5*r+# i# a !ellEarchitected cla## li3rary that #i+pli9ie# the creati*n *9 the va#t +a4*rity *9 u#er inter9ace#) -t i# pr*gra++ed 3y a #erie# *9 pu3lic delegate pr*pertie# called e-ents that are a##*ciated !ith individual Control#) Control# c*ntain *ther Control#) = :orm i# a type *9 Control that take# the 9*r+ *9 a !ind*!) Control# are laid *ut !ithin their c*ntaining Control 3y +ean# *9 the Location, $oc(, and 'nchor pr*pertie#) Thi# lay*ut +*del i# #i+ple, 3ut n*t #i+pli#tic, and i9 c*+3ined !ith a pr*per attenti*n t* >Uarchitecture, can lead t* ea#ily +*di9ied, ea#yEt*Eu#e u#er inter9ace#) Pr*pertie# *9 Control# can 3e 3*und t* value# !ithin a $ata#et via a c*llecti*n *9 Binding#) O9ten, the 3*und pr*perty i# the ITe;tJ pr*perty *9 the Control) = c*llecti*n *9 Binding# +ay 3e c**rdinated 3y a Binding.anagerBase pr*vided 3y a BindingContext) Such c**rdinated Binding# !ill re9er t* a #ingle data rec*rd *r #et *9 pr*pertie# and thu#, Control# 3*und t* th*#e Binding# !ill #i+ultane*u#ly update) ,hile ,ind*!# 5*r+# i# !ellEarchitected, there are +any Duirk# and inc*n#i#tencie# in the vari*u# Control#) The#e Duirk# range 9r*+ !hat are clearly de9ect# GChec(edListBox6Chec(edBndexCollection include ite+# !h*#e check#tate i# indeterminateH, t* de#ign 9la!# Gther #h*uld 3e a Control6+ooltip pr*pertyH, t* und*cu+ented 3ehavi*r# G!hen handed an *34ect *9 illegal type, #h*uld B$ata1b)ect6#et1b)ect( ) thr*! an e;cepti*nFH, t* 3ehavi*r# that re9lect an underlying Duirk in the *perating #y#te+ Gthe #tring that #peci9ie# 1pen:ile$ialog6:ilterH) Ci#ual Studi* ) ET +ake# the creati*n *9 ,ind*!# 5*r+# inter9ace very ea#y 3ut i# n* #u3#titute 9*r !*rking directly !ith the i+ple+enting c*de) A*#t real applicati*n# !ill u#e a c*+3inati*n *9 Ci#ual ?e#ignerE generated c*de and handE!ritten i+ple+entati*n#) One !ay *r the *ther, the #ucce## *9 y*ur applicati*n i# dependent *n the u#a3ility *9 y*ur

Cha"ter 13* Creating Gindows = 5""lets

#(#

inter9aceQ i9 at all p*##i3le, !*rk !ith a c*+puterEhu+an inter9ace #peciali#t t* guide the creati*n *9 y*ur U-)

%&ercises

#(&

Thinking in C

www.ThinkingIn.!et

1 , G4IU Overview
,hile ,ind*!# 5*r+# pr*vide# a great 3a#i# 9*r #*+e large +a4*rity *9 u#er inter9ace#, the ) ET 5ra+e!*rk e;p*#e#

4rawing $i&els 4rawing sha$es 7illing and stro*ing Printing


?e+*n#trate# c*++*n dial*g# #kipped in previ*u# di#cu##i*n //:c"T:-rinting.c# //:e!on#trate# printing fro! Vindo.# Hor!# u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.:ra.ing.-rinting3

#('

u#ing Sy#te!.Vindo.#.Hor!#3 c a## -rinting : Hor! ; -aperVa#ter p. 9 ne. -aperVa#ter013 -rinting01; GainGenu !enu 9 ne. GainGenu013 Genu 9 !enu3 Genu5te! fGenu 9 ne. Genu5te!0&@Hi e&13 !enu.Genu5te!#.)dd0fGenu13 Genu5te! pr*Genu 9 ne. Genu5te!0&-@re*ie....&13 fGenu.Genu5te!#.)dd0pr*Genu13 pr*Genu.C ic% R9 ne. +*entUand er0On-re*ie.13 Genu5te! prtGenu 9 ne. Genu5te!0&@-rint...&13 fGenu.Genu5te!#.)dd0prtGenu13 prtGenu.C ic% R9 ne. +*entUand er0On-rint13 < pu$ ic *oid On-re*ie.0o$Dect #rc2 +*ent)rg# ea1; -rint-re*ie.:ia og ppd 9 ne. -rint-re*ie.:ia og013 ppd.:ocu!ent 9 p..:ocu!ent3 if0ppd.Sho.:ia og01 99 :ia ogRe#u t.Oa1; < < pu$ ic *oid On-rint0o$Dect #rc2 +*ent)rg# ea1;

#1(

-rint:ia og pd 9 ne. -rint:ia og013 pd.:ocu!ent 9 p..:ocu!ent3 if0pd.Sho.:ia og01 99 :ia ogRe#u t.Oa1; < < pu$ ic #tatic *oid Gain01; )pp ication.Run0ne. -rinting0113 < < c a## -aperVa#ter; -rint:ocu!ent pd 9 ne. -rint:ocu!ent013 interna -rint:ocu!ent :ocu!ent; get ; return pd3 < < interna -aperVa#ter01; pd.-rint-age R9 ne. -rint-age+*entUand er0-rint)-age13 < *oid -rint)-age0o$Dect #rc2 -rint-age+*ent)rg# ea1; _raphic# g 9 ea._raphic#3 Hont f 9 ne. Hont0&)ria &2 T?13 So idBru#h $ 9 ne. So idBru#h0Co or.B ac%13 -ointH p 9 ne. -ointH0"0.0f2 "0.0f13 g.:ra.String0&Reduce2 Reu#e2 Recyc e&2 f2 $2 p13 < <//:8

Cha"ter 13* Creating Gindows = 5""lets

#11

)ccessing 4irectT Creating a screensvaer Creating a s5ste# service >sage;Centered 4esign Creating an a$$lication 1Windows I @enus2
)#+ient Pro$erties )$$lication )$$licationConte&t )&9ost %rrorProvider 7eature'u$$ort 9el$ @essage @essage3o& (oti05Icon

#1)

Thinking in C

www.ThinkingIn.!et

Progress 3ar Pro$ert5Grid 'election6ange -a+Control? -a++ed Pages -i#er -ool3ar -rac*3ar >serControl

Windows 'ervices Progra##ing techniques


3inding events d5na#icall5 'e$arating +usiness logic 0ro# >I logic

8isual $rogra##ing 'u##ar5 %&ercises


Cha"ter 13* Creating Gindows = 5""lets #13

1 , @ultithreaded Progra##ing
O34ect# divide the #*luti*n #pace int* l*gical chunk# *9 #tate and 3ehavi*r) O9ten, y*u need gr*up# *9 y*ur *34ect# t* per9*r+ their 3ehavi*r #i+ultane*u#ly, a# independent #u3ta#k# that +ake up the !h*le)
Each *9 the#e independent #u3ta#k# i# called a thread, and y*u pr*gra+ a# i9 each thread run# 3y it#el9 and ha# the CPU t* it#el9) S*+e underlying +echani#+ i# actually dividing up the CPU ti+e 9*r y*u, 3ut in general, y*u d*nt have t* think a3*ut it, !hich +ake# pr*gra++ing !ith +ultiple thread# a +uch ea#ier ta#k) = "rocess i# a #el9Ec*ntained running pr*gra+ !ith it# *!n addre## #pace) = multitasking *perating #y#te+ i# capa3le *9 running +*re than *ne pr*ce## Gpr*gra+H at a ti+e, !hile +aking it l**k like each *ne i# chugging al*ng *n it# *!n, 3y peri*dically pr*viding CPU cycle# t* each pr*ce##) = thread i# a #ingle #eDuential 9l*! *9 c*ntr*l !ithin a pr*ce##) = #ingle pr*ce## can thu# have +ultiple c*ncurrently e;ecuting thread#)

#15

There are +any p*##i3le u#e# 9*r +ultithreading, 3ut in general, y*ull have #*+e part *9 y*ur pr*gra+ tied t* a particular event *r re#*urce, and y*u d*nt !ant t* hang up the re#t *9 y*ur pr*gra+ 3ecau#e *9 that) S* y*u create a thread a##*ciated !ith that event *r re#*urce and let it run independently *9 the +ain pr*gra+) = g**d e;a+ple i# a IcancelJ 3utt*n t* #t*p a lengthy calculati*n Ry*u d*nt !ant t* 3e 9*rced t* p*ll the cancel 3utt*n in every piece *9 c*de y*u !rite in y*ur pr*gra+ and yet y*u !ant the cancel 3utt*n t* 3e re#p*n#ive, a# i9 y*u were checking it regularly) -n 9act, *ne *9 the +*#t i++ediately c*+pelling rea#*n# 9*r +ultithreading i# t* pr*duce a re#p*n#ive u#er inter9ace)

#16

.(%-s -hreading @odel -hread 'cheduling -hreading Pro+le#s -he Cardinal 6ules o0 -hreading -hread Li0ec5cle 'tarting -hreads 'to$$ing -hreads Pausing and 6estarting 3loc*ing and Waiting %&ce$tion 9andling in -hreads -hreads and Intero$era+ilit5
Cha"ter 15* Cistri2uted Com"uting #1#

-hreads and Gar+age Collection -hreads and 'cala+ilit5 6es$onsive user inter0aces
=# a #tarting p*int, c*n#ider a pr*gra+ that per9*r+# #*+e CPUEinten#ive *perati*n and thu# end# up ign*ring u#er input and 3eing unre#p*n#ive) Thi# *ne #i+ply c*ver# the di#play in a rand*+ patch!*rk *9 red #p*t#1 //Wexa!p eZ ///WchapterZGu tithreadedW/chapterZ ///Wprogra!ZCounter".c#W/progra!Z // ) non6re#pon#i*e u#er interface. u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.'hreading3 c a## Counter" : Hor! ; int nu!$er'oCount'o3 Counter"0int nu!$er'oCount'o1 ; thi#.nu!$er'oCount'o 9 nu!$er'oCount'o3 C ientSiMe 9 ne. Sy#te!.:ra.ing.SiMe0P002 T0013 'ext 9 &Conre#pon#i*e interface&3 Button #tart 9 ne. Button013 #tart.'ext 9 &Start&3 #tart.Location 9 ne. -oint0"02 "013 #tart.C ic% R9 ne. +*entUand er0StartCounting13 Button onOff 9 ne. Button013 onOff.'ext 9 &'ogg e&3 onOff.Location 9 ne. -oint0"02 E013 onOff.C ic% R9 ne. +*entUand er0StopCounting13

#1&

Thinking in C

www.ThinkingIn.!et

Contro #.)ddRange0ne. Contro JK; #tart2 onOff <13 < pu$ ic *oid StartCounting0O$Dect #ender2 +*ent)rg# arg#1 ; Rectang e $ound# 9 Screen._etBound#0thi#13 int .idth 9 $ound#.Vidth3 int height 9 $ound#.Ueight3 _raphic# g 9 _raphic#.Hro!U.nd0thi#.Uand e13 -en pen 9 ne. -en0Co or.Red2 "13 Rando! rand 9 ne. Rando!013 runH ag 9 true3 for 0int i 9 03 runH ag @@ i W nu!$er'oCount'o3 iRR1 ; //:o #o!ething !i d y ti!e6con#u!ing int x 9 rand.Cext0.idth13 int y 9 rand.Cext0height13 g.:ra.Rectang e0pen2 x2 y2 "2 "13 'hread.S eep0"013 < < $oo runH ag 9 true3

pu$ ic *oid StopCounting0O$Dect #ender2 +*ent)rg# arg#1; runH ag 9 fa #e3 < pu$ ic #tatic *oid Gain01 ; )pp ication.Run0ne. Counter"0"0000113 < < //W/exa!p eZ =t thi# p*int, the graphic# c*de #h*uld 3e rea#*na3ly 9a+iliar 9r*+ Chapter 0/) The startCounting( ) +eth*d i# !here the pr*gra+ #tay# 3u#y1 it l**p# number+oCount+o ti+e#, pick# a rand*+ #p*t *n the 9*r+, and dra!# a 0Epi;el rectangle their)

Cha"ter 15* Cistri2uted Com"uting

#1'

Part *9 the l**p in#ide startCounting( ) call# +hread6#leep( )) ) +hread6#leep() pau#e# the currently e;ecuting thread 9*r #*+e a+*unt *9 +illi#ec*nd#) Regardle## *9 !hether y*ure e;plicitly u#ing thread#, y*u can pr*duce the current thread u#ed 3y y*ur pr*gra+ !ith +hread and the #tatic #leep( ) +eth*d) ,hen the #tart 3utt*n i# pre##ed, startCounting( ) i# inv*ked) On e;a+ining startCounting( ), y*u +ight think that it #h*uld all*! +ultithreading 3ecau#e it g*e# t* #leep) That i#, !hile the +eth*d i# a#leep, it #ee+# like the CPU c*uld 3e 3u#y +*nit*ring *ther 3utt*n pre##e#) But it turn# *ut that the real pr*3le+ i# that startCounting( ) d*e#nt return until a$ter it# 9ini#hed, and thi# +ean# that stopCounting( ) i# never called until it# t** late 9*r it# 3ehavi*r t* 3e +eaning9ul) Since y*ure #tuck in#ide startCounting( ) 9*r the 9ir#t 3utt*n pre##, the pr*gra+ cant handle any *ther event#) GT* get *ut, y*u +u#t either !ait until startCounting() end#, *r kill the pr*ce##Q the ea#ie#t !ay t* d* thi# i# t* pre## C*ntr*lEC *r t* click a c*uple ti+e# t* trigger ,ind*!# IPr*gra+ *t Re#p*ndingJ dial*gue)H The 3a#ic pr*3le+ here i# that startCounting( ) need# t* c*ntinue per9*r+ing it# *perati*n#, and at the #a+e ti+e it need# t* return #* that stopCounting( ) can 3e activated and the u#er inter9ace can c*ntinue re#p*nding t* the u#er) But in a c*nventi*nal +eth*d like startCounting( ) it cann*t c*ntinue and at the #a+e ti+e return c*ntr*l t* the re#t *9 the pr*gra+) Thi# #*und# like an i+p*##i3le thing t* acc*+pli#h, a# i9 the CPU +u#t 3e in t!* place# at *nce, 3ut thi# i# preci#ely the illu#i*n that threading pr*vide#) The thread +*del Gand it# pr*gra++ing #upp*rt in C#H i# a pr*gra++ing c*nvenience t* #i+pli9y 4uggling #everal *perati*n# at the #a+e ti+e !ithin a #ingle pr*gra+) ,ith thread#, the CPU !ill p*p ar*und and give each thread #*+e *9 it# ti+e) Each thread ha# the c*n#ci*u#ne## *9 c*n#tantly having the CPU t* it#el9, 3ut the CPU# ti+e i# actually #liced 3et!een all the thread#) The e;cepti*n t* thi# i# i9 y*ur pr*gra+ i# running *n +ultiple CPU#) But *ne *9 the great thing# a3*ut threading i# that y*u are a3#tracted a!ay 9r*+ thi# layer, #* y*ur c*de d*e# n*t need t* kn*! !hether it i# actually running *n a #ingle CPU *r +any) Thu#, thread# are a !ay t* create tran#parently #cala3le pr*gra+#)

#)(

Thinking in C

www.ThinkingIn.!et

Threading reduce# c*+puting e99iciency #*+e!hat, 3ut the net i+pr*ve+ent in pr*gra+ de#ign, re#*urce 3alancing, and u#er c*nvenience i# *9ten Duite valua3le) O9 c*ur#e, i9 y*u have +*re than *ne CPU, then the *perating #y#te+ can dedicate each CPU t* a #et *9 thread# *r even a #ingle thread and the !h*le pr*gra+ can run +uch 9a#ter) Aultita#king and +ultithreading tend t* 3e the +*#t rea#*na3le !ay# t* utili7e +ultipr*ce##*r #y#te+#)

Creating -hreads
T* u#e Thread# in C#, y*u #i+ply create a +hread *34ect and a delegate called +hread#tart) +hread take# care# *9 the underlying creati*n and +anage+ent *9 the thread, !hile +hread#tart #peci9ie# the actual c*de that !ill 3e e;ecuted !hen the thread i# active) Thu#, !hatever +eth*d i# pa##ed t* the +hread#tart c*n#truct*r i# the c*de that !ill 3e e;ecuted I#i+ultane*u#lyJ !ith the *ther thread# in a pr*gra+) The 9*ll*!ing e;a+ple create# any nu+3er *9 thread# that it keep# track *9 3y a##igning each thread a uniDue nu+3er, generated !ith a static varia3le) The delegated 3ehavi*r i# in the run( ) +eth*d, !hich i# *verridden t* c*unt d*!n each ti+e it pa##e# thr*ugh it# l**p and 9ini#he# !hen the c*unt i# 7er* Gat the p*int !hen the delegated +eth*d return#, the thread i# ter+inatedH) //Wexa!p eZ ///WchapterZc"EW/chapterZ ///Wprogra!ZSi!p e'hreading.c#W/progra!Z // Nery #i!p e 'hreading exa!p e. u#ing Sy#te!.'hreading3 pu$ ic c a## Si!p e'hreading ; pri*ate int count:o.n 9 P3 pri*ate #tatic int threadCount 9 03 pri*ate int threadCu!$er 9 RRthreadCount3 pu$ ic Si!p e'hreading01 ; Sy#te!.Con#o e.VriteLine0&Ga%ing & R threadCu!$er13 < pu$ ic *oid run01 ; .hi e0true1 ; Sy#te!.Con#o e.VriteLine0&'hread & R

Cha"ter 15* Cistri2uted Com"uting

#)1

threadCu!$er R &0& R count:o.n R &1&13 if066count:o.n 99 01 return3 < < pu$ ic #tatic *oid Gain01 ; for0int i 9 03 i W P3 iRR1; Si!p e'hreading #t 9 ne. Si!p e'hreading013 'hread a'hread 9 ne. 'hread0 ne. 'hreadStart0#t.run113 a'hread.Start013 < Sy#te!.Con#o e.VriteLine0&) 'hread# Started&13 < < //W/exa!p eZ = threadEdelegate +eth*d G*9ten called run( )H virtually al!ay# ha# #*+e kind *9 l**p that c*ntinue# until the thread i# n* l*nger nece##ary, #* y*u +u#t e#ta3li#h the c*nditi*n *n !hich t* 3reak *ut *9 thi# l**p G*r, in the ca#e a3*ve, #i+ply return 9r*+ run( )H) O9ten, run( ) i# ca#t in the 9*r+ *9 an in9inite l**p, !hich +ean# that, 3arring #*+e e;ternal 9act*r that cau#e# run( ) t* ter+inate, it !ill c*ntinue 9*rever) -n .ain( ) y*u can #ee a nu+3er *9 thread# 3eing created and run) The #tart( ) +eth*d in the +hread cla## per9*r+# the initiali7ati*n 9*r the thread and then call# run( )) S* the #tep# are1 the c*n#truct*r i# called t* 3uild the *34ect that !ill d* the !*rk, the +hread#tart delegate i# given the na+e *9 the !*rking 9uncti*n, the +hread#tart i# pa##ed t* a ne!ly created +hread, then #tart( ) c*n9igure# the thread and call# the delegated 9uncti*n EE run( )) -9 y*u d*nt call #tart( ), the thread !ill never 3e #tarted) The *utput 9*r *ne run *9 thi# pr*gra+ Git !ill 3e di99erent 9r*+ *ne run t* an*therH i#1 Ga%ing Ga%ing Ga%ing 'hread 'hread 'hread 'hread 'hread " 2 T "0P1 "0E1 "0T1 "021 "0"1

#))

Thinking in C

www.ThinkingIn.!et

Ga%ing E Ga%ing P ) 'hread# Started 'hread 20P1 'hread 20E1 'hread 20T1 'hread 2021 'hread 20"1 'hread P0P1 'hread P0E1 'hread P0T1 'hread P021 'hread P0"1 'hread E0P1 'hread E0E1 'hread E0T1 'hread E021 'hread E0"1 'hread T0P1 'hread T0E1 'hread T0T1 'hread T021 'hread T0"1 :*ull n*tice that n*!here in thi# e;a+ple i# +hread6#leep( ) called, and yet the *utput indicate# that each thread get# a p*rti*n *9 the CPU# ti+e in !hich t* e;ecute) Thi# #h*!# that #leep( ), !hile it relie# *n the e;i#tence *9 a thread in *rder t* e;ecute, i# n*t inv*lved !ith either ena3ling *r di#a3ling threading) -t# #i+ply an*ther +eth*d) :*u can al#* #ee that the thread# are n*t run in the *rder that theyre created) -n 9act, the *rder that the CPU attend# t* an e;i#ting #et *9 thread# i# indeter+inate, unle## y*u g* in and ad4u#t the Pri*rity pr*perty *9 the thread) ,hen .ain( ) create# the +hread *34ect# it i#nt capturing the re9erence# 9*r any *9 the+) Ot*d*1 Check thi#EW =n *rdinary *34ect !*uld 3e 9air ga+e 9*r gar3age c*llecti*n, 3ut n*t a +hread) Each +hread Iregi#ter#J it#el9 #* there i# actually a re9erence t* it #*+eplace and the gar3age c*llect*r cant clean it up)

Cha"ter 15* Cistri2uted Com"uting

#)3

-hreading 0or a res$onsive inter0ace


*! it# p*##i3le t* #*lve the pr*3le+ in Counter76cs !ith a thread) The trick i# t* +ake the !*rking +eth*d Rthat i#, the l**p that# in#ide stopCounting( )Ra delegate *9 a thread) ,hen the u#er pre##e# the start 3utt*n, the thread i# #tarted, 3ut then the creation *9 the thread c*+plete#, #* even th*ugh the thread i# running, the +ain 4*3 *9 the pr*gra+ G!atching 9*r and re#p*nding t* u#erEinter9ace event#H can c*ntinue) Here# the #*luti*n1 //Wexa!p eZ ///WchapterZGu tithreadedW/chapterZ ///Wprogra!ZCounter2.c#W/progra!Z // ) non6re#pon#i*e u#er interface. u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.'hreading3 c a## Counter2 : Hor! ; int nu!$er'oCount'o3 Counter20int nu!$er'oCount'o1 ; thi#.nu!$er'oCount'o 9 nu!$er'oCount'o3 C ientSiMe 9 ne. Sy#te!.:ra.ing.SiMe0P002 T0013 'ext 9 &Re#pon#i*e interface&3 Button #tart 9 ne. Button013 #tart.'ext 9 &Start&3 #tart.Location 9 ne. -oint0"02 "013 #tart.C ic% R9 ne. +*entUand er0StartCounting13 Button onOff 9 ne. Button013 onOff.'ext 9 &'ogg e&3 onOff.Location 9 ne. -oint0"02 E013 onOff.C ic% R9 ne. +*entUand er0StopCounting13 Contro #.)ddRange0ne. Contro JK; #tart2 onOff <13 <

#)4

Thinking in C

www.ThinkingIn.!et

pu$ ic *oid StartCounting0O$Dect #ender2 +*ent)rg# arg#1 ; 'hreadStart de 9 ne. 'hreadStart0paintScreen13 'hread t 9 ne. 'hread0de 13 t.Start013 < pu$ ic *oid paintScreen01; Rectang e $ound# 9 Screen._etBound#0thi#13 int .idth 9 $ound#.Vidth3 int height 9 $ound#.Ueight3 _raphic# g 9 _raphic#.Hro!U.nd0thi#.Uand e13 -en pen 9 ne. -en0Co or.Red2 "13 Rando! rand 9 ne. Rando!013 runH ag 9 true3 for 0int i 9 03 runH ag @@ i W nu!$er'oCount'o3 iRR1 ; //:o #o!ething !i d y ti!e6con#u!ing int x 9 rand.Cext0.idth13 int y 9 rand.Cext0height13 g.:ra.Rectang e0pen2 x2 y2 "2 "13 'hread.S eep0"013 < < $oo runH ag 9 true3

pu$ ic *oid StopCounting0O$Dect #ender2 +*ent)rg# arg#1; runH ag 9 fa #e3 < pu$ ic #tatic *oid Gain01 ; )pp ication.Run0ne. Counter20"0000113 < < //W/exa!p eZ

Cha"ter 15* Cistri2uted Com"uting

#)5

Counter8 i# a #traight9*r!ard pr*gra+, !h*#e *nly 4*3 i# t* #et up and +aintain the u#er inter9ace) But n*!, !hen the u#er pre##e# the start 3utt*n, the eventEhandling c*de d*e# n*t d* the ti+eEc*n#u+ing !*rk) -n#tead a thread i# created and #tarted, and then the Counter8 inter9ace can c*ntinue t* re#p*nd t* event#) ,hen y*u pre## the on1ff 3utt*n it t*ggle# the run:lag in#ide the Counter8 *34ect) Then, !hen the I!*rkerJ thread call# paint#creen(), it can l**k at that 9lag and decide !hether t* c*ntinue *r #t*p) Pre##ing the on1ff 3utt*n pr*duce# an apparently in#tant re#p*n#e) O9 c*ur#e, the re#p*n#e i#nt really in#tant, n*t like that *9 a #y#te+ that# driven 3y interrupt#) The painting #t*p# *nly !hen the thread ha# the CPU and n*tice# that the 9lag ha# changed)

'haring li#ited resources


:*u can think *9 a #ingleEthreaded pr*gra+ a# *ne l*nely entity +*ving ar*und thr*ugh y*ur pr*3le+ #pace and d*ing *ne thing at a ti+e) Becau#e there# *nly *ne entity, y*u never have t* think a3*ut the pr*3le+ *9 t!* entitie# trying t* u#e the #a+e re#*urce at the #a+e ti+e, like t!* pe*ple trying t* park in the #a+e #pace, !alk thr*ugh a d**r at the #a+e ti+e, *r even talk at the #a+e ti+e) ,ith +ultithreading, thing# arent l*nely any+*re, 3ut y*u n*! have the p*##i3ility *9 t!* *r +*re thread# trying t* u#e the #a+e li+ited re#*urce at *nce) C*lliding *ver a re#*urce +u#t 3e prevented *r el#e y*ull have t!* thread# trying t* acce## the #a+e 3ank acc*unt at the #a+e ti+e, print t* the #a+e printer, *r ad4u#t the #a+e valve, etc)

I#$ro$erl5 accessing resources


C*n#ider a variati*n *n the c*unter# that have 3een u#ed #* 9ar in thi# chapter) -n the 9*ll*!ing e;a+ple, each thread c*ntain# t!* c*unter# that are incre+ented and di#played in#ide run( )) -n additi*n, there# an*ther thread *9 cla## =atcher that i# !atching the c*unter# t* #ee i9 theyre al!ay# eDuivalent) Thi# #ee+# like a needle## activity, #ince l**king at the c*de it appear# *3vi*u# that the c*unter# !ill al!ay# 3e the #a+e) But that# !here the #urpri#e c*+e# in) Here# the 9ir#t ver#i*n *9 the pr*gra+1

#)6

Thinking in C

www.ThinkingIn.!et

//Wexa!p eZ ///WchapterZc"EW/chapterZ ///Wprogra!ZSharing".c#W/progra!Z // -ro$ e!# .ith re#ource #haring .hi e threading. u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.'hreading3 pu$ ic c a## Sharing" : Hor! ; pri*ate 'extBox acce##CountBox 9 ne. 'extBox013 pri*ate Button #tart 9 ne. Button013 pri*ate Button .atch 9 ne. Button013 pri*ate int acce##Count 9 03 pu$ ic *oid incre!ent)cce##01 ; acce##CountRR3 acce##CountBox.'ext 9 acce##Count.'oString013 < pri*ate int nu!Counter# 9 "23 pri*ate int nu!Vatcher# 9 "P3 pri*ate '.oCounterJK #3 pu$ ic Sharing"01 ; C ientSiMe 9 ne. SiMe0EP02 EI013 -ane p 9 ne. -ane 013 p.SiMe 9 ne. SiMe0E002 P013 #tart.C ic% R9 ne. +*entUand er0Start) .atch.C ic% R9 ne. +*entUand er0Start) Vatcher#13 'hread#13

acce##CountBox.'ext 9 &0&3 acce##CountBox.Location 9 ne. -oint0"02 "013 #tart.'ext 9 &Start thread#&3 #tart.Location 9 ne. -oint0""02 "013 .atch.'ext 9 &Begin .atching&3 .atch.Location 9 ne. -oint02"02 "013

Cha"ter 15* Cistri2uted Com"uting

#)#

p.Contro #.)dd0#tart13 p.Contro #.)dd0.atch13 p.Contro #.)dd0acce##CountBox13 # 9 ne. '.oCounterJnu!Counter#K3 for 0int i 9 03 i W #.Length3 iRR1 ; #JiK 9 ne. '.oCounter0ne. '.oCounter.5ncre!ent)cce##0incre!ent)cce##113 #JiK.Location 9 ne. -oint0"02 P0 R #JiK.Ueight = i13 Contro #.)dd0#JiK13 < thi#.C o#ed R9 ne. +*entUand er0Stop) Contro #.)dd0p13 < pu$ ic *oid Start) 'hread#0O$Dect #ender2 +*ent)rg# arg#1 ; for 0int i 9 03 i W #.Length3 iRR1 #JiK.Start013 < pu$ ic *oid Stop) 'hread#0O$Dect #ender2 +*ent)rg# arg#1; for0int i 9 03 i W #.Length3 iRR1; if0#JiK !9 nu 1; #JiK.Stop013 < < < pu$ ic *oid Start) Vatcher#0O$Dect #ender2 +*ent)rg# arg#1 ; for 0int i 9 03 i W nu!Vatcher#3 iRR1 ne. Vatcher0#13 < pu$ ic #tatic *oid Gain0#tringJK arg#1 ; Sharing" app 9 ne. Sharing"013 'hread#13

#)&

Thinking in C

www.ThinkingIn.!et

if 0arg#.Length Z 01 ; app.nu!Counter# 9 SByte.-ar#e0arg#J0K13 if 0arg#.Length 99 21 ; app.nu!Vatcher# 9 SByte.-ar#e0arg#J"K13 < < )pp ication.Run0app13 < < c a## '.oCounter : -ane ; pri*ate $oo #tarted 9 fa #e3 pri*ate La$e t"3 pri*ate La$e t23 pri*ate La$e $ 3 pri*ate 'hread t3 pri*ate int count" 9 02 count2 9 03 pu$ ic de egate *oid 5ncre!ent)cce##013 5ncre!ent)cce## de 3 // )dd the di#p ay co!ponent# pu$ ic '.oCounter05ncre!ent)cce## de 1 ; thi#.de 9 de 3 thi#.SiMe 9 ne. SiMe0TP02 T013 thi#.BorderSty e 9 BorderSty e.HixedT:3 t" 9 ne. La$e 013 t".Location 9 ne. -oint0"02 "013 t2 9 ne. La$e 013 t2.Location 9 ne. -oint0""02 "013 $ 9 ne. La$e 013 $ .'ext 9 &Count" 99 Count2&3 $ .Location 9 ne. -oint02"02 "013 Contro #.)ddRange0ne. Contro JK;t"2 t22 $ <13 //5nitia iMe the 'hread t 9 ne. 'hread0ne. 'hreadStart0run113 < pu$ ic *oid Start01 ;

Cha"ter 15* Cistri2uted Com"uting

#)'

if 0!#tarted1 ; #tarted 9 true3 t.Start013 < < pu$ ic *oid Stop01; t.)$ort013 < pu$ ic *oid run01 ; .hi e 0true1 ; t".'ext 9 RRcount".'oString013 t2.'ext 9 RRcount2.'oString013 'hread.S eep0P0013 < < pu$ ic *oid #ynch'e#t01 ; de 013 if 0count" !9 count21 $ .'ext 9 &On#ynched&3 < < c a## Vatcher ; '.oCounterJK #3 pu$ ic Vatcher0'.oCounterJK #1 ; thi#.# 9 #3 ne. 'hread0ne. 'hreadStart0run11.Start013 < pu$ ic *oid run01 ; .hi e 0true1 ; for 0int i 9 03 i W #.Length3 iRR1 #JiK.#ynch'e#t013 'hread.S eep0P0013 < < < //W/exa!p eZ

#3(

Thinking in C

www.ThinkingIn.!et

=# 3e9*re, each c*unter c*ntain# it# *!n di#play c*+p*nent#1 t!* te;t 9ield# and a la3el that initially indicate# that the c*unt# are eDuivalent) The#e c*+p*nent# are added t* the panel *9 the #haring7 *34ect in the #haring7 c*n#truct*r) Becau#e a +woCounter thread i# #tarted via a 3utt*n pre## 3y the u#er, it# p*##i3le that #tart( ) c*uld 3e called +*re than *nce) -t# illegal 9*r +hread6#tart( ) t* 3e called +*re than *nce 9*r a thread Gan e;cepti*n i# thr*!nH) :*u can #ee the +achinery t* prevent thi# in the started 9lag and the #tart( ) +eth*d) The accessCountBox in #haring7 keep# track *9 h*! +any t*tal acce##e# have 3een +ade *n all +woCounter thread#) One !ay t* d* thi# !*uld have 3een t* have a #tatic pr*perty that each +woCounter c*uld have incre+ented during synch+est()) -n#tead, !e declared an Bncrement'ccess() delegate !ithin +woCounter that #haring7 pr*vide# a# a para+eter t* the +woCounter c*n#truct*r) -n run( ), count7 and count8 are incre+ented and di#played in a +anner that !*uld #ee+ t* keep the+ identical) Then #leep( ) i# calledQ !ith*ut thi# call the U- 3ec*+e# unre#p*n#ive 3ecau#e all the CPU ti+e i# 3eing c*n#u+ed !ithin the l**p#) The synch+est( ) call# it# Bncrement'ccess delegate and then per9*r+# the apparently #uper9lu*u# activity *9 checking t* #ee i9 count7 i# eDuivalent t* count8Q i9 they are n*t eDuivalent it #et# the la3el t* IUn#ynchedJ t* indicate thi#) The =atcher cla## i# a thread !h*#e 4*3 i# t* call synch+est( ) 9*r all *9 the +woCounter *34ect# that are active) -t d*e# thi# 3y #tepping thr*ugh the array *9 +woCounters pa##ed t* it 3y the #haring7 *34ect) :*u can think *9 the =atcher a# c*n#tantly peeking *ver the #h*ulder# *9 the +woCounter *34ect#) #haring7 c*ntain# an array *9 +woCounter *34ect# that it initiali7e# in it# c*n#truct*r and #tart# a# thread# !hen y*u pre## the IStart Thread#J 3utt*n) Later, !hen y*u pre## the IBegin ,atchingJ 3utt*n, *ne *r +*re !atcher# are created and 9ree t* #py up*n the un#u#pecting +woCounter thread#)

Cha"ter 15* Cistri2uted Com"uting

#31

By changing the numCounters and num=atchers value#, !hich y*u can d* at the c*++andEline, y*ull change the 3ehavi*r *9 the pr*gra+) Here# the #urpri#ing part) -n +woCounter6run( ), the in9inite l**p i# 4u#t repeatedly pa##ing *ver the ad4acent line#1 t".'ext 9 RRcount".'oString013 t2.'ext 9 RRcount2.'oString013 Ga# !ell a# #leeping, 3ut that# n*t i+p*rtant hereH) ,hen y*u run the pr*gra+, h*!ever, y*ull di#c*ver that count7 and count8 !ill 3e *3#erved G3y the =atcher#H t* 3e uneDual at ti+e#K Thi# i# 3ecau#e *9 the nature *9 thread#Rthey can 3e #u#pended at any ti+e) S* at ti+e#, the #u#pen#i*n *ccur# 2etween the ti+e c*unt0 and c*unt2 are incre+ented, and the =atcher thread happen# t* c*+e al*ng and per9*r+ the c*+pari#*n at 4u#t thi# +*+ent, thu# 9inding the t!* c*unter# t* 3e di99erent) Thi# e;a+ple #h*!# a 9unda+ental pr*3le+ !ith u#ing thread#) :*u never kn*! !hen a thread +ight 3e run) -+agine #itting at a ta3le !ith a 9*rk, a3*ut t* #pear the la#t piece *9 9**d *n y*ur plate and a# y*ur 9*rk reache# 9*r it, the 9**d #uddenly vani#he# G3ecau#e y*ur thread !a# #u#pended and an*ther thread ca+e in and #t*le the 9**dH) That# the pr*3le+ that y*ure dealing !ith) =ny ti+e y*u rely *n the #tate *9 an *34ect 3eing c*n#i#tent, and that #tate can 3e +anipulated 3y a di99erent thread, y*u are vulnera3le t* thi# type *9 pr*3le+) Thi# i# !hat i# kn*!n a# a race condition G3ecau#e y*ur pr*gra+# pr*per 9uncti*ning i# dependent *n it# thread !inning the IraceJ t* the re#*urceH) Thi# type *9 3ug Gand all 3ug# relating t* threadingH i# di99icult t* track d*!n, a# they !ill *9ten #lip under the radar *9 y*ur unit te#ting c*de and appear and di#appear depending *n l*ad, hard!are and *perating #y#te+ di99erence#, and the !hi+#y *9 the 9ate#) Preventing thi# kind *9 c*lli#i*n i# #i+ply a +atter *9 putting a l*ck *n a re#*urce !hen *ne thread i# relying *n that re#*urce) The 9ir#t thread that acce##e# a re#*urce l*ck# it, and then the *ther thread# cann*t acce## that re#*urce until it i# unl*cked, at !hich ti+e an*ther thread l*ck# and u#e#

#3)

Thinking in C

www.ThinkingIn.!et

it, etc) -9 the 9r*nt #eat *9 the car i# the li+ited re#*urce, the child !h* #h*ut# I?i3#KJ a##ert# the l*ck)

>sing the @onitor class to $revent collisions Ktodo S con0ir# #echanis# o0 @onitor and add @ute& sa#$le code and Interloc*ed
RealE!*rld pr*gra+# have t* #hare +any type# *9 re#*urce# P net!*rk #*cket#, data3a#e c*nnecti*n#, #*und channel#, etc) By 9ar the +*#t c*++*n c*lli#i*n#, th*ugh, *ccur !hen #*+e thread# are changing the #tate# *9 *34ect# and *ther thread# are relying *n the #tate 3eing c*n#i#tent) Thi# i# the ca#e !ith *ur +woCounter and =atcher *34ect#, !here a thread c*ntr*lled 3y +woCounter incre+ent# the count7 and count8 varia3le#, !hile a thread c*ntr*lled 3y =atcher check# the#e varia3le# 9*r c*n#i#tency) The A*nit*r cla## in the na+e#pace Sy#te+)Threading help# prevent c*lli#i*n# *ver *34ect #tate) Every ob)ect in C# ha# an a##*ciated I#ynchr*ni7ati*n 3l*ckJ *34ect !hich +aintain# a l*ck 9*r that *34ect and a Dueue *9 thread# !aiting t* acce## the l*ck) The .onitor cla## i# the pu3lic inter9ace t* the 3ehindEtheE#cene# #ync 3l*ck i+ple+entati*n) The +eth*d .onitor6&nter( ob)ect o) act# a# gatekeeper P !hen a thread e;ecute# thi# line, the #ynchr*ni7ati*n 3l*ck 9*r o i# checkedQ i9 n* *ne currently ha# the l*ck, the thread get# the l*ck and pr*ce##ing c*ntinue#, 3ut i9 an*ther thread ha# already acDuired the l*ck, the thread !ait#, *r I3l*ck#,J until the l*ck 3ec*+e# availa3le) ,hen the critical #ecti*n *9 c*de ha# 3een e;ecuted, the thread #h*uld call .onitor6&xit( ob)ect o) t* relea#e the l*ck) The ne;t 3l*cking thread !ill then 3e given a chance t* *3tain the l*ck) Becau#e y*u virtually al!ay# !ant t* relea#e the l*ck *n a thread at the end *9 a critical #ecti*n, even !hen thr*!ing an &xception, call# t* .onitor6&nter() and .onitor6&xit() are u#ually !rapped in a try 3l*ck1 try;

Cha"ter 15* Cistri2uted Com"uting

#33

Gonitor.+nter0o13 //critica #ection <fina y; Gonitor.+xit0o13 <

'5nchroni:ing the counters


=r+ed !ith thi# techniDue it appear# that the #*luti*n i# at hand1 !ell u#e the A*nit*r cla## t* #ynchr*ni7e acce## t* the c*unter#) The 9*ll*!ing e;a+ple i# the #a+e a# the previ*u# *ne, !ith the additi*n *9 .onitor6&nter/&xit call# at the t!* critical #ecti*n#1 //Wexa!p eZ ///WchapterZc"EW/chapterZ ///Wprogra!ZSharing2.c#W/progra!Z // O#ing Gonitor.enter01 and exit01 u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.'hreading3 pu$ ic c a## Sharing" : Hor! ; pri*ate 'extBox aCount 9 ne. 'extBox013 pri*ate Button #tart 9 ne. Button013 pri*ate Button .atch 9 ne. Button013 pri*ate int acce##Count 9 03 pu$ ic *oid incre!ent)cce##01 ; acce##CountRR3 aCount.'ext 9 acce##Count.'oString013 < pri*ate int nu!Counter# 9 "23 pri*ate int nu!Vatcher# 9 "P3 pri*ate '.oCounterJK #3 pri*ate VatcherJK .3 pu$ ic Sharing"01 ; C ientSiMe 9 ne. SiMe0EP02 EI013 -ane p 9 ne. -ane 013

#34

Thinking in C

www.ThinkingIn.!et

p.SiMe 9 ne. SiMe0E002 P013 #tart.C ic% R9 ne. +*entUand er0Start) .atch.C ic% R9 ne. +*entUand er0Start) Vatcher#13 aCount.'ext 9 &0&3 aCount.Location 9 ne. -oint0"02 "013 #tart.'ext 9 &Start thread#&3 #tart.Location 9 ne. -oint0""02 "013 .atch.'ext 9 &Begin .atching&3 .atch.Location 9 ne. -oint02"02 "013 p.Contro #.)dd0#tart13 p.Contro #.)dd0.atch13 p.Contro #.)dd0aCount13 # 9 ne. '.oCounterJnu!Counter#K3 for 0int i 9 03 i W #.Length3 iRR1 ; #JiK 9 ne. '.oCounter0ne. '.oCounter.5ncre!ent)cce##0incre!ent)cce##113 #JiK.Location 9 ne. -oint0"02 P0 R #JiK.Ueight = i13 Contro #.)dd0#JiK13 < thi#.C o#ed R9 ne. +*entUand er0Stop) Contro #.)dd0p13 < pu$ ic *oid Start) 'hread#0O$Dect #ender2 +*ent)rg# arg#1 ; for 0int i 9 03 i W #.Length3 iRR1 #JiK.Start013 < pu$ ic *oid Stop) 'hread#0O$Dect #ender2 +*ent)rg# arg#1; for0int i 9 03 i W #.Length3 iRR1; if0#JiK !9 nu 1; 'hread#13 'hread#13

Cha"ter 15* Cistri2uted Com"uting

#35

#JiK.Stop013 < < for0int i 9 03 i W ..Length3 iRR1; if0.JiK !9 nu 1; .JiK.Stop013 < < < pu$ ic *oid Start) Vatcher#0O$Dect #ender2 +*ent)rg# arg#1 ; . 9 ne. VatcherJnu!Vatcher#K3 for 0int i 9 03 i W nu!Vatcher#3 iRR1 .JiK 9 ne. Vatcher0#13 < pu$ ic #tatic *oid Gain0#tringJK arg#1 ; Sharing" app 9 ne. Sharing"013 if 0arg#.Length Z 01 ; app.nu!Counter# 9 SByte.-ar#e0arg#J0K13 if 0arg#.Length 99 21 ; app.nu!Vatcher# 9 SByte.-ar#e0arg#J"K13 < < )pp ication.Run0app13 < < c a## '.oCounter : -ane ; pri*ate $oo #tarted 9 fa #e3 pri*ate La$e t"3 pri*ate La$e t23 pri*ate La$e $ 3 pri*ate 'hread t3 pri*ate int count" 9 02 count2 9 03 pu$ ic de egate *oid 5ncre!ent)cce##013 5ncre!ent)cce## de 3 // )dd the di#p ay co!ponent#

#36

Thinking in C

www.ThinkingIn.!et

pu$ ic '.oCounter05ncre!ent)cce## de 1 ; thi#.de 9 de 3 thi#.SiMe 9 ne. SiMe0TP02 T013 thi#.BorderSty e 9 BorderSty e.HixedT:3 t" 9 ne. La$e 013 t".Location 9 ne. -oint0"02 "013 t2 9 ne. La$e 013 t2.Location 9 ne. -oint0""02 "013 $ 9 ne. La$e 013 $ .'ext 9 &Count" 99 Count2&3 $ .Location 9 ne. -oint02"02 "013 Contro #.)ddRange0ne. Contro JK;t"2 t22 $ <13 //5nitia iMe the 'hread t 9 ne. 'hread0ne. 'hreadStart0run113 < pu$ ic *oid Start01 ; if 0!#tarted1 ; #tarted 9 true3 t.Start013 < < pu$ ic *oid Stop01; t.)$ort013 < pu$ ic *oid run01 ; .hi e 0true1 ; try; Gonitor.+nter0thi#13 t".'ext 9 0RRcount"1.'oString013 t2.'ext 9 0RRcount21.'oString013 <fina y; Gonitor.+xit0thi#13 < 'hread.S eep0P0013 < < pu$ ic *oid #ynch'e#t01 ;

Cha"ter 15* Cistri2uted Com"uting

#3#

de 013 try ; Gonitor.+nter0thi#13 if 0count" !9 count21 ; $ .'ext 9 &On#ynched&3 < < fina ; < < < c a## Vatcher ; '.oCounterJK #3 'hread t3 pu$ ic Vatcher0'.oCounterJK #1 ; thi#.# 9 #3 t 9 ne. 'hread0ne. 'hreadStart0run113 t.Start013 < pu$ ic *oid run01 ; .hi e 0true1 ; for 0int i 9 03 i W #.Length3 iRR1 #JiK.#ynch'e#t013 'hread.S eep0P0013 < < pu$ ic *oid Stop01; t.)$ort013 < < //W/exa!p eZ y Gonitor.+xit0thi#13

#3&

Thinking in C

www.ThinkingIn.!et

:*ull n*tice that 2oth run( ) and synch+est( ) call .onitor6&nter() and &xit()6 -9 y*u u#e the .onitor *nly *n run(), the =atcher thread# calling synch+est() !ill happily read the #tate *9 the +woCounter even !hile the +woCounter thread ha# entered the critical #ecti*n and ha# placed the *34ect in an inc*n#i#tent #tate 3y incre+enting Counter7 3ut n*t yet changing Counter8) There# n*thing +agic a3*ut thread #ynchr*ni7ati*n P it# the +anipulati*n *9 the +woCounter in#tance# #ync 3l*ck via the .onitor that d*e# the !*rk) =ll #ynchr*ni7ati*n depend# *n pr*gra++er diligence1 every piece *9 c*de that can place an *34ect in an inc*n#i#tent #tate *r that relie# *n an *34ect 3eing in a c*n#i#tent #tate +u#t 3e !rapped in an appr*priate 3l*ck)

Gloc*H +loc*s S a shortcut 0or using the @onitor


-n *rder t* #ave y*u #*+e ti+e typing, C# pr*vide# the loc( key!*rd, !hich create# a guarded c*de3l*ck e;actly eDuivalent t* the try/ .onitor6&nter()`0finally/.onitor6&xit()0 idi*+) -n#tead *9 all that typing, y*u u#e the loc((ob)ect) key!*rd and #peci9y a c*de 3l*ck t* 3e pr*tected1 oc%0thi#1; //critica < =lth*ugh loc(()# 9*r+ +ake# it appear t* 3e a call t* a 3a#e cla## +eth*d Gi+ple+ented 3y ob)ect pre#u+a3lyH, it# really 4u#t #yntactic #ugar) The ch*ice *9 loc( a# a key!*rd +ay 3e a little +i#leading, in that y*u +ay e;pect that a Il*ckedJ *34ect !*uld 3e aut*+atically thread#a9e) Thi# i# n*t #*Q loc( #ay# that the current thread !ill act appr*priately) -9 all thread# 9*ll*! the rule#, thing# !ill !*rk *ut 9*r the 3e#t, 3ut i9 an*ther piece *9 c*de ha# a re9erence t* the Il*ckedJ *34ect, it +ay +i#takenly +anipulate the *34ect !ith*ut ever u#ing .onitor) -t# like taking a nu+3er 9*r #ervice at a 3akery P a 9ine idea that 3reak# d*!n a# #**n a# #*+e*ne +i#3ehave# thr*ugh la7ine## *r ign*rance) #ection

Cha"ter 15* Cistri2uted Com"uting

#3'

Choosing what to #onitor


.onitor6&nter() and &xit() can 3e pa##ed any *34ect 9*r #ynchr*ni7ati*n) -t i# 3e#t t* u#e this P an ina3ility t* u#e this 9*r #ynchr*ni7ati*n Gperhap# 3ecau#e y*u have +utually e;clu#ive type# *9 inc*n#i#tency t* guard again#tH i# a Ic*de #+ellJ that indicate# that y*ur *34ect +ay 3e trying t* d* t** +any thing# at *nce and +ay 3e 3e#t 3r*ken up int* #+aller cla##e#) 5*r in#tance, in the T!*C*unter cla##, !e c*uld place counter7 and counter8 in an inner class, add threadE#a9e acce##*r# and +eth*d#, and achieve *ur g*al !ith*ut ever l*cking the entire +wo!anel in#tance1 //Wexa!p eZ ///WchapterZc"EW/chapterZ ///Wprogra!ZSharingT.c#W/progra!Z // Refactoring for finer granu arity u#ing Sy#te!3 u#ing Sy#te!.:ra.ing3 u#ing Sy#te!.Vindo.#.Hor!#3 u#ing Sy#te!.'hreading3 pu$ ic c a## SharingT : Hor! ; pri*ate 'extBox aCount 9 ne. 'extBox013 pri*ate Button #tart 9 ne. Button013 pri*ate Button .atch 9 ne. Button013 pri*ate int acce##Count 9 03 pu$ ic *oid incre!ent)cce##01 ; acce##CountRR3 aCount.'ext 9 acce##Count.'oString013 < pri*ate int nu!Counter# 9 "23 pri*ate int nu!Vatcher# 9 "P3 pri*ate '.oCounterJK #3 pri*ate VatcherJK .3 pu$ ic Sharing"01 ; C ientSiMe 9 ne. SiMe0EP02 EI013 -ane p 9 ne. -ane 013

#4(

Thinking in C

www.ThinkingIn.!et

p.SiMe 9 ne. SiMe0E002 P013 #tart.C ic% R9 ne. +*entUand er0Start) .atch.C ic% R9 ne. +*entUand er0Start) Vatcher#13 aCount.'ext 9 &0&3 aCount.Location 9 ne. -oint0"02 "013 #tart.'ext 9 &Start thread#&3 #tart.Location 9 ne. -oint0""02 "013 .atch.'ext 9 &Begin .atching&3 .atch.Location 9 ne. -oint02"02 "013 p.Contro #.)dd0#tart13 p.Contro #.)dd0.atch13 p.Contro #.)dd0aCount13 # 9 ne. '.oCounterJnu!Counter#K3 for 0int i 9 03 i W #.Length3 iRR1 ; #JiK 9 ne. '.oCounter0ne. '.oCounter.5ncre!ent)cce##0incre!ent)cce##113 #JiK.Location 9 ne. -oint0"02 P0 R #JiK.Ueight = i13 Contro #.)dd0#JiK13 < thi#.C o#ed R9 ne. +*entUand er0Stop) Contro #.)dd0p13 < pu$ ic *oid Start) 'hread#0O$Dect #ender2 +*ent)rg# arg#1 ; for 0int i 9 03 i W #.Length3 iRR1 #JiK.Start013 < pu$ ic *oid Stop) 'hread#0O$Dect #ender2 +*ent)rg# arg#1; for0int i 9 03 i W #.Length3 iRR1; if0#JiK !9 nu 1; 'hread#13 'hread#13

Cha"ter 15* Cistri2uted Com"uting

#41

#JiK.Stop013 < < for0int i 9 03 i W ..Length3 iRR1; if0.JiK !9 nu 1; .JiK.Stop013 < < < pu$ ic *oid Start) Vatcher#0O$Dect #ender2 +*ent)rg# arg#1 ; . 9 ne. VatcherJnu!Vatcher#K3 for 0int i 9 03 i W nu!Vatcher#3 iRR1 .JiK 9 ne. Vatcher0#13 < pu$ ic #tatic *oid Gain0#tringJK arg#1 ; SharingT app 9 ne. SharingT013 if 0arg#.Length Z 01 ; app.nu!Counter# 9 SByte.-ar#e0arg#J0K13 if 0arg#.Length 99 21 ; app.nu!Vatcher# 9 SByte.-ar#e0arg#J"K13 < < )pp ication.Run0app13 < < c a## '.oCounter : -ane ; pri*ate $oo #tarted 9 fa #e3 pri*ate La$e t"3 pri*ate La$e t23 pri*ate La$e $ 3 pri*ate 'hread t3 c a## Counter ; pri*ate int c" 9 03 pri*ate int c2 9 03

#4)

Thinking in C

www.ThinkingIn.!et

pu$ ic *oid 5ncre!ent01 ; oc%0thi#1 ; RRc"3 RRc23 < < pu$ ic int Count" ; get; oc%0thi#1; return c"3< < < pu$ ic int Count2 ; get; oc%0thi#1; return c23 < < < < pri*ate Counter counter 9 ne. Counter013 pu$ ic de egate *oid 5ncre!ent)cce##013 5ncre!ent)cce## de 3 // )dd the di#p ay co!ponent# pu$ ic '.oCounter05ncre!ent)cce## de 1 ; thi#.de 9 de 3 thi#.SiMe 9 ne. SiMe0TP02 T013 thi#.BorderSty e 9 BorderSty e.HixedT:3 t" 9 ne. La$e 013 t".Location 9 ne. -oint0"02 "013 t2 9 ne. La$e 013 t2.Location 9 ne. -oint0""02 "013 $ 9 ne. La$e 013 $ .'ext 9 &Count" 99 Count2&3 $ .Location 9 ne. -oint02"02 "013 Contro #.)ddRange0ne. Contro JK;t"2 t22 $ <13 //5nitia iMe the 'hread t 9 ne. 'hread0ne. 'hreadStart0run113

Cha"ter 15* Cistri2uted Com"uting

#43

< pu$ ic *oid Start01 ; if 0!#tarted1 ; #tarted 9 true3 t.Start013 < < pu$ ic *oid Stop01; t.)$ort013 < pu$ ic *oid run01 ; .hi e 0true1 ; counter.5ncre!ent013 t".'ext 9 counter.Count".'oString013 t2.'ext 9 counter.Count2.'oString013 'hread.S eep0P0013 < < pu$ ic *oid #ynch'e#t01 ; de 013 if0counter.Count" !9 counter.Count21 ; $ .'ext 9 &On#ynched&3 < < < c a## Vatcher ; '.oCounterJK #3 'hread t3 pu$ ic Vatcher0'.oCounterJK #1 ; thi#.# 9 #3 t 9 ne. 'hread0ne. 'hreadStart0run113 t.Start013 < pu$ ic *oid run01 ; .hi e 0true1 ;

#44

Thinking in C

www.ThinkingIn.!et

for 0int i 9 03 i W #.Length3 iRR1 #JiK.#ynch'e#t013 'hread.S eep0P0013 < < pu$ ic *oid Stop01; t.)$ort013 < < //W/exa!p eZ

The Counter cla##, an inner cla## *9 +wo!anel i# n*! IthreadE#a9e,J 3y re+*ving any chance that an e;ternal *34ect can place it in an inc*n#i#tent #tate) -ncre+enting the c*unter integer# i# d*ne in#ide the Bncrement +eth*d, !ith a loc(ed critical #ecti*n, and acce## t* the integer# i# d*ne via the Count7 and Count8 pr*pertie#, !hich al#* #ynchr*ni7e again#t the A*nit*r t* en#ure that they cann*t 3e read until the Bncrement critical #ecti*n ha# e;ited Gand, unde#ira3ly, al#* en#ure that Count7 and Count8 cann*t 3e read #i+ultane*u#ly 3y t!* di99erent thread# P a #+all penalty typical *9 the de#ign deci#i*n# +ade !hen devel*ping +ultithreaded app#H) S*+eti+e#, l*cking this d*e#nt #ee+ like the right idea) ,hen an *34ect c*ntain# #*+e re#*urce, and e#pecially !hen that re#*urce i# a c*ntainer *9 #*+e #*rt, #uch a# a Collection *r a #tream *r an Bmage, it i# c*++*n t* !ant t* per9*r+ #*+e *perati*n acr*## #*+e #u3#et *9 that re#*urce !ith*ut !*rrying a3*ut !hether #*+e *ther thread !ill change the re#*urce hal9!ay thr*ugh y*ur *perati*n) -n a #ituati*n like thi#, it# c*++*n t* l*ck the re#*urce, n*t this6 -+ *9 t!* +ind# *n thi#1 *n the *ne hand, the principle *9 c*upling lead# t* the th*ught that i9 the *nly thing that# vulnera3le t* 3eing placed in an inc*n#i#tent #tate i# the re#*urce, then l*ck the re#*urce, a# l*cking this unnece##arily c*uple# this and the re#*urce) On the *ther hand, the principle *9 c*he#i*n lead# u# t* think that i9 *ne p*rti*n *9 the +eth*d# and re#*urce# in an in#tance are vulnera3le t* race c*nditi*n#, 3ut *ther +eth*d# and re#*urce# in the in#tance arent, then +ay3e !e *ught t* re9act*r) Thi# i#

Cha"ter 15* Cistri2uted Com"uting

#45

!hat !e did !ith *ur +wo!anel cla##, #plitting the initial cla## int* t!*, and - think #haring9 i# clearly a #uperi*r de#ign t* #haring86

Where to #onitor
=n *34ect# threadE#a9ety i# entirely a 9uncti*n *9 the *34ect# #tate) = cla## !ith*ut any #tatic *r in#tance varia3le#, c*n#i#ting #*lely *9 +eth*d#, i# inherently thread#a9e) =ny varia3le# *r re#*urce# that a99ect !hether y*ur *34ect i# in a c*n#i#tent #tate #h*uld 3e private *r protected and *nly availa3le t* *ut#ide *34ect# 3y !ay *9 pr*pertie# *r +eth*d#) -t# 4u#t 9**li#h t* ever all*! direct re9erence# t* the#e critical re#*urce# 9r*+ e;ternal *34ect#) -9 in#tead y*u create pr*pertie# and +eth*d# !hich c*n#i#tently u#e the .onitor cla## G*r the eDuivalent loc( 3l*ck#H, y*ull #ave y*ur#el9 c*n#idera3le headache# !hen it c*+e# t* l*cating and de3ugging threading pr*3le+#)

-hreads and Collections


The C*llecti*n cla##e# in ) ET# #ystem6Collections na+e#pace are n*t thread#a9e and 3ehavi*r i# Iunde9inedJ !hen c*lli#i*n# *ccur) Thi# pr*gra+ illu#trate# the i##ue1 //Wexa!p eZ u#ing Sy#te!3 u#ing Sy#te!.Co ection#3 u#ing Sy#te!.'hreading3 c a## SyncCo "; pu$ ic #tatic *oid Gain01; int i'hread# 9 2P3 SyncCo " #c" 9 ne. SyncCo "0i'hread#13 < int i'hread#3 SortedLi#t !yLi#t3 pu$ ic SyncCo "0int i'hread#1; thi#.i'hread# 9 i'hread#3 !yLi#t 9 ne. SortedLi#t013 'i!edVrite0!yLi#t13 !yLi#t 9 SortedLi#t.SynchroniMed0ne. SortedLi#t0113

#46

Thinking in C

www.ThinkingIn.!et

'i!edVrite0!yLi#t13 < pu$ ic *oid 'i!edVrite0SortedLi#t !yLi#t1; Vriter'hread.+xceptionCount 9 03 Vriter'hreadJK .riter'hread# 9 ne. Vriter'hreadJi'hread#K3 :ate'i!e #tart 9 :ate'i!e.Co.3 for0int i 9 03 i W i'hread#3 iRR1; .riter'hread#JiK 9 ne. Vriter'hread0!yLi#t2 i13 .riter'hread#JiK.Start013 < VaitHor) 'hread#0.riter'hread#13 :ate'i!e #top 9 :ate'i!e.Co.3 'i!eSpan e ap#ed 9 #top 6 #tart3 Sy#te!.Con#o e.VriteLine0&SynchroniMed Li#t: & R !yLi#t.5#SynchroniMed13 Sy#te!.Con#o e.VriteLine0i'hread# R & = P000 9 & R !yLi#t.Count R &Y & R 0!yLi#t.Count 99 0i'hread# = P0001113 Sy#te!.Con#o e.VriteLine0&Cu!$er of exception# thro.n: & R Vriter'hread.+xceptionCount13 Sy#te!.Con#o e.VriteLine0&'i!e of ca cu ation 9 & R e ap#ed13 < pu$ ic *oid VaitHor) 'hread#0Vriter'hreadJK t#1; for0int i 9 03 i W t#.Length3 iRR1; .hi e0t#JiK.Hini#hed 99 fa #e1; 'hread.S eep0"00013 < < < < c a## Vriter'hread ; #tatic int i+xception#'hro.n 9 03 pu$ ic #tatic int +xceptionCount; get; return i+xception#'hro.n3 < #et; i+xception#'hro.n 9 *a ue3 <

Cha"ter 15* Cistri2uted Com"uting

#4#

< 'hread t3 SortedLi#t theLi#t3 pu$ ic Vriter'hread0SortedLi#t theLi#t2 int i1; t 9 ne. 'hread0ne. 'hreadStart0Vrite'hread113 t.5#Bac%ground 9 true3 t.Ca!e 9 &VriterJ& R i.'oString01 R &K&3 thi#.theLi#t 9 theLi#t3 < pu$ ic $oo Hini#hed; get; return i#Hini#hed3 < < $oo i#Hini#hed 9 fa #e3 pu$ ic *oid Vrite'hread01; for0int oop 9 03 oop W P0003 oopRR1; String e Ca!e 9 t.Ca!e R oop.'oString013 try; theLi#t.)dd0e Ca!e2 e Ca!e13 <catch0+xception 1; RRi+xception#'hro.n3 < < i#Hini#hed 9 true3 t.)$ort013 < pu$ ic *oid Start01; t.Start013 < < //W/exa!p eZ The .ain() create# a #yncCol7 cla## !ith a para+eter indicating h*! +any thread# t* #i+ultane*u#ly !rite t* a c*llecti*n) = #ortedList i# created and pa##ed t* the +imed=rite +eth*d) Thi# +eth*d #et# the #tatic varia3le &xceptionCount *9 the =riter+hread cla## t* $ and create# an array *9 =riter+hread#) The =riter+hread c*n#truct*r take# the li#t and a varia3le) Each =riter+hread create# a ne! thread, !h*#e pr*ce##ing i# delegated t* the =riter+hread6=rite+hread()

#4&

Thinking in C

www.ThinkingIn.!et

+eth*d) The Bac(ground pr*perty *9 the =riter+hread# thread i# #et t* true) = pr*gra+ !*nt e;it until all it# n*nE3ackgr*und thread# have ended) Being a3le t* create 3ackgr*und Idae+*nJ thread# i# very c*nvenient, e#pecially in a >U-, !here the u#er can reDue#t a pr*gra+ cl*#ure at any ti+e) =9ter the =riter+hread c*n#truct*r return#, the ne;t line *9 +imed=rite() call# the #tart() +eth*d, !hich in turn #tart# the inner thread, !hich in turn delegate# pr*ce##ing t* =rite+hread()6 =rite+hread() l**p# ',$$$ ti+e#, each ti+e creating a ne! na+e G#uch a# I,riterZ02\2/%JH and atte+pting t* add that t* theList) = #orted'rray i# 3acked 3y t!* #t*re# P *ne t* #t*re the value# and an*ther t* #t*re a #*rted li#t *9 key# Gthe key# +ay *r +ay n*t 3e the #a+e a# the value#H) The #*rted li#t i# #t*red in a data #tructure called a I3alanced treeJ G+*re #peci9ically, - 3elieve it i# 3acked 3y a IredE3lackJ treeH) IBalanced tree#J have the pr*perty that l**king up any ite+ happen# in a ti+e pr*p*rti*nal t* the l*garith+ *9 the t*tal nu+3er *9 ite+# #t*red) ,hen #peaking *9 alg*rith+ic e99iciency, it i# 3e#t t* ign*re the actual nu+3er *9 in#tructi*n# inv*lved and *nly c*ncentrate *n the *rder *9 the e;p*nential increa#e a##*ciated !ith #caling the alg*rith+) The actual nu+3er *9 #tep#, a9ter all, varie# 9r*+ pr*gra++ing language t* pr*gra++ing language and c*+puter #peed# increa#e c*n#tantly) S* !hat reall4 +atter# 3*il# d*!n t* !hat# called IBig OJ n*tati*n P a redE3lack tree d*e# a l**kup in OGl*g nH #tep#) =n un#*rted array, *n the *ther hand, reDuire# OGnH #tep# t* #earch G*n average, y*ull 9ind an ite+ in n<2 c*+pari#*n#, 3ut 9*r the purp*#e# *9 IBig OJ c*nver#ati*n#, y*u dr*p everything 3ut the e;p*nentH) But i9 y*u !ant really 9a#t retrieval, the "ashtable cla## d*e# a l**kup in OG0H #tep# P !hat# called Ic*n#tant ti+e)J O9 c*ur#e, a# Ta3le % #h*!#, 9*r every advantage, there# a di#advantage) C*llecti*n Cla## =rrayLi#t Bit=rray -n#ert OG0H ?elete L**kup

Cha"ter 15* Cistri2uted Com"uting

#4'

Ha#hta3le Mueue S*rtedLi#t Stack OGl*g nH OGl*g nH

OG0H

OGl*g nH

The large +a4*rity *9 e99*rt that pr*gra++er# e;pend *n e99iciency and *pti+i7ati*n and per9*r+ance ign*re# Big O e99iciency and c*ncentrate# *n trivial a#pect# *9 re+*ving an inter+ediate a##ign+ent here, packing t!ice a# +uch data in a varia3le *ver there, and #* 9*rth) ?*nt 9all 9*r thi# +i#take P i9 it# n*t Big O e99iciency, it# al+*#t certainly n*t !*rth paying attenti*n t*) On !hat - pr*+i#e i# the la#t tangent 3e9*re getting 3ack t* thread#, the 3ig +agic in Duantu+ c*+puter# i# that they reduce the alg*rith+ic c*#t *9 r*tating an nEdi+en#i*nal hyper#phere 9r*+ OGn2H t* OG0H) -9 +y analy#i# i# c*rrect, thi# +ean# that any pr*3le+ y*u can #*lve 3y +anipulating a Ru3ik# cu3e !hile !earing a 3lind9*ld can 3e #*lved 3y a t!*EDu3it Duantu+ c*+puter in c*n#tant ti+e) Have at it, gang) Back t* =riter+hread6=rite+hread()) The call t* 'dd() an ele+ent t* the li#t i# !rapped in a catch 3l*ck) Since !e are ign*ring the detail# *9 the e;cepti*n and *nly rec*rding h*! +any e;cepti*n# !ere thr*!n, the catch #tate+ent d*e# n*t #peci9y a varia3le na+e 9*r the caught e;cepti*n) Once the l**p i# 9ini#hed, !e #et the :inished pr*perty *9 the =riter+hread, kill the Thread, and return) Back in the #yncCol7 cla##, the +ain applicati*n thread g*e# thr*ugh the array, checking t* #ee i9 it# 9ini#hed) -9 it# n*t, the +ain thread g*e# t* #leep 9*r 0,$$$ #ec*nd# 3e9*re checking again) ,hen all the =riter+hread# are :inished, the =rite+hread() !rite# #*+e data *n the e;peri+ent and return#) =9ter the initial call !ith a regular #ortedList, !e create a ne! #ortedList and pa## it t* the #tatic +eth*d #ortedList6#ynchroniTed()) =ll the C*llecti*n# have thi# #tatic +eth*d, !hich create# a ne!, threadE#a9e C*llecti*n) T* 3e clear, the pr*gra+ create# a t*tal *9 / #ortedList#1 the *ne 9*r the initial run thr*ugh =rite+hread(), a #ec*nd an*ny+*u# *ne, !hich i# u#ed a# the

#5(

Thinking in C

www.ThinkingIn.!et

para+eter t* #ortedList6#ynchroniTe(), !hich return# a third *ne) =9ter Chapter Ustream chapter U, y*u #h*uld rec*gni7e the ?ec*rat*r pattern in play) ,hen y*u run thi# pr*gra+, y*ull #ee that the 9ir#t run, !ith a plain #ortedList thr*!# a large nu+3er *9 e;cepti*n# Gi9 y*u have a #u99iciently #peedy c*+puter, y*u +ay get n* e;cepti*n#, 3ut i9 y*u increa#e the nu+3er *9 thread#, eventually y*ull run int* tr*u3leH, !hile the li#t pr*duced 3y #ynchroniTed() add# all the data 9la!le##ly) :*ull al#* #ee !hy C*llecti*n# arent #ynchr*ni7ed 3y de9ault1 the threadE#a9e li#t take# #*+ething like 'E( ti+e# the durati*n t* c*+plete) G-9 y*u #aid IBut it# the #a+e Big OKJ give y*ur#el9 a g*ld #tar) -9 y*u #aid, IBut ign*rant hack# !*uld c*n9u#e li3rary per9*r+ance !ith language per9*r+ance and c*+pare threadE#a9e c*llecti*n# t* n*nEthreadE#a9e c*llecti*n#, and *n the 3a#i# *9 #i+pli#tic 3ench+ark# !rite that C# ha# a per9*r+ance pr*3le+, 4u#t a# they did !ith "avaKJ give y*ur#el9 a platinu+ #tar)H :*u can 9ind *ut i9 a C*llecti*n i# #ynchr*ni7ed *r n*t 3y e;a+ining it# #ynchroniTed pr*perty, a# +imed=rite() d*e# during it# #tatu#E!riting line#) -9, in#tead *9 u#ing a li#t pr*duced 3y #ortedList6#ynchroniTed(), y*u put a loc((theList) 3l*ck ar*und the 'dd() call, y*ull get e;cepti*nE le## 3ehavi*r *n 3*th run# a# !ell) Curi*u#ly, i9 y*u d* thi#, the #ynchr*ni7ed li#t #ee+# t* al!ay# *utper9*r+ the un#ynchr*ni7ed li#t 3y a #+all +arginK -n general, th*ugh, the challenge *9 !*rking !ith c*llecti*n# and thread# i# n*t the threadE#a9ety *9 the underlying c*llecti*n, 3ut the inherent challenge *9 *34ect# 3eing added, deleted, *r changed 3y thread# !hile y*ur current thread trie# t* deal !ith the c*llecti*n a# a #ingle l*gical unit) 5*r in#tance, in an *34ect !ith an in#tance *34ect called myCollection, !hether the C*llecti*n i# #ynchroniTed *r n*t, the line# int i 9 !yCo ection.Count3 O$Dect o 9 !yCo ectionJiK3 are inherently threadEun#a9e 3ecau#e an*ther thread +ight have re+*ved ele+ent i 3e9*re the #ec*nd line i# e;ecuted) -9 the cla## *3ey# the rec*++endati*n that the *nly re9erence# t* a critical re#*urce like

Cha"ter 15* Cistri2uted Com"uting

#51

myCollection are internal, any +eth*d that acce##e# myCollection can #i+ply loc((this) and achieve threadE#a9ety) -t# n*t al!ay# p*##i3le t* de#ign cla##e# that d*nt e;p*#e internal in#tance *r #tatic c*llecti*n#, 3ut give it a hard try 3e9*re giving up *n the atte+pt) Can y*u Clone the c*llecti*nF U#e the Pr*;y pattern t* return, n*t the c*llecti*n it#el9, 3ut an inter9ace t* y*ur *!n thread#a9e +eth*d#F -9 n*t, 3e prepared 9*r #*+e l*ng de3ugging #e##i*n#, 3ecau#e it# a g**d 3et that any ti+e y*u *pen the d**r t* +ultithreading de9ect#, #*+e*ne !ill intr*duce the+)

-hreads. 4elegates. and %vents


*! that y*u under#tand the A*nit*r cla##, l*ck 3l*ck#, and i##ue# !ith c*llecti*n cla##e#, y*u can take an*ther l**k at ?elegate# and Event#) 5*r any cla## that generate# Event# Gand re+e+3er, Event# arent 4u#t 9*r >U-# any+*reH, y*u +u#t a##u+e that it !ill run in a +ultithreaded envir*n+ent) Si+ilarly, !hen !riting EventHandler# *r ?elegate#, y*u +u#t a##u+e that the #*urce *9 the Event +ay alread4 have changed 3y the ti+e that the delegate i# called) C*n#ider thi# pr*gra+, !hich atte+pt# t* trap the p*#iti*n *9 a 9a#t +*ving +*u#e1 O#tart here

#5)

Thinking in C

www.ThinkingIn.!et

1!, T@L
'che#as and 4ata'ets

#53

1", We+ 'ervices

#55

), C# 7or Aava Progra##ers

#5#

3, C# 7or 8isual 3asic Progra##ers

#5'

C, C# Progra##ing Guidelines
Thi# appendi; c*ntain# #ugge#ti*n# t* help guide y*u in per9*r+ing l*!Elevel pr*gra+ de#ign, and in !riting c*de)
aturally, the#e are guideline# and n*t rule#) The idea i# t* u#e the+ a# in#pirati*n#, and t* re+e+3er that there are *cca#i*nal #ituati*n# !here y*u need t* 3end *r 3reak a rule)

4esign
1. &legance always pays off) -n the #h*rt ter+ it +ight #ee+ like it take# +uch l*nger t* c*+e up !ith a truly grace9ul #*luti*n t* a pr*3le+, 3ut !hen it !*rk# the 9ir#t ti+e and ea#ily adapt# t* ne! #ituati*n# in#tead *9 reDuiring h*ur#, day#, *r +*nth# *9 #truggle, y*ull #ee the re!ard# Geven i9 n* *ne can +ea#ure the+H) *t *nly

#61

d*e# it give y*u a pr*gra+ that# ea#ier t* 3uild and de3ug, 3ut it# al#* ea#ier t* under#tand and +aintain, and that# !here the 9inancial value lie#) Thi# p*int can take #*+e e;perience t* under#tand, 3ecau#e it can appear that y*ure n*t 3eing pr*ductive !hile y*ure +aking a piece *9 c*de elegant) Re#i#t the urge t* hurryQ it !ill *nly #l*! y*u d*!n) 0%) :irst ma(e it wor(, then ma(e it fast) Thi# i# true even i9 y*u are certain that a piece *9 c*de i# really i+p*rtant and that it !ill 3e a principal 3*ttleneck in y*ur #y#te+) ?*nt d* it) >et the #y#te+ g*ing 9ir#t !ith a# #i+ple a de#ign a# p*##i3le) Then i9 it i#nt g*ing 9a#t en*ugh, pr*9ile it) :*ull al+*#t al!ay# di#c*ver that Iy*urJ 3*ttleneck i#nt the pr*3le+) Save y*ur ti+e 9*r the really i+p*rtant #tu99) 0() *emember the adivide and con%uerb principle ) -9 the pr*3le+ y*ure l**king at i# t** c*n9u#ing, try t* i+agine !hat the 3a#ic *perati*n *9 the pr*gra+ !*uld 3e, given the e;i#tence *9 a +agic IpieceJ that handle# the hard part#) That IpieceJ i# an *34ectR!rite the c*de that u#e# the *34ect, then l**k at the *34ect and encap#ulate its hard part# int* *ther *34ect#, etc) 06) #eparate the class creator from the class user (client programmer)) The cla## u#er i# the Icu#t*+erJ and d*e#nt need *r !ant t* kn*! !hat# g*ing *n 3ehind the #cene# *9 the cla##) The cla## creat*r +u#t 3e the e;pert in cla## de#ign and !rite the cla## #* that it can 3e u#ed 3y the +*#t n*vice pr*gra++er p*##i3le, yet #till !*rk

#6)

r*3u#tly in the applicati*n) Li3rary u#e !ill 3e ea#y *nly i9 it# tran#parent) 2$) =hen you create a class, attempt to ma(e your names so clear that comments are unnecessary) :*ur g*al #h*uld 3e t* +ake the client pr*gra++er# inter9ace c*nceptually #i+ple) T* thi# end, u#e +eth*d *verl*ading !hen appr*priate t* create an intuitive, ea#yEt*Eu#e inter9ace) 20) @our analysis and design must produce, at minimum, the classes in your system, their public interfaces, and their relationships to other classes, especially base classes ) -9 y*ur de#ign +eth*d*l*gy pr*duce# +*re than that, a#k y*ur#el9 i9 all the piece# pr*duced 3y that +eth*d*l*gy have value *ver the li9eti+e *9 the pr*gra+) -9 they d* n*t, +aintaining the+ !ill c*#t y*u) Ae+3er# *9 devel*p+ent tea+# tend n*t t* +aintain anything that d*e# n*t c*ntri3ute t* their pr*ductivityQ thi# i# a 9act *9 li9e that +any de#ign +eth*d# d*nt acc*unt 9*r) 22) 'utomate everything) ,rite the te#t c*de 9ir#t G3e9*re y*u !rite the cla##H, and keep it !ith the cla##) =ut*+ate the running *9 y*ur te#t# thr*ugh a +ake9ile *r #i+ilar t**l) Thi# !ay, any change# can 3e aut*+atically veri9ied 3y running the te#t c*de, and y*ull i++ediately di#c*ver err*r#) Becau#e y*u kn*! that y*u have the #a9ety net *9 y*ur te#t 9ra+e!*rk, y*u !ill 3e 3*lder a3*ut +aking #!eeping change# !hen y*u di#c*ver the need) Re+e+3er that the greate#t i+pr*ve+ent# in language# c*+e 9r*+ the 3uiltEin te#ting pr*vided 3y type checking, e;cepti*n handling, etc), 3ut th*#e 9eature# take y*u *nly #* 9ar) :*u +u#t g* the re#t *9 the !ay in creating a r*3u#t #y#te+ 3y 9illing in the te#t# that veri9y 9eature# that are #peci9ic t* y*ur cla## *r pr*gra+) 2/) =rite the test code first (before you write the class) in order to verify that your class design is complete) -9 y*u cant !rite te#t c*de, y*u d*nt kn*! !hat y*ur cla## l**k# like) -n additi*n, the act *9 !riting the te#t c*de !ill *9ten 9lu#h *ut additi*nal 9eature# *r c*n#traint# that y*u need in the cla##Rthe#e 9eature# *r c*n#traint# d*nt al!ay# appear during analy#i# and de#ign) Te#t# al#* pr*vide e;a+ple c*de #h*!ing h*! y*ur cla## can 3e u#ed)

5""endi% C* ,a-a /rogramming Duidelines

#63

2&) 'll software design problems can be simplified by introducing an extra level of conceptual indirection . Thi# 9unda+ental rule *9 #*9t!are engineering0 i# the 3a#i# *9 a3#tracti*n, the pri+ary 9eature *9 *34ectE*riented pr*gra++ing) 2') 'n indirection should have a meaning Gin c*ncert !ith guideline 6H) Thi# +eaning can 3e #*+ething a# #i+ple a# Iputting c*++*nly u#ed c*de in a #ingle +eth*d)J -9 y*u add level# *9 indirecti*n Ga3#tracti*n, encap#ulati*n, etc)H that d*nt have +eaning, it can 3e a# 3ad a# n*t having adeDuate indirecti*n) 2.) .a(e classes as atomic as possible) >ive each cla## a #ingle, clear purp*#e) -9 y*ur cla##e# *r y*ur #y#te+ de#ign gr*!# t** c*+plicated, 3reak c*+ple; cla##e# int* #i+pler *ne#) The +*#t *3vi*u# indicat*r *9 thi# i# #heer #i7e1 i9 a cla## i# 3ig, chance# are it# d*ing t** +uch and #h*uld 3e 3r*ken up) Clue# t* #ugge#t rede#ign *9 a cla## are1 0H = c*+plicated #!itch #tate+ent1 c*n#ider u#ing p*ly+*rphi#+) 2H = large nu+3er *9 +eth*d# that c*ver 3r*adly di99erent type# *9 *perati*n#1 c*n#ider u#ing #everal cla##e#) /H = large nu+3er *9 +e+3er varia3le# that c*ncern 3r*adly di99erent characteri#tic#1 c*n#ider u#ing #everal cla##e#) 2%) =atch for long argument lists) Aeth*d call# then 3ec*+e di99icult t* !rite, read, and +aintain) -n#tead, try t* +*ve the +eth*d t* a cla## !here it i# G+*reH appr*priate, and<*r pa## *34ect# in a# argu+ent#) 2() $on5t repeat yourself) -9 a piece *9 c*de i# recurring in +any +eth*d# in derived cla##e#, put that c*de int* a #ingle +eth*d in the 3a#e cla## and call it 9r*+ the derivedEcla## +eth*d#) *t *nly d* y*u #ave c*de #pace, y*u pr*vide 9*r ea#y pr*pagati*n *9 change#) S*+eti+e# the di#c*very *9 thi# c*++*n c*de !ill add valua3le 9uncti*nality t* y*ur inter9ace) 26) =atch for switch statements or chained i!'else clauses) Thi# i# typically an indicat*r *9 t4"e9check coding, !hich +ean# y*u are ch**#ing !hat c*de t* e;ecute 3a#ed *n #*+e kind *9 type
0 E;plained t* +e 3y =ndre! N*enig)

#64

Thinking in C

www.ThinkingIn.!et

in9*r+ati*n Gthe e;act type +ay n*t 3e *3vi*u# at 9ir#tH) :*u can u#ually replace thi# kind *9 c*de !ith inheritance and p*ly+*rphi#+Q a p*ly+*rphic +eth*d call !ill per9*r+ the type checking 9*r y*u, and all*! 9*r +*re relia3le and ea#ier e;ten#i3ility) /$) :rom a design standpoint, loo( for and separate things that change from things that stay the same) That i#, #earch 9*r the ele+ent# in a #y#te+ that y*u +ight !ant t* change !ith*ut 9*rcing a rede#ign, then encap#ulate th*#e ele+ent# in cla##e#) :*u can learn #igni9icantly +*re a3*ut thi# c*ncept in Thinking in /atterns with ,a-a, d*!nl*ada3le at www.BruceEckel.com) /0) $on5t extend fundamental functionality by subclassing) -9 an inter9ace ele+ent i# e##ential t* a cla## it #h*uld 3e in the 3a#e cla##, n*t added during derivati*n) -9 y*ure adding +eth*d# 3y inheriting, perhap# y*u #h*uld rethink the de#ign) /2) Less is more) Start !ith a +ini+al inter9ace t* a cla##, a# #+all and #i+ple a# y*u need t* #*lve the pr*3le+ at hand, 3ut d*nt try t* anticipate all the !ay# that y*ur cla## might 3e u#ed) =# the cla## i# u#ed, y*ull di#c*ver !ay# y*u +u#t e;pand the inter9ace) H*!ever, *nce a cla## i# in u#e y*u cann*t #hrink the inter9ace !ith*ut di#tur3ing client c*de) -9 y*u need t* add +*re +eth*d#, that# 9ineQ it !*nt di#tur3 c*de, *ther than 9*rcing rec*+pile#) But even i9 ne! +eth*d# replace the 9uncti*nality *9 *ld *ne#, leave the e;i#ting inter9ace al*ne Gy*u can c*+3ine the 9uncti*nality in the underlying i+ple+entati*n i9 y*u !antH) -9 y*u need t* e;pand the inter9ace *9 an e;i#ting +eth*d 3y adding +*re argu+ent#, create an *verl*aded +eth*d !ith the ne! argu+ent#Q thi# !ay y*u !*nt di#tur3 any e;i#ting call# t* the e;i#ting +eth*d) //) *ead your classes aloud to ma(e sure they5re logical ) Re9er t* the relati*n#hip 3et!een a 3a#e cla## and derived cla## a# Ii#EaJ and +e+3er *34ect# a# Iha#Ea)J /&) =hen deciding between inheritance and composition, as( if you need to upcast to the base type) -9 n*t, pre9er c*+p*#iti*n G+e+3er *34ect#H t* inheritance) Thi# can eli+inate the perceived need 9*r +ultiple 3a#e type#) -9 y*u inherit, u#er# !ill think they are #upp*#ed t* upca#t)

5""endi% C* ,a-a /rogramming Duidelines

#65

/') Vse data members for variation in value and method overriding for variation in behavior) That i#, i9 y*u 9ind a cla## that u#e# #tate varia3le# al*ng !ith +eth*d# that #!itch 3ehavi*r 3a#ed *n th*#e varia3le#, y*u #h*uld pr*3a3ly rede#ign it t* e;pre## the di99erence# in 3ehavi*r !ithin #u3cla##e# and *verridden +eth*d#) /.) =atch for overloading) = +eth*d #h*uld n*t c*nditi*nally e;ecute c*de 3a#ed *n the value *9 an argu+ent) -n thi# ca#e, y*u #h*uld create t!* *r +*re *verl*aded +eth*d# in#tead) /%) Vse exception hierarchiesRpre9era3ly derived 9r*+ #peci9ic appr*priate cla##e# in the #tandard "ava e;cepti*n hierarchy) The per#*n catching the e;cepti*n# can then catch the #peci9ic type# *9 e;cepti*n#, 9*ll*!ed 3y the 3a#e type) -9 y*u add ne! derived e;cepti*n#, e;i#ting client c*de !ill #till catch the e;cepti*n thr*ugh the 3a#e type) /() #ometimes simple aggregation does the )ob) = Ipa##enger c*+9*rt #y#te+J *n an airline c*n#i#t# *9 di#c*nnected ele+ent#1 #eat, air c*nditi*ning, vide*, etc), and yet y*u need t* create +any *9 the#e in a plane) ?* y*u +ake private +e+3er# and 3uild a !h*le ne! inter9aceF *Rin thi# ca#e, the c*+p*nent# are al#* part *9 the pu3lic inter9ace, #* y*u #h*uld create pu3lic +e+3er *34ect#) Th*#e *34ect# have their *!n private i+ple+entati*n#, !hich are #till #a9e) Be a!are that #i+ple aggregati*n i# n*t a #*luti*n t* 3e u#ed *9ten, 3ut it d*e# happen) /6) Consider the perspective of the client programmer and the person maintaining the code) ?e#ign y*ur cla## t* 3e a# *3vi*u# a# p*##i3le t* u#e) =nticipate the kind *9 change# that !ill 3e +ade, and de#ign y*ur cla## #* that th*#e change# !ill 3e ea#y) &$) =atch out for agiant ob)ect syndrome6b Thi# i# *9ten an a99licti*n *9 pr*cedural pr*gra++er# !h* are ne! t* OOP and !h* end up !riting a pr*cedural pr*gra+ and #ticking it in#ide *ne *r t!* giant *34ect#) ,ith the e;cepti*n *9 applicati*n 9ra+e!*rk#, *34ect# repre#ent c*ncept# in y*ur applicati*n, n*t the applicati*n)

#66

Thinking in C

www.ThinkingIn.!et

&0) Bf you must do something ugly, at least localiTe the ugliness inside a class) &2) Bf you must do something nonportable, ma(e an abstraction for that service and localiTe it within a class) Thi# e;tra level *9 indirecti*n prevent# the n*np*rta3ility 9r*+ 3eing di#tri3uted thr*ugh*ut y*ur pr*gra+) GThi# idi*+ i# e+3*died in the Bridge PatternH) &/) ob)ects should not simply hold some data) They #h*uld al#* have !ellEde9ined 3ehavi*r#) GOcca#i*nally, Idata *34ect#J are appr*priate, 3ut *nly !hen u#ed e;pre##ly t* package and tran#p*rt a gr*up *9 ite+# !hen a generali7ed c*ntainer i# innappr*priate)H &&) Choose composition first when creating new classes from existing classes) :*u #h*uld *nly u#ed inheritance i9 it i# reDuired 3y y*ur de#ign) -9 y*u u#e inheritance !here c*+p*#iti*n !ill !*rk, y*ur de#ign# !ill 3ec*+e needle##ly c*+plicated) &') Vse inheritance and method overriding to express differences in behavior, and fields to express variations in state) =n e;tre+e e;a+ple *9 !hat n*t t* d* i# inheriting di99erent cla##e# t* repre#ent c*l*r# in#tead *9 u#ing a Ic*l*rJ 9ield) &.) =atch out for variance) T!* #e+antically di99erent *34ect# +ay have identical acti*n#, *r re#p*n#i3ilitie#, and there i# a natural te+ptati*n t* try t* +ake *ne a #u3cla## *9 the *ther 4u#t t* 3ene9it 9r*+ inheritance) Thi# i# called variance, 3ut there# n* real 4u#ti9icati*n t* 9*rce a #upercla##<#u3cla## relati*n#hip !here it d*e#nt e;i#t) = 3etter #*luti*n i# t* create a general 3a#e cla## that pr*duce# an inter9ace 9*r 3*th a# derived cla##e#Rit reDuire# a 3it +*re #pace, 3ut y*u #till 3ene9it 9r*+ inheritance, and !ill pr*3a3ly +ake an i+p*rtant di#c*very a3*ut the de#ign) &%) =atch out for limitation during inheritance) The cleare#t de#ign# add ne! capa3ilitie# t* inherited *ne#) = #u#pici*u# de#ign re+*ve# *ld capa3ilitie# during inheritance !ith*ut adding ne! *ne#) But rule# are +ade t* 3e 3r*ken, and i9 y*u are !*rking 9r*+ an *ld cla## li3rary, it +ay 3e +*re e99icient t* re#trict an e;i#ting cla## in it#

5""endi% C* ,a-a /rogramming Duidelines

#6#

#u3cla## than it !*uld 3e t* re#tructure the hierarchy #* y*ur ne! cla## 9it# in !here it #h*uld, a3*ve the *ld cla##) &() Vse design patterns to eliminate ana(ed functionality6b That i#, i9 *nly *ne *34ect *9 y*ur cla## #h*uld 3e created, d*nt 3*lt ahead t* the applicati*n and !rite a c*++ent IAake *nly *ne *9 the#e)J ,rap it in a #inglet*n) -9 y*u have a l*t *9 +e##y c*de in y*ur +ain pr*gra+ that create# y*ur *34ect#, l**k 9*r a creati*nal pattern like a 9act*ry +eth*d in !hich y*u can encap#ulate that creati*n) Eli+inating Inaked 9uncti*nalityJ !ill n*t *nly +ake y*ur c*de +uch ea#ier t* under#tand and +aintain, it !ill al#* +ake it +*re 3ulletpr**9 again#t the !ellEintenti*ned +aintainer# that c*+e a9ter y*u) &6) =atch out for aanalysis paralysis6b Re+e+3er that y*u +u#t u#ually +*ve 9*r!ard in a pr*4ect 3e9*re y*u kn*! everything, and that *9ten the 3e#t and 9a#te#t !ay t* learn a3*ut #*+e *9 y*ur unkn*!n 9act*r# i# t* g* t* the ne;t #tep rather than trying t* 9igure it *ut in y*ur head) :*u cant kn*! the #*luti*n until y*u ha-e the #*luti*n) "ava ha# 3uiltEin 9ire!all#Q let the+ !*rk 9*r y*u) :*ur +i#take# in a cla## *r #et *9 cla##e# !*nt de#tr*y the integrity *9 the !h*le #y#te+) '$) =hen you thin( you5ve got a good analysis, design, or implementation, do a wal(through ) Bring #*+e*ne in 9r*+ *ut#ide y*ur gr*upRthi# d*e#nt have t* 3e a c*n#ultant, 3ut can 3e #*+e*ne 9r*+ an*ther gr*up !ithin y*ur c*+pany) Revie!ing y*ur !*rk !ith a 9re#h pair *9 eye# can reveal pr*3le+# at a #tage !hen it# +uch ea#ier t* 9i; the+, and +*re than pay# 9*r the ti+e and +*ney Il*#tJ t* the !alkthr*ugh pr*ce##)

I#$le#entation
'0) Bn general, follow the .icrosoft coding conventions ) The#e are availa3le at re$ Gthe c*de in thi# 3**k 9*ll*!# the#e c*nventi*n# a# +uch a# !a# a3leH) The#e are u#ed 9*r !hat c*n#titute# argua3ly the large#t 3*dy *9 c*de that the large#t nu+3er *9 C# pr*gra++er# !ill 3e e;p*#ed t*) -9 y*u d*ggedly #tick t* the c*ding #tyle y*uve al!ay#

#6&

Thinking in C

www.ThinkingIn.!et

u#ed, y*u !ill +ake it harder 9*r y*ur reader) ,hatever c*ding c*nventi*n# y*u decide *n, en#ure they are c*n#i#tent thr*ugh*ut the pr*4ect) '2) =hatever coding style you use, it really does ma(e a difference if your team (and even better, your company) standardiTes on it) Thi# +ean# t* the p*int that every*ne c*n#ider# it 9air ga+e t* 9i; #*+e*ne el#e# c*ding #tyle i9 it d*e#nt c*n9*r+) The value *9 #tandardi7ati*n i# that it take# le## 3rain cycle# t* par#e the c*de, #* that y*u can 9*cu# +*re *n !hat the c*de +ean#) '/) :ollow standard capitaliTation rules) Capitali7e the 9ir#t letter *9 cla## na+e# and n*nEprivate +eth*d# and pr*pertie#) The 9ir#t letter *9 private 9ield#, +eth*d#, and *34ect# Gre9erence#H #h*uld 3e l*!erca#e) =ll identi9ier# #h*uld run their !*rd# t*gether, and capitali7e the 9ir#t letter *9 all inter+ediate !*rd#) 5*r e;a+ple1 +hisBs'Class,ame thisBs'!rivate.ethod1r:ield,ame Capitali7e all the letter# *9 static final pri+itive identi9ier# that have c*n#tant initiali7er# in their de9initi*n#) Thi# indicate# they are c*+pileEti+e c*n#tant#) '&) $on5t create your own adecoratedb private data member names) Thi# i# u#ually #een in the 9*r+ *9 prepended under#c*re# and character#) Hungarian n*tati*n i# the !*r#t e;a+ple *9 thi#, !here y*u attach e;tra character# that indicate data type, u#e, l*cati*n, etc), a# i9 y*u !ere !riting a##e+3ly language and the c*+piler pr*vided n* e;tra a##i#tance at all) The#e n*tati*n# are c*n9u#ing, di99icult t* read, and unplea#ant t* en9*rce and +aintain) Let cla##e# and package# d* the na+e #c*ping 9*r y*u) '') :ollow a acanonical formb !hen creating a cla## 9*r generalE purp*#e u#e) -nclude de9initi*n# 9*r e%uals( ), hashCode( ), to#tring( ), clone( ) Gi+ple+ent CloneableH, and i+ple+ent Comparable and #erialiTable) '.) Vse the XavaBeans aget,b aset,b and aisb naming conventions 9*r +eth*d# that read and change private 9ield#, even i9 y*u d*nt think y*ure +aking a "avaBean at the ti+e) *t *nly d*e# it +ake it ea#y t* u#e y*ur cla## a# a Bean, 3ut it# a #tandard !ay t* na+e the#e

5""endi% C* ,a-a /rogramming Duidelines

#6'

kind# *9 +eth*d# and #* !ill 3e +*re ea#ily under#t**d 3y the reader) '%) :or each class you create, consider including a static public test6 7 that contains code to test that class) :*u d*nt need t* re+*ve the te#t c*de t* u#e the cla## in a pr*4ect, and i9 y*u +ake any change# y*u can ea#ily rerun the te#t#) Thi# c*de al#* pr*vide# e;a+ple# *9 h*! t* u#e y*ur cla##) '() #ometimes you need to inherit in order to access protected members of the base class) Thi# can lead t* a perceived need 9*r +ultiple 3a#e type#) -9 y*u d*nt need t* upca#t, 9ir#t derive a ne! cla## t* per9*r+ the pr*tected acce##) Then +ake that ne! cla## a +e+3er *34ect in#ide any cla## that need# t* u#e it, rather than inheriting) '6) Bf two classes are associated with each other in some functional way (such as containers and iterators), try to ma(e one an inner class of the other) Thi# n*t *nly e+pha#i7e# the a##*ciati*n 3et!een the cla##e#, 3ut it all*!# the cla## na+e t* 3e reu#ed !ithin a #ingle package 3y ne#ting it !ithin an*ther cla##) .$) 'nytime you notice classes that appear to have high coupling with each other, consider the coding and maintenance improvements you might get by using inner classes) The u#e *9 inner cla##e# !ill n*t unc*uple the cla##e#, 3ut rather +ake the c*upling e;plicit and +*re c*nvenient) .0) $on5t fall prey to premature optimiTation) Thi# !ay lie# +adne##) -n particular, d*nt !*rry a3*ut !riting G*r av*idingH native +eth*d#, +aking #*+e +eth*d# final, *r t!eaking c*de t* 3e e99icient !hen y*u are 9ir#t c*n#tructing the #y#te+) :*ur pri+ary g*al #h*uld 3e t* pr*ve the de#ign, unle## the de#ign reDuire# a certain e99iciency) .2) Eeep scopes as small as possible so the visibility and lifetime of your ob)ects are as small as possible) Thi# reduce# the chance *9 u#ing an *34ect in the !r*ng c*nte;t and hiding a di99icultEt*E9ind 3ug) 5*r e;a+ple, #upp*#e y*u have a c*ntainer and a piece *9 c*de that iterate# thr*ugh it) -9 y*u c*py that c*de t* u#e !ith a ne!

##(

Thinking in C

www.ThinkingIn.!et

c*ntainer, y*u +ay accidentally end up u#ing the #i7e *9 the *ld c*ntainer a# the upper 3*und *9 the ne! *ne) -9, h*!ever, the *ld c*ntainer i# *ut *9 #c*pe, the err*r !ill 3e caught at c*+pileEti+e) ./) Vse the containers in the 6,&+ :ramewor( #$E) Bec*+e pr*9icient !ith their u#e and y*ull greatly increa#e y*ur pr*ductivity) .&) :or a program to be robust, each component must be robust) U#e all the t**l# pr*vided 3y C#1 acce## c*ntr*l, e;cepti*n#, type checking, and #* *n, in each cla## y*u create) That !ay y*u can #a9ely +*ve t* the ne;t level *9 a3#tracti*n !hen 3uilding y*ur #y#te+) .') !refer compile-time errors to run-time errors) Try t* handle an err*r a# cl*#e t* the p*int *9 it# *ccurrence a# p*##i3le) Pre9er dealing !ith the err*r at that p*int t* thr*!ing an e;cepti*n) Catch any e;cepti*n# in the neare#t handler that ha# en*ugh in9*r+ati*n t* deal !ith the+) ?* !hat y*u can !ith the e;cepti*n at the current levelQ i9 that d*e#nt #*lve the pr*3le+, rethr*! the e;cepti*n) ..) =atch for long method definitions) Aeth*d# #h*uld 3e 3rie9, 9uncti*nal unit# that de#cri3e and i+ple+ent a di#crete part *9 a cla## inter9ace) = +eth*d that i# l*ng and c*+plicated i# di99icult and e;pen#ive t* +aintain, and i# pr*3a3ly trying t* d* t** +uch all 3y it#el9) -9 y*u #ee #uch a +eth*d, it indicate# that, at the lea#t, it #h*uld 3e 3r*ken up int* +ultiple +eth*d#) -t +ay al#* #ugge#t the creati*n *9 a ne! cla##) S+all +eth*d# !ill al#* 9*#ter reu#e !ithin y*ur cla##) GS*+eti+e# +eth*d# +u#t 3e large, 3ut they #h*uld #till d* 4u#t *ne thing)H .%) Eeep things as aprivate as possible6b Once y*u pu3lici7e an a#pect *9 y*ur li3rary Ga +eth*d, a cla##, a 9ieldH, y*u can never take it *ut) -9 y*u d*, y*ull !reck #*+e3*dy# e;i#ting c*de, 9*rcing the+ t* re!rite and rede#ign) -9 y*u pu3lici7e *nly !hat y*u +u#t, y*u can change everything el#e !ith i+punity, and #ince de#ign# tend t* ev*lve thi# i# an i+p*rtant 9reed*+) -n thi# !ay, i+ple+entati*n change# !ill have +ini+al i+pact *n derived cla##e#) Privacy i# e#pecially i+p*rtant !hen dealing !ith +ultithreadingR*nly private 9ield# can 3e pr*tected again#t unEsynchroniTed u#e)

5""endi% C* ,a-a /rogramming Duidelines

##1

.() Vse comments liberally, and use the commentdocumentation syntax to produce your program documentation) H*!ever, the c*++ent# #h*uld add geniune +eaning t* the c*deQ c*++ent# that *nly reiterate !hat the c*de i# clearly e;pre##ing are ann*ying) *te that the typical ver3*#e detail *9 "ava cla## and +eth*d na+e# reduce the need 9*r a# +any c*++ent#) .6) 'void using amagic numbersbR!hich are nu+3er# hardE!ired int* c*de) The#e are a night+are i9 y*u need t* change the+, #ince y*u never kn*! i9 I0$$J +ean# Ithe array #i7eJ *r I#*+ething el#e entirely)J -n#tead, create a c*n#tant !ith a de#criptive na+e and u#e the c*n#tant identi9ier thr*ugh*ut y*ur pr*gra+) Thi# +ake# the pr*gra+ ea#ier t* under#tand and +uch ea#ier t* +aintain) %$) =hen creating constructors, consider exceptions) -n the 3e#t ca#e, the c*n#truct*r !*nt d* anything that thr*!# an e;cepti*n) -n the ne;tE3e#t #cenari*, the cla## !ill 3e c*+p*#ed and inherited 9r*+ r*3u#t cla##e# *nly, #* they !ill need n* cleanup i9 an e;cepti*n i# thr*!n) Other!i#e, y*u +u#t clean up c*+p*#ed cla##e# in#ide a finally clau#e) -9 a c*n#truct*r +u#t 9ail, the appr*priate acti*n i# t* thr*! an e;cepti*n, #* the caller d*e#nt c*ntinue 3lindly, thinking that the *34ect !a# created c*rrectly) %0) Bf your class re%uires any cleanup when the client programmer is finished with the ob)ect, ma(e your class implement B$isposable tk) %2) =hen you are creating a fixed-siTe container of ob)ects, transfer them to an arrayRe#pecially i9 y*ure returning thi# c*ntainer 9r*+ a +eth*d) Thi# !ay y*u get the 3ene9it *9 the array# c*+pileEti+e type checking, and the recipient *9 the array +ight n*t need t* ca#t the *34ect# in the array in *rder t* u#e the+) %/) Choose inter!aces over abstract classes) -9 y*u kn*! #*+ething i# g*ing t* 3e a 3a#e cla##, y*ur 9ir#t ch*ice #h*uld 3e t* +ake it an interface, and *nly i9 y*ure 9*rced t* have +eth*d de9initi*n# *r +e+3er varia3le# #h*uld y*u change it t* an abstract cla##) =n interface talk# a3*ut !hat the client !ant# t* d*, !hile a cla## tend# t* 9*cu# *n G*r all*!H i+ple+entati*n detail#)

##)

Thinking in C

www.ThinkingIn.!et

%&) Bnside constructors, do only what is necessary to set the ob)ect into the proper state) =ctively av*id calling *ther +eth*d# Ge;cept 9*r final +eth*d#H #ince th*#e +eth*d# can 3e *verridden 3y #*+e*ne el#e t* pr*duce une;pected re#ult# during c*n#tructi*n) GSee Chapter % 9*r detail#)H S+aller, #i+pler c*n#truct*r# are le## likely t* thr*! e;cepti*n# *r cau#e pr*3le+#) %') =atch out for accidental overloading) -9 y*u atte+pt t* *verride a 3a#eEcla## +eth*d and y*u d*nt Duite get the #pelling right, y*ull end up adding a ne! +eth*d rather than *verriding an e;i#ting +eth*d) H*!ever, thi# i# per9ectly legal, #* y*u !*nt get any err*r +e##age 9r*+ the c*+piler *r runEti+e #y#te+Ry*ur c*de #i+ply !*nt !*rk c*rrectly) %.) =atch out for premature optimiTation) 5ir#t +ake it !*rk, then +ake it 9a#tR3ut *nly i9 y*u +u#t, and *nly i9 it# pr*ven that there i# a per9*r+ance 3*ttleneck in a particular #ecti*n *9 y*ur c*de) Unle## y*u have u#ed a pr*9iler t* di#c*ver a 3*ttleneck, y*u !ill pr*3a3ly 3e !a#ting y*ur ti+e) The hidden c*#t *9 per9*r+ance t!eak# i# that y*ur c*de 3ec*+e# le## under#tanda3le and +aintaina3le) %%) *emember that code is read much more than it is written) Clean de#ign# +ake 9*r ea#yEt*Eunder#tand pr*gra+#, 3ut c*++ent#, detailed e;planati*n#, and e;a+ple# are invalua3le) They !ill help 3*th y*u and every*ne !h* c*+e# a9ter y*u) -9 n*thing el#e, the 9ru#trati*n *9 trying t* 9erret *ut u#e9ul in9*r+ati*n 9r*+ the *nline "ava d*cu+entati*n #h*uld c*nvince y*u)

4, 6esources
'o0tware
tk

5""endi% C* ,a-a /rogramming Duidelines

##3

3oo*s
C#
tk

)nal5sis I design
tk

@anage#ent I Process
tk

Inde&
Plea#e n*te that #*+e na+e# !ill 3e duplicated in capitali7ed 9*r+) 5*ll*!ing C# #tyle, the capitali7ed na+e# re9er t* C# cla##e#, !hile l*!erca#e na+e# re9er t* a general c*ncept)
A
+ultita#king f %0'

StartG H f %22 thread# and e99iciency f %20 !hen they can 3e #u#pended f %/2 U
u#er inter9ace f

P
pr*ce##, and threading f %0'

S
SleepG H f %2$, %/0

T
Thread f

*rder *9 e;ecuti*n *9 thread# f %2/ #haring li+ited re#*urce# f %2.

and thread#, 9*r re#p*n#ivene## f %2& re#p*n#ive, !ith threading f %0(

##4

Thinking in C

www.ThinkingIn.!et

Chec( www."ruceEc(el.com 0or in;de$th details and the date and location o0 the ne&t ands)*n +ava Seminar
Ba#ed *n thi# 3**k Taught 3y Bruce Eckel Per#*nal attenti*n 9r*+ Bruce Eckel and hi# #e+inar a##i#tant# -nclude# inEcla## pr*gra++ing e;erci#e# -nter+ediate<=dvanced #e+inar# al#* *99ered Hundred# have already en4*yed thi# #e+inarR #ee the ,e3 #ite 9*r their te#ti+*nial#

##6

"ruce Ec(el,s ands)*n +ava Seminar @ulti#edia C4 Its li*e co#ing to the se#inarJ )vaila+le at www.BruceEckel.com
The >ands91n ,a-a @eminar captured *n a Aulti+edia C?K Overhead #lide# and #ynchr*ni7ed audi* v*ice narrati*n 9*r all the lecture#) "u#t play it t* #ee and hear the lecture#K Created and narrated 3y Bruce Eckel) Ba#ed *n the +aterial in thi# 3**k) ?e+* lecture availa3le at www.BruceEckel.com

%nd;>ser License )gree#ent 0or @icroso0t 'o0tware I@PO6-)(-;6%)4 C)6%7>LLB, -his @icroso0t %nd;>ser License )gree#ent 1=%>L)=2 is a legal agree#ent +etween 5ou 1either an individual or a single entit52 and @icroso0t Cor$oration 0or the @icroso0t so0tware $roduct included in this $ac*age. which includes co#$uter so0tware and #a5 include associated #edia. $rinted #aterials. and =online= or electronic docu#entation 1='O7-W)6% P6O4>C-=2. -he 'O7-W)6% P6O4>C- also includes an5 u$dates and su$$le#ents to the original 'O7-W)6% P6O4>C- $rovided to 5ou +5 @icroso0t. 35 installing. co$5ing. downloading. accessing or otherwise using the 'O7-W)6% P6O4>C-. 5ou agree to +e +ound +5 the ter#s o0 this %>L). I0 5ou do not agree to the ter#s o0 this %>L). do not install. co$5. or otherwise use the 'O7-W)6% P6O4>C-. 'O7-W)6% P6O4>C- LIC%('% -he 'O7-W)6% P6O4>C- is $rotected +5 co$5right laws and international co$5right treaties. as well as other intellectual $ro$ert5 laws and treaties. -he 'O7-W)6% P6O4>C- is licensed. not sold. 1. G6)(- O7 LIC%('%. -his %>L) grants 5ou the 0ollowing rights, 1.1 License Grant. @icroso0t grants to 5ou as an individual. a $ersonal none&clusive license to #a*e and use co$ies o0 the 'O7-W)6% P6O4>C- 0or the sole $ur$oses o0 evaluating and learning how to use the 'O7-W)6% P6O4>C-. as #a5 +e instructed in acco#$an5ing $u+lications or docu#entation. Bou #a5 install the so0tware on an unli#ited nu#+er o0 co#$uters $rovided that 5ou are the onl5 individual using the 'O7-W)6% P6O4>C-. 1.2 )cade#ic >se. Bou #ust +e a =Quali0ied %ducational >ser= to use the 'O7-W)6% P6O4>C- in the #anner descri+ed in this section. -o deter#ine whether 5ou are a Quali0ied %ducational >ser. $lease contact the @icroso0t 'ales In0or#ation Center?One @icroso0t Wa5?6ed#ond. W) EDF!2;"3EE or the @icroso0t su+sidiar5 serving 5our countr5. I0 5ou are a Quali0ied %ducational >ser. 5ou #a5 either, 1i2 e&ercise the rights granted in 'ection 1.1. O6 1ii2 i0 5ou intend to use the 'O7-W)6% P6O4>C- solel5 0or instructional $ur$oses in connection with a class or other educational $rogra#. this %>L) grants 5ou the 0ollowing alternative license #odels, 1)2 Per Co#$uter @odel. 7or ever5 valid license 5ou have acquired 0or the 'O7-W)6% P6O4>C-. 5ou #a5 install a single co$5 o0 the 'O7-W)6%

##&

P6O4>C- on a single co#$uter 0or access and use +5 an unli#ited nu#+er o0 student end users at 5our educational institution. $rovided that all such end users co#$l5 with all other ter#s o0 this %>L). O6 132 Per License @odel. I0 5ou have #ulti$le licenses 0or the 'O7-W)6% P6O4>C-. then at an5 ti#e 5ou #a5 have as #an5 co$ies o0 the 'O7-W)6% P6O4>C- in use as 5ou have licenses. $rovided that such use is li#ited to student or 0acult5 end users at 5our educational institution and $rovided that all such end users co#$l5 with all other ter#s o0 this %>L). 7or $ur$oses o0 this su+section. the 'O7-W)6% P6O4>C- is =in use= on a co#$uter when it is loaded into the te#$orar5 #e#or5 1i.e.. 6)@2 or installed into the $er#anent #e#or5 1e.g.. hard dis*. C4 6O@. or other storage device2 o0 that co#$uter. e&ce$t that a co$5 installed on a networ* server 0or the sole $ur$ose o0 distri+ution to other co#$uters is not =in use=. I0 the antici$ated nu#+er o0 users o0 the 'O7-W)6% P6O4>C- will e&ceed the nu#+er o0 a$$lica+le licenses. then 5ou #ust have a reasona+le #echanis# or $rocess in $lace to ensure that the nu#+er o0 $ersons using the 'O7-W)6% P6O4>Cconcurrentl5 does not e&ceed the nu#+er o0 licenses. 2. 4%'C6IP-IO( O7 O-9%6 6IG9-' )(4 LI@I-)-IO('. V Li#itations on 6everse %ngineering. 4eco#$ilation. and 4isasse#+l5. Bou #a5 not reverse engineer. deco#$ile. or disasse#+le the 'O7-W)6% P6O4>C-. e&ce$t and onl5 to the e&tent that such activit5 is e&$ressl5 $er#itted +5 a$$lica+le law notwithstanding this li#itation. V 'e$aration o0 Co#$onents. -he 'O7-W)6% P6O4>C- is licensed as a single $roduct. Its co#$onent $arts #a5 not +e se$arated 0or use on #ore than one co#$uter. V 6ental. Bou #a5 not rent. lease or lend the 'O7-W)6% P6O4>C-. V -rade#ar*s. -his %>L) does not grant 5ou an5 rights in connection with an5 trade#ar*s or service #ar*s o0 @icroso0t. V 'o0tware -rans0er. -he initial user o0 the 'O7-W)6% P6O4>C- #a5 #a*e a one;ti#e $er#anent trans0er o0 this %>L) and 'O7-W)6% P6O4>C- onl5 directl5 to an end user. -his trans0er #ust include all o0 the 'O7-W)6% P6O4>C- 1including all co#$onent $arts. the #edia and $rinted #aterials. an5 u$grades. this %>L). and. i0 a$$lica+le. the Certi0icate o0 )uthenticit52. 'uch trans0er #a5 not +e +5 wa5 o0 consign#ent or an5 other indirect trans0er. -he trans0eree o0 such one;ti#e trans0er #ust agree to co#$l5 with the ter#s o0 this %>L). including the o+ligation not to 0urther trans0er this %>L) and 'O7-W)6% P6O4>C-. V (o 'u$$ort. @icroso0t shall have no o+ligation to $rovide an5 $roduct su$$ort 0or the 'O7-W)6% P6O4>C-. V -er#ination. Without $re/udice to an5 other rights. @icroso0t #a5 ter#inate this %>L) i0 5ou 0ail to co#$l5 with the ter#s and conditions o0 this %>L). In

##'

such event. 5ou #ust destro5 all co$ies o0 the 'O7-W)6% P6O4>C- and all o0 its co#$onent $arts. 3. COPB6IG9-. )ll title and intellectual $ro$ert5 rights in and to the 'O7-W)6% P6O4>C- 1including +ut not li#ited to an5 i#ages. $hotogra$hs. ani#ations. video. audio. #usic. te&t. and =a$$lets= incor$orated into the 'O7-W)6% P6O4>C-2. the acco#$an5ing $rinted #aterials. and an5 co$ies o0 the 'O7-W)6% P6O4>C- are owned +5 @icroso0t or its su$$liers. )ll title and intellectual $ro$ert5 rights in and to the content which #a5 +e accessed through use o0 the 'O7-W)6% P6O4>C- is the $ro$ert5 o0 the res$ective content owner and #a5 +e $rotected +5 a$$lica+le co$5right or other intellectual $ro$ert5 laws and treaties. -his %>L) grants 5ou no rights to use such content. )ll rights not e&$ressl5 granted are reserved +5 @icroso0t. . 3)CR>P COPB. )0ter installation o0 one co$5 o0 the 'O7-W)6% P6O4>C$ursuant to this %>L). 5ou #a5 *ee$ the original #edia on which the 'O7-W)6% P6O4>C- was $rovided +5 @icroso0t solel5 0or +ac*u$ or archival $ur$oses. I0 the original #edia is required to use the 'O7-W)6% P6O4>C- on the CO@P>-%6. 5ou #a5 #a*e one co$5 o0 the 'O7-W)6% P6O4>C- solel5 0or +ac*u$ or archival $ur$oses. %&ce$t as e&$ressl5 $rovided in this %>L). 5ou #a5 not otherwise #a*e co$ies o0 the 'O7-W)6% P6O4>C- or the $rinted #aterials acco#$an5ing the 'O7-W)6% P6O4>C-. !. >.'. GO8%6(@%(- 6%'-6IC-%4 6IG9-'. -he 'O7-W)6% P6O4>C- and docu#entation are $rovided with 6%'-6IC-%4 6IG9-'. >se. du$lication. or disclosure +5 the Govern#ent is su+/ect to restrictions as set 0orth in su+$aragra$h 1c21121ii2 o0 the 6ights in -echnical 4ata and Co#$uter 'o0tware clause at 47)6' 2!2.22C;CF13 or su+$aragra$hs 1c2112 and 122 o0 the Co##ercial Co#$uter 'o0tware;6estricted 6ights at D C76 !2.22C;1E. as a$$lica+le. @anu0acturer is @icroso0t Cor$oration?One @icroso0t Wa5?6ed#ond. W) EDF!2;"3EE. ". %TPO6- 6%'-6IC-IO('. Bou agree that 5ou will not e&$ort or re;e&$ort the 'O7-W)6% P6O4>C-. an5 $art thereo0. or an5 $rocess or service that is the direct $roduct o0 the 'O7-W)6% P6O4>C- 1the 0oregoing collectivel5 re0erred to as the =6estricted Co#$onents=2. to an5 countr5. $erson. entit5 or end user su+/ect to >.'. e&$ort restrictions. Bou s$eci0icall5 agree not to e&$ort or re; e&$ort an5 o0 the 6estricted Co#$onents 1i2 to an5 countr5 to which the >.'. has e#+argoed or restricted the e&$ort o0 goods or services. which currentl5 include. +ut are not necessaril5 li#ited to Cu+a. Iran. Iraq. Li+5a. (orth Rorea. 'udan and '5ria. or to an5 national o0 an5 such countr5. wherever located. who intends to trans#it or trans$ort the 6estricted Co#$onents +ac* to such countr5L 1ii2 to an5 end;user who 5ou *now or have reason to *now will utili:e the 6estricted Co#$onents in the design. develo$#ent or $roduction o0 nuclear. che#ical or +iological wea$onsL or 1iii2 to an5 end;user who has +een

#&(

$rohi+ited 0ro# $artici$ating in >.'. e&$ort transactions +5 an5 0ederal agenc5 o0 the >.'. govern#ent. Bou warrant and re$resent that neither the 3T) nor an5 other >.'. 0ederal agenc5 has sus$ended. revo*ed. or denied 5our e&$ort $rivileges. C. (O-% O( A)8) '>PPO6-. -9% 'O7-W)6% P6O4>C- @)B CO(-)I( '>PPO6- 7O6 P6OG6)@' W6I--%( I( A)8). A)8) -%C9(OLOGB I' (O7)>L- -OL%6)(- )(4 I' (O- 4%'IG(%4. @)(>7)C->6%4. O6 I(-%(4%4 7O6 >'% O6 6%')L% )' O(;LI(% CO(-6OL %Q>IP@%(- I( 9)W)64O>' %(8I6O(@%(-' 6%Q>I6I(G 7)IL;')7% P%67O6@)(C%. '>C9 )' I( -9% OP%6)-IO( O7 (>CL%)6 7)CILI-I%'. )I6C6)7- ()8IG)-IO( O6 CO@@>(IC)-IO( 'B'-%@'. )I6 -6)77IC CO(-6OL. 4I6%C- LI7% '>PPO6@)C9I(%'. O6 W%)PO(' 'B'-%@'. I( W9IC9 -9% 7)IL>6% O7 A)8) -%C9(OLOGB CO>L4 L%)4 4I6%C-LB -O 4%)-9. P%6'O()L I(A>6B. O6 '%8%6% P9B'IC)L O6 %(8I6O(@%(-)L 4)@)G%. @I'C%LL)(%O>' I0 5ou acquired this $roduct in the >nited 'tates. this %>L) is governed +5 the laws o0 the 'tate o0 Washington. I0 5ou acquired this $roduct in Canada. this %>L) is governed +5 the laws o0 the Province o0 Ontario. Canada. %ach o0 the $arties hereto irrevoca+l5 attorns to the /urisdiction o0 the courts o0 the Province o0 Ontario and 0urther agrees to co##ence an5 litigation which #a5 arise hereunder in the courts located in the Audicial 4istrict o0 Bor*. Province o0 Ontario. I0 this $roduct was acquired outside the >nited 'tates. then local law #a5 a$$l5. 'hould 5ou have an5 questions concerning this %>L). or i0 5ou desire to contact @icroso0t 0or an5 reason. $lease contact @icroso0t. or write, @icroso0t 'ales In0or#ation Center?One @icroso0t Wa5?6ed#ond. W) EDF!2;"3EE. LI@I-%4 W)66)(-B LI@I-%4 W)66)(-B. @icroso0t warrants that 1a2 the 'O7-W)6% P6O4>C- will $er0or# su+stantiall5 in accordance with the acco#$an5ing written #aterials 0or a $eriod o0 ninet5 1EF2 da5s 0ro# the date o0 recei$t. and 1+2 an5 'u$$ort 'ervices $rovided +5 @icroso0t shall +e su+stantiall5 as descri+ed in a$$lica+le written #aterials $rovided to 5ou +5 @icroso0t. and @icroso0t su$$ort engineers will #a*e co##erciall5 reasona+le e00orts to solve an5 $ro+le#. -o the e&tent allowed +5 a$$lica+le law. i#$lied warranties on the 'O7-W)6% P6O4>C-. i0 an5. are li#ited to ninet5 1EF2 da5s. 'o#e states?/urisdictions do

#&1

not allow li#itations on duration o0 an i#$lied warrant5. so the a+ove li#itation #a5 not a$$l5 to 5ou. C>'-O@%6 6%@%4I%'. @icroso0tXs and its su$$liersX entire lia+ilit5 and 5our e&clusive re#ed5 shall +e. at @icroso0tXs o$tion. either 1a2 return o0 the $rice $aid. i0 an5. or 1+2 re$air or re$lace#ent o0 the 'O7-W)6% P6O4>C- that does not #eet @icroso0tXs Li#ited Warrant5 and that is returned to @icroso0t with a co$5 o0 5our recei$t. -his Li#ited Warrant5 is void i0 0ailure o0 the 'O7-W)6% P6O4>C- has resulted 0ro# accident. a+use. or #isa$$lication. )n5 re$lace#ent 'O7-W)6% P6O4>C- will +e warranted 0or the re#ainder o0 the original warrant5 $eriod or thirt5 13F2 da5s. whichever is longer. Outside the >nited 'tates. neither these re#edies nor an5 $roduct su$$ort services o00ered +5 @icroso0t are availa+le without $roo0 o0 $urchase 0ro# an authori:ed international source. (O O-9%6 W)66)(-I%'. -O -9% @)TI@>@ %T-%(- P%6@I--%4 3B )PPLIC)3L% L)W. @IC6O'O7- )(4 I-' '>PPLI%6' 4I'CL)I@ )LL O-9%6 W)66)(-I%' )(4 CO(4I-IO('. %I-9%6 %TP6%'' O6 I@PLI%4. I(CL>4I(G. 3>- (O- LI@I-%4 -O. I@PLI%4 W)66)(-I%' O6 CO(4I-IO(' O7 @%6C9)(-)3ILI-B. 7I-(%'' 7O6 ) P)6-IC>L)6 P>6PO'%. -I-L% )(4 (O(; I(76I(G%@%(-. WI-9 6%G)64 -O -9% 'O7-W)6% P6O4>C-. )(4 -9% P6O8I'IO( O7 O6 7)IL>6% -O P6O8I4% '>PPO6- '%68IC%'. -9I' LI@I-%4 W)66)(-B GI8%' BO> 'P%CI7IC L%G)L 6IG9-'. BO> @)B 9)8% O-9%6'. W9IC9 8)6B 76O@ '-)-%?A>6I'4IC-IO( -O '-)-%?A>6I'4IC-IO(. LI@I-)-IO( O7 LI)3ILI-B. -O -9% @)TI@>@ %T-%(- P%6@I--%4 3B )PPLIC)3L% L)W. I( (O %8%(- '9)LL @IC6O'O7- O6 I-' '>PPLI%6' 3% LI)3L% 7O6 )(B 'P%CI)L. I(CI4%(-)L. I(4I6%C-. O6 CO('%Q>%(-I)L 4)@)G%' W9)-'O%8%6 1I(CL>4I(G. WI-9O>- LI@I-)-IO(. 4)@)G%' 7O6 LO'' O7 3>'I(%'' P6O7I-'. 3>'I(%'' I(-%66>P-IO(. LO'' O7 3>'I(%'' I(7O6@)-IO(. O6 )(B O-9%6 P%C>(I)6B LO''2 )6I'I(G O>- O7 -9% >'% O7 O6 I()3ILI-B -O >'% -9% 'O7-W)6% P6O4>C- O6 -9% 7)IL>6% -O P6O8I4% '>PPO6- '%68IC%'. %8%( I7 @IC6O'O7- 9)' 3%%( )48I'%4 O7 -9% PO''I3ILI-B O7 '>C9 4)@)G%'. I( )(B C)'%. @IC6O'O7-X' %(-I6% LI)3ILI-B >(4%6 )(B P6O8I'IO( O7 -9I' %>L) '9)LL 3% LI@I-%4 -O -9% G6%)-%6 O7 -9% )@O>(- )C->)LLB P)I4 3B BO> 7O6 -9% 'O7-W)6% P6O4>C- O6 >.'.Y!.FFL P6O8I4%4. 9OW%8%6. I7 BO> 9)8% %(-%6%4 I(-O ) @IC6O'O7- '>PPO6- '%68IC%' )G6%%@%(-. @IC6O'O7-X' %(-I6% LI)3ILI-B 6%G)64I(G '>PPO6- '%68IC%' '9)LL 3% GO8%6(%4 3B -9% -%6@' O7 -9)- )G6%%@%(-. 3%C)>'% 'O@% '-)-%'?A>6I'4IC-IO(' 4O (O- )LLOW -9% %TCL>'IO( O6 LI@I-)-IO( O7 LI)3ILI-B. -9% )3O8% LI@I-)-IO( @)B (O- )PPLB -O BO>. F E! Part (o. " 3!D

#&)

LIC%('% )G6%%@%(- 7O6 @ind8iew. Inc.Xs -hin*ing in C, 7oundations 0or Aava I CUU C4 6O@ +5 Chuc* )llison -his C4 is $rovided together with the +oo* =-hin*ing in Aava. 2 nd edition.= 6%)4 -9I' )G6%%@%(- 3%7O6% >'I(G -9I' =-hin*ing in C, 7oundations 0or CUU I Aava= 19erea0ter called =C4=2. 3B >'I(G -9% C4 BO> )G6%% -O 3% 3O>(4 3B -9% -%6@' )(4 CO(4I-IO(' O7 -9I' )G6%%@%(-. I7 BO> 4O (O- )G6%% -O -9% -%6@' )(4 CO(4I-IO(' O7 -9I' )G6%%@%(-. I@@%4I)-%LB 6%->6( -9% >(>'%4 C4 7O6 ) 7>LL 6%7>(4 O7 @O(I%' P)I4. I7 )(B. Z2FFF @ind8iew. Inc. )ll rights reserved. Printed in the >.'. 'O7-W)6% 6%Q>I6%@%(-' -he $ur$ose o0 this C4 is to $rovide the Content. not the associated so0tware necessar5 to view the Content. -he Content o0 this C4 is in 9-@L 0or viewing with @icroso0t Internet %&$lorer or newer. and uses @icroso0t 'ound Codecs availa+le in @icroso0tXs Windows @edia Pla5er 0or Windows. It is 5our res$onsi+ilit5 to correctl5 install the a$$ro$riate @icroso0t so0tware 0or 5our s5ste#. -he te&t. i#ages. and other #edia included on this C4 1=Content=2 and their co#$ilation are licensed to 5ou su+/ect to the ter#s and conditions o0 this )gree#ent +5 @ind8iew. Inc.. having a $lace o0 +usiness at !3 3 8alle 8ista. La @esa. C) E1E 1. Bour rights to use other $rogra#s and #aterials included on the C4 are also governed +5 se$arate agree#ents distri+uted with those $rogra#s and #aterials on the C4 1the =Other )gree#ents=2. In the event o0 an5 inconsistenc5 +etween this )gree#ent and the Other )gree#ents. this )gree#ent shall govern. 35 using this C4. 5ou agree to +e +ound +5 the ter#s and conditions o0 this )gree#ent. @ind8iew. Inc. owns title to the Content and to all intellectual $ro$ert5 rights therein. e&ce$t inso0ar as it contains #aterials that are $ro$rietar5 to third;$art5 su$$liers. )ll rights in the Content e&ce$t those e&$ressl5 granted to 5ou in this )gree#ent are reserved to @ind8iew. Inc. and such su$$liers as their res$ective interests #a5 a$$ear. 1. LI@I-%4 LIC%('% @ind8iew. Inc. grants 5ou a li#ited. none&clusive. nontrans0era+le license to use the Content on a single dedicated co#$uter 1e&cluding networ* servers2. -his )gree#ent and 5our rights hereunder shall auto#aticall5 ter#inate i0 5ou

0ail to co#$l5 with an5 $rovisions o0 this )gree#ent or an5 o0 the Other )gree#ents. >$on such ter#ination. 5ou agree to destro5 the C4 and all co$ies o0 the C4. whether law0ul or not. that are in 5our $ossession or under 5our control. 2. )44I-IO()L 6%'-6IC-IO(' a. Bou shall not 1and shall not $er#it other $ersons or entities to2 directl5 or indirectl5. +5 electronic or other #eans. re$roduce 1e&ce$t 0or archival $ur$oses as $er#itted +5 law2. $u+lish. distri+ute. rent. lease. sell. su+license. assign. or otherwise trans0er the Content or an5 $art thereo0. +. Bou shall not 1and shall not $er#it other $ersons or entities to2 use the Content or an5 $art thereo0 0or an5 co##ercial $ur$ose or #erge. #odi05. create derivative wor*s o0. or translate the Content. c. Bou shall not 1and shall not $er#it other $ersons or entities to2 o+scure @ind8iewXs or its su$$liers co$5right. trade#ar*. or other $ro$rietar5 notices or legends 0ro# an5 $ortion o0 the Content or an5 related #aterials. 3. P%6@I''IO(' a. %&ce$t as noted in the Contents o0 the C4. 5ou #ust treat this so0tware /ust li*e a +oo*. 9owever. 5ou #a5 co$5 it onto a co#$uter to +e used and 5ou #a5 #a*e archival co$ies o0 the so0tware 0or the sole $ur$ose o0 +ac*ing u$ the so0tware and $rotecting 5our invest#ent 0ro# loss. 35 sa5ing. =/ust li*e a +oo*.= @ind8iew. Inc. #eans. 0or e&a#$le. that this so0tware #a5 +e used +5 an5 nu#+er o0 $eo$le and #a5 +e 0reel5 #oved 0ro# one co#$uter location to another. so long as there is no $ossi+ilit5 o0 its +eing used at one location or on one co#$uter while it is +eing used at another. Aust as a +oo* cannot +e read +5 two di00erent $eo$le in two di00erent $laces at the sa#e ti#e. neither can the so0tware +e used +5 two di00erent $eo$le in two di00erent $laces at the sa#e ti#e. +. Bou #a5 show or de#onstrate the un;#odi0ied Content in a live $resentation. live se#inar. or live $er0or#ance as long as 5ou attri+ute all #aterial o0 the Content to @ind8iew. Inc. c. Other $er#issions and grants o0 rights 0or use o0 the C4 #ust +e o+tained directl5 0ro# @ind8iew. Inc. at htt$,??www.@ind8iew.net. 13ul* co$ies o0 the C4 #a5 also +e $urchased at this site.2 4I'CL)I@%6 O7 W)66)(-B -he Content and C4 are $rovided =)' I'= without warrant5 o0 an5 *ind. either

e&$ress or i#$lied. including. without li#itation. an5 warrant5 o0 #erchanta+ilit5 and 0itness 0or a $articular $ur$ose. -he entire ris* as to the results and $er0or#ance o0 the C4 and Content is assu#ed +5 5ou. @ind8iew. Inc. and its su$$liers assu#e no res$onsi+ilit5 0or de0ects in the C4. the accurac5 o0 the Content. or o#issions in the C4 or the Content. @ind8iew. Inc. and its su$$liers do not warrant. guarantee. or #a*e an5 re$resentations regarding the use. or the results o0 the use. o0 the $roduct in ter#s o0 correctness. accurac5. relia+ilit5. currentness. or otherwise. or that the Content will #eet 5our needs. or that o$eration o0 the C4 will +e uninterru$ted or error;0ree. or that an5 de0ects in the C4 or Content will +e corrected. @ind8iew. Inc. and its su$$liers shall not +e lia+le 0or an5 loss. da#ages. or costs arising 0ro# the use o0 the C4 or the inter$retation o0 the Content. 'o#e states do not allow e&clusion or li#itation o0 i#$lied warranties or li#itation o0 lia+ilit5 0or incidental or consequential da#ages. so all o0 the a+ove li#itations or e&clusions #a5 not a$$l5 to 5ou. In no event shall @ind8iew. Inc. or its su$$liersX total lia+ilit5 to 5ou 0or all da#ages. losses. and causes o0 action 1whether in contract. tort. or otherwise2 e&ceed the a#ount $aid +5 5ou 0or the C4. @ind8iew. Inc.. and Prentice;9all. Inc. s$eci0icall5 disclai# the i#$lied warrantees o0 #erchanta+ilit5 and 0itness 0or a $articular $ur$ose. (o oral or written in0or#ation or advice given +5 @ind8iew. Inc.. Prentice;9all. Inc.. their dealers. distri+utors. agents or e#$lo5ees shall create a warrantee. Bou #a5 have other rights. which var5 0ro# state to state. (either @ind8iew. Inc.. 3ruce %c*el. Chuc* )llison. Prentice;9all. nor an5one else who has +een involved in the creation. $roduction or deliver5 o0 the $roduct shall +e lia+le 0or an5 direct. indirect. consequential. or incidental da#ages 1including da#ages 0or loss o0 +usiness $ro0its. +usiness interru$tion. loss o0 +usiness in0or#ation. and the li*e2 arising out o0 the use o0 or ina+ilit5 to use the $roduct even i0 @ind8iew. Inc.. has +een advised o0 the $ossi+ilit5 o0 such da#ages. 3ecause so#e states do not allow the e&clusion or li#itation o0 lia+ilit5 0or consequential or incidental da#ages. the a+ove li#itation #a5 not a$$l5 to 5ou. -his C4 is $rovided as a su$$le#ent to the +oo* =-hin*ing in Aava 2nd edition.= -he sole res$onsi+ilit5 o0 Prentice;9all will +e to $rovide a re$lace#ent C4 in the event that the one that ca#e with the +oo* is de0ective. -his re$lace#ent warrantee shall +e in e00ect 0or a $eriod o0 si&t5 da5s 0ro# the $urchase date. @ind8iew. Inc. does not +ear an5 additional res$onsi+ilit5 0or the C4. (O -%C9(IC)L '>PPO6- I' P6O8I4%4 WI-9 -9I' C4 6O@

#&5

-he 0ollowing are trade#ar*s o0 their res$ective co#$anies in the >.'. and #a5 +e $rotected as trade#ar*s in other countries, 'un and the 'un Logo. 'un @icros5ste#s. Aava. all Aava;+ased na#es and logos and the Aava Co00ee Cu$ are trade#ar*s o0 'un @icros5ste#sL Internet %&$lorer. the Windows @edia Pla5er. 4O'. Windows E!. and Windows (- are trade#ar*s o0 @icroso0t.

Thin(ing in C- %oundations for +ava . C//


@ulti#edia 'e#inar;on;C4 6O@ g2$$$ AindCie!, -nc) =ll right# re#erved)
='*,B, D B&:1*& 1!&,B, +"& $B#C !'CE' &, C'*&:VLL@ *&'$ +"& +&*.# ',$ C1,$B+B1,# 1: +"& LBC&,#& ' *&&.&,+ L ='*',+&& LB.B+'+B1, 1, +"& !*&HB1V# !' &#6

The C? ROA packaged !ith thi# 3**k i# a +ulti+edia #e+inar c*n#i#ting *9 #ynchr*ni7ed #lide# and audi* lecture#) The g*al *9 thi# #e+inar i# t* intr*duce y*u t* the a#pect# *9 C that are nece##ary 9*r y*u t* +*ve *n t* C@@ *r "ava, leaving *ut the unplea#ant part# that C pr*gra++er# +u#t deal !ith *n a dayEt*Eday 3a#i# 3ut that the C@@ and "ava language# #teer y*u a!ay 9r*+) The C? al#* c*ntain# thi# 3**k in HTAL 9*r+ al*ng !ith the #*urce c*de 9*r the 3**k) Thi# C? ROA !ill !*rk !ith ,ind*!# G!ith a #*und #y#te+H) H*!ever, y*u +u#t1

0) -n#tall the +*#t recent ver#i*n *9 Aicr*#*9t# -nternet E;pl*rer) Becau#e *9 the 9eature# pr*vided *n the C?, it !ill OT !*rk !ith et#cape avigat*r) +he Bnternet &xplorer software for =indows R?/,+ is included on the C$6 2) -n#tall Aicr*#*9t# Gindows .edia /la4er) +he .edia !layer software for =indows R?/,+ is included on the C$6 :*u can al#* g* t* httpD//www6microsoft6com/windows/mediaplayer and 9*ll*! the in#tructi*n# *r link# there t* d*!nl*ad and in#tall the Aedia Player 9*r y*ur particular plat9*r+) /) =t thi# p*int y*u #h*uld 3e a3le t* play the lecture# *n the C?) U#ing the -nternet E;pl*rer ,e3 3r*!#er, *pen the 9ile Bnstall6html that y*ull 9ind *n the C?) Thi# !ill intr*duce y*u t* the C? and pr*vide 9urther in#tructi*n# a3*ut the u#e *9 the C?)

#&#

Das könnte Ihnen auch gefallen