100% found this document useful (2 votes)
615 views448 pages

Programming Scala

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (2 votes)
615 views448 pages

Programming Scala

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Download at WoweBook.

Com
Programming Scala

Download at WoweBook.Com
Download at WoweBook.Com
Programming Scala

'HDQ:DPSOHUDQG$OH[3D\QH

Beijing • Cambridge • Farnham • Köln • Sebastopol • Taipei • Tokyo

Download at WoweBook.Com
Programming Scala
E\'HDQ:DPSOHUDQG$OH[3D\QH

&RS\ULJKW‹'HDQ:DPSOHUDQG$OH[3D\QH$OOULJKWVUHVHUYHG
3ULQWHGLQWKH8QLWHG6WDWHVRI$PHULFD

3XEOLVKHGE\2¦5HLOO\0HGLD,QF*UDYHQVWHLQ+LJKZD\1RUWK6HEDVWRSRO&$

2¦5HLOO\ERRNVPD\EHSXUFKDVHGIRUHGXFDWLRQDOEXVLQHVVRUVDOHVSURPRWLRQDOXVH2QOLQHHGLWLRQV
DUHDOVRDYDLODEOHIRUPRVWWLWOHV KWWSP\VDIDULERRNVRQOLQHFRP )RUPRUHLQIRUPDWLRQFRQWDFWRXU
FRUSRUDWHLQVWLWXWLRQDOVDOHVGHSDUWPHQWRUFRUSRUDWH#RUHLOO\FRP

Editor: 0LNH/RXNLGHV Indexer: (OOHQ7URXWPDQ=DLJ


Production Editor: 6DUDK6FKQHLGHU Cover Designer: .DUHQ0RQWJRPHU\
Proofreader: 6DUDK6FKQHLGHU Interior Designer: 'DYLG)XWDWR
Illustrator: 5REHUW5RPDQR

Printing History:
6HSWHPEHU )LUVW(GLWLRQ

2¦5HLOO\DQGWKH2¦5HLOO\ORJRDUHUHJLVWHUHGWUDGHPDUNVRI2¦5HLOO\0HGLD,QF3URJUDPPLQJ6FDODWKH
LPDJHRID0DOD\DQWDSLUDQGUHODWHGWUDGHGUHVVDUHWUDGHPDUNVRI2¦5HLOO\0HGLD,QF
0DQ\RIWKHGHVLJQDWLRQVXVHGE\PDQXIDFWXUHUVDQGVHOOHUVWRGLVWLQJXLVKWKHLUSURGXFWVDUHFODLPHGDV
WUDGHPDUNV:KHUHWKRVHGHVLJQDWLRQVDSSHDULQWKLVERRNDQG2¦5HLOO\0HGLD,QFZDVDZDUHRID
WUDGHPDUNFODLPWKHGHVLJQDWLRQVKDYHEHHQSULQWHGLQFDSVRULQLWLDOFDSV

:KLOHHYHU\SUHFDXWLRQKDVEHHQWDNHQLQWKHSUHSDUDWLRQRIWKLVERRNWKHSXEOLVKHUDQGDXWKRUVDVVXPH
QRUHVSRQVLELOLW\IRUHUURUVRURPLVVLRQVRUIRUGDPDJHVUHVXOWLQJIURPWKHXVHRIWKHLQIRUPDWLRQFRQ
WDLQHGKHUHLQ7KLVZRUNKDVEHHQUHOHDVHGXQGHUWKH&UHDWLYH&RPPRQV$WWULEXWLRQ1RQFRPPHUFLDO
OLFHQVH

,6%1

>0@



Download at WoweBook.Com
7R'DGDQG0RPZKRDOZD\VEHOLHYHGLQPH
7R$QQZKRZDVDOZD\VWKHUHIRUPH
¢'HDQ

7RP\PRWKHUZKRJDYHPHDQDSSUHFLDWLRQIRU
JRRGZULWLQJDQGWKHDFFRPSDQ\LQJLQWHOOHFWXDO
WRROVZLWKZKLFKWRDWWHPSWWRSURGXFHLW
7R.ULVWHQIRUKHUXQHQGLQJSDWLHQFHORYHDQG
NLQGQHVV
¢$OH[

Download at WoweBook.Com
Download at WoweBook.Com
Table of Contents

Foreword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii

1. Zero to Sixty: Introducing Scala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1


:K\6FDOD" 
,I<RX$UHD-DYD3URJUDPPHUš 
,I<RX$UHD5XE\3\WKRQHWF3URJUDPPHUš 
,QWURGXFLQJ6FDOD 
7KH6HGXFWLRQVRI6FDOD 
,QVWDOOLQJ6FDOD 
)RU0RUH,QIRUPDWLRQ 
$7DVWHRI6FDOD 
$7DVWHRI&RQFXUUHQF\ 
5HFDSDQG:KDW¦V1H[W 

2. Type Less, Do More . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23


,Q7KLV&KDSWHU 
6HPLFRORQV 
9DULDEOH'HFODUDWLRQV 
0HWKRG'HFODUDWLRQV 
0HWKRG'HIDXOWDQG1DPHG$UJXPHQWV 6FDOD9HUVLRQ 
1HVWLQJ0HWKRG'HILQLWLRQV 
,QIHUULQJ7\SH,QIRUPDWLRQ 
/LWHUDOV 
,QWHJHU/LWHUDOV 
)ORDWLQJ3RLQW/LWHUDOV 
%RROHDQ/LWHUDOV 
&KDUDFWHU/LWHUDOV 
6WULQJ/LWHUDOV 
6\PERO/LWHUDOV 

vii

Download at WoweBook.Com
7XSOHV 
2SWLRQ6RPHDQG1RQH$YRLGLQJQXOOV 
2UJDQL]LQJ&RGHLQ)LOHVDQG1DPHVSDFHV 
,PSRUWLQJ7\SHVDQG7KHLU0HPEHUV 
,PSRUWVDUH5HODWLYH 
$EVWUDFW7\SHV$QG3DUDPHWHUL]HG7\SHV 
5HVHUYHG:RUGV 
5HFDSDQG:KDW¦V1H[W 

3. Rounding Out the Essentials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53


2SHUDWRU"2SHUDWRU" 
6\QWDFWLF6XJDU 
0HWKRGV:LWKRXW3DUHQWKHVHVDQG'RWV 
3UHFHGHQFH5XOHV 
'RPDLQ6SHFLILF/DQJXDJHV 
6FDODLI6WDWHPHQWV 
6FDODIRU&RPSUHKHQVLRQV 
$'RJ6LPSOH([DPSOH 
)LOWHULQJ 
<LHOGLQJ 
([SDQGHG6FRSH 
2WKHU/RRSLQJ&RQVWUXFWV 
6FDODZKLOH/RRSV 
6FDODGRZKLOH/RRSV 
*HQHUDWRU([SUHVVLRQV 
&RQGLWLRQDO2SHUDWRUV 
3DWWHUQ0DWFKLQJ 
$6LPSOH0DWFK 
9DULDEOHVLQ0DWFKHV 
0DWFKLQJRQ7\SH 
0DWFKLQJRQ6HTXHQFHV 
0DWFKLQJRQ7XSOHV DQG*XDUGV 
0DWFKLQJRQ&DVH&ODVVHV 
0DWFKLQJRQ5HJXODU([SUHVVLRQV 
%LQGLQJ1HVWHG9DULDEOHVLQ&DVH&ODXVHV 
8VLQJWU\FDWFKDQGILQDOO\&ODXVHV 
&RQFOXGLQJ5HPDUNVRQ3DWWHUQ0DWFKLQJ 
(QXPHUDWLRQV 
5HFDSDQG:KDW¦V1H[W 

4. Traits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
,QWURGXFLQJ7UDLWV 
7UDLWV$V0L[LQV 

viii | Table of Contents

Download at WoweBook.Com
6WDFNDEOH7UDLWV 
&RQVWUXFWLQJ7UDLWV 
&ODVVRU7UDLW" 
5HFDSDQG:KDW¦V1H[W 

5. Basic Object-Oriented Programming in Scala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89


&ODVVDQG2EMHFW%DVLFV 
3DUHQW&ODVVHV 
&RQVWUXFWRUVLQ6FDOD 
&DOOLQJ3DUHQW&ODVV&RQVWUXFWRUV 
1HVWHG&ODVVHV 
9LVLELOLW\5XOHV 
3XEOLF9LVLELOLW\ 
3URWHFWHG9LVLELOLW\ 
3ULYDWH9LVLELOLW\ 
6FRSHG3ULYDWHDQG3URWHFWHG9LVLELOLW\ 
)LQDO7KRXJKWVRQ9LVLELOLW\ 
5HFDSDQG:KDW¦V1H[W 

6. Advanced Object-Oriented Programming In Scala . . . . . . . . . . . . . . . . . . . . . . . . . . 111


2YHUULGLQJ0HPEHUVRI&ODVVHVDQG7UDLWV 
$WWHPSWLQJWR2YHUULGHILQDO'HFODUDWLRQV 
2YHUULGLQJ$EVWUDFWDQG&RQFUHWH0HWKRGV 
2YHUULGLQJ$EVWUDFWDQG&RQFUHWH)LHOGV 
2YHUULGLQJ$EVWUDFWDQG&RQFUHWH)LHOGVLQ7UDLWV 
2YHUULGLQJ$EVWUDFWDQG&RQFUHWH)LHOGVLQ&ODVVHV 
2YHUULGLQJ$EVWUDFW7\SHV 
:KHQ$FFHVVRU0HWKRGVDQG)LHOGV$UH,QGLVWLQJXLVKDEOH7KH8QL
IRUP$FFHVV3ULQFLSOH 
&RPSDQLRQ2EMHFWV 
$SSO\ 
8QDSSO\ 
$SSO\DQG8QDSSO\6HTIRU&ROOHFWLRQV 
&RPSDQLRQ2EMHFWVDQG-DYD6WDWLF0HWKRGV 
&DVH&ODVVHV 
6\QWDFWLF6XJDUIRU%LQDU\2SHUDWLRQV 
7KHFRS\0HWKRGLQ6FDOD9HUVLRQ 
&DVH&ODVV,QKHULWDQFH 
(TXDOLW\RI2EMHFWV 
7KHHTXDOV0HWKRG 
7KH DQG 0HWKRGV 
7KHQHDQGHT0HWKRGV 
$UUD\(TXDOLW\DQGWKHVDPH(OHPHQWV0HWKRG 

Table of Contents | ix

Download at WoweBook.Com
5HFDSDQG:KDW¦V1H[W 

7. The Scala Object System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145


7KH3UHGHI2EMHFW 
&ODVVHVDQG2EMHFWV:KHUH$UHWKH6WDWLFV" 
3DFNDJH2EMHFWV 
6HDOHG&ODVV+LHUDUFKLHV 
7KH6FDOD7\SH+LHUDUFK\ 
/LQHDUL]DWLRQRIDQ2EMHFW¦V+LHUDUFK\ 
5HFDSDQG:KDW¦V1H[W 

8. Functional Programming in Scala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165


:KDW,V)XQFWLRQDO3URJUDPPLQJ" 
)XQFWLRQVLQ0DWKHPDWLFV 
9DULDEOHVWKDW$UHQ¦W 
)XQFWLRQDO3URJUDPPLQJLQ6FDOD 
)XQFWLRQ/LWHUDOVDQG&ORVXUHV 
3XULW\,QVLGH9HUVXV2XWVLGH 
5HFXUVLRQ 
7DLO&DOOVDQG7DLO&DOO2SWLPL]DWLRQ 
7UDPSROLQHIRU7DLO&DOOV 
)XQFWLRQDO'DWD6WUXFWXUHV 
/LVWVLQ)XQFWLRQDO3URJUDPPLQJ 
0DSVLQ)XQFWLRQDO3URJUDPPLQJ 
6HWVLQ)XQFWLRQDO3URJUDPPLQJ 
2WKHU'DWD6WUXFWXUHVLQ)XQFWLRQDO3URJUDPPLQJ 
7UDYHUVLQJ0DSSLQJ)LOWHULQJ)ROGLQJDQG5HGXFLQJ 
7UDYHUVDO 
0DSSLQJ 
)LOWHULQJ 
)ROGLQJDQG5HGXFLQJ 
)XQFWLRQDO2SWLRQV 
3DWWHUQ0DWFKLQJ 
3DUWLDO)XQFWLRQV 
&XUU\LQJ 
,PSOLFLWV 
,PSOLFLW&RQYHUVLRQV 
,PSOLFLW)XQFWLRQ3DUDPHWHUV 
)LQDO7KRXJKWVRQ,PSOLFLWV 
&DOOE\1DPH&DOOE\9DOXH 
/D]\9DOV 
5HFDS)XQFWLRQDO&RPSRQHQW$EVWUDFWLRQV 

x | Table of Contents

Download at WoweBook.Com
9. Robust, Scalable Concurrency with Actors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
7KH3UREOHPVRI6KDUHG6\QFKURQL]HG6WDWH 
$FWRUV 
$FWRUVLQ$EVWUDFW 
$FWRUVLQ6FDOD 
6HQGLQJ0HVVDJHVWR$FWRUV 
7KH0DLOER[ 
$FWRUVLQ'HSWK 
(IIHFWLYH$FWRUV 
7UDGLWLRQDO&RQFXUUHQF\LQ6FDOD7KUHDGLQJDQG(YHQWV 
2QH2II7KUHDGV 
8VLQJMDYDXWLOFRQFXUUHQW 
(YHQWV 
5HFDSDQG:KDW¦V1H[W 

10. Herding XML in Scala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211


5HDGLQJ;0/ 
([SORULQJ;0/ 
/RRSLQJDQG0DWFKLQJ;0/ 
:ULWLQJ;0/ 
$5HDO:RUOG([DPSOH 
5HFDSDQG:KDW¦V1H[W 

11. Domain-Specific Languages in Scala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217


,QWHUQDO'6/V 
$3D\UROO,QWHUQDO'6/ 
,QIL[2SHUDWRU1RWDWLRQ 
,PSOLFLW&RQYHUVLRQVDQG8VHU'HILQHG7\SHV 
$SSO\0HWKRGV 
3D\UROO5XOHV'6/,PSOHPHQWDWLRQ 
,QWHUQDO'6/V)LQDO7KRXJKWV 
([WHUQDO'6/VZLWK3DUVHU&RPELQDWRUV 
$ERXW3DUVHU&RPELQDWRUV 
$3D\UROO([WHUQDO'6/ 
$6FDOD,PSOHPHQWDWLRQRIWKH([WHUQDO'6/*UDPPDU 
*HQHUDWLQJ3D\FKHFNVZLWKWKH([WHUQDO'6/ 
,QWHUQDO9HUVXV([WHUQDO'6/V)LQDO7KRXJKWV 
5HFDSDQG:KDW¦V1H[W 

12. The Scala Type System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247


5HIOHFWLQJRQ7\SHV 
8QGHUVWDQGLQJ3DUDPHWHUL]HG7\SHV 
0DQLIHVWV 

Table of Contents | xi

Download at WoweBook.Com
3DUDPHWHUL]HG0HWKRGV 
9DULDQFH8QGHU,QKHULWDQFH 
9DULDQFHRI0XWDEOH7\SHV 
9DULDQFH,Q6FDOD9HUVXV-DYD 
,PSOHPHQWDWLRQ1RWHV 
7\SH%RXQGV 
8SSHU7\SH%RXQGV 
/RZHU7\SH%RXQGV 
$&ORVHU/RRNDW/LVWV 
9LHZVDQG9LHZ%RXQGV 
1RWKLQJDQG1XOO 
8QGHUVWDQGLQJ$EVWUDFW7\SHV 
3DUDPHWHUL]HG7\SHV9HUVXV$EVWUDFW7\SHV 
3DWK'HSHQGHQW7\SHV 
&WKLV 
&VXSHU 
SDWK[ 
9DOXH7\SHV 
7\SH'HVLJQDWRUV 
7XSOHV 
3DUDPHWHUL]HG7\SHV 
$QQRWDWHG7\SHV 
&RPSRXQG7\SHV 
,QIL[7\SHV 
)XQFWLRQ7\SHV 
7\SH3URMHFWLRQV 
6LQJOHWRQ7\SHV 
6HOI7\SH$QQRWDWLRQV 
6WUXFWXUDO7\SHV 
([LVWHQWLDO7\SHV 
,QILQLWH'DWD6WUXFWXUHVDQG/D]LQHVV 
5HFDSDQG:KDW¦V1H[W 

13. Application Design . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289


$QQRWDWLRQV 
(QXPHUDWLRQV9HUVXV3DWWHUQ0DWFKLQJ 
7KRXJKWV2Q$QQRWDWLRQVDQG(QXPHUDWLRQV 
(QXPHUDWLRQV9HUVXV&DVH&ODVVHVDQG3DWWHUQ0DWFKLQJ 
8VLQJ1XOOV9HUVXV2SWLRQV 
2SWLRQVDQGIRU&RPSUHKHQVLRQV 
([FHSWLRQVDQGWKH$OWHUQDWLYHV 
6FDODEOH$EVWUDFWLRQV 
)LQH*UDLQHG9LVLELOLW\5XOHV 

xii | Table of Contents

Download at WoweBook.Com
0L[LQ&RPSRVLWLRQ 
6HOI7\SH$QQRWDWLRQVDQG$EVWUDFW7\SH0HPEHUV 
(IIHFWLYH'HVLJQRI7UDLWV 
'HVLJQ3DWWHUQV 
7KH9LVLWRU3DWWHUQ$%HWWHU$OWHUQDWLYH 
'HSHQGHQF\,QMHFWLRQLQ6FDOD7KH&DNH3DWWHUQ 
%HWWHU'HVLJQZLWK'HVLJQ%\&RQWUDFW 
5HFDSDQG:KDW¦V1H[W 

14. Scala Tools, Libraries, and IDE Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343


&RPPDQG/LQH7RROV 
VFDODF&RPPDQG/LQH7RRO 
7KHVFDOD&RPPDQG/LQH7RRO 
7KHVFDODSMDYDSDQGMDG&RPPDQG/LQH7RROV 
7KHVFDODGRF&RPPDQG/LQH7RRO 
7KHVED]&RPPDQG/LQH7RRO 
7KHIVF&RPPDQG/LQH7RRO 
%XLOG7RROV 
,QWHJUDWLRQZLWK,'(V 
(FOLSVH 
,QWHOOL- 
1HW%HDQV 
7H[W(GLWRUV 
7HVW'ULYHQ'HYHORSPHQWLQ6FDOD 
6FDOD7HVW 
6SHFV 
6FDOD&KHFN 
2WKHU1RWDEOH6FDOD/LEUDULHVDQG7RROV 
/LIW 
6FDOD] 
6FDOD[ 
0HWD6FDOD 
-DYD5HEHO 
0LVFHOODQHRXV6PDOOHU/LEUDULHV 
-DYD,QWHURSHUDELOLW\ 
-DYDDQG6FDOD*HQHULFV 
8VLQJ6FDOD)XQFWLRQVLQ-DYD 
-DYD%HDQ3URSHUWLHV 
$Q\9DO7\SHVDQG-DYD3ULPLWLYHV 
6FDOD1DPHVLQ-DYD&RGH 
-DYD/LEUDU\,QWHURSHUDELOLW\ 
$VSHFW- 
7KH6SULQJ)UDPHZRUN 

Table of Contents | xiii

Download at WoweBook.Com
7HUUDFRWWD 
+DGRRS 
5HFDSDQG:KDW¦V1H[W 

Appendix: References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387

Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407

xiv | Table of Contents

Download at WoweBook.Com
Foreword

,IWKHUHKDVEHHQDFRPPRQWKHPHWKURXJKRXWP\FDUHHUDVDSURJUDPPHULWKDVEHHQ
WKHTXHVWIRUEHWWHUDEVWUDFWLRQVDQGEHWWHUWRROVWRVXSSRUWWKHFUDIWRIZULWLQJVRIWZDUH
2YHUWKH\HDUV,KDYHFRPHWRYDOXHRQHWUDLWPRUHWKDQDQ\RWKHUFRPSRVDELOLW\,I
RQHFDQZULWHFRGHZLWKJRRGFRPSRVDELOLW\LWXVXDOO\PHDQVWKDWRWKHUWUDLWVZHVRIW
ZDUHGHYHORSHUVYDOXH¢VXFKDVRUWKRJRQDOLW\ORRVHFRXSOLQJDQGKLJKFRKHVLRQ¢
DUHDOUHDG\SUHVHQW,WLVDOOFRQQHFWHG
:KHQ,GLVFRYHUHG6FDODVRPH\HDUVDJRWKHWKLQJWKDWPDGHWKHELJJHVWLPSUHVVLRQ
RQPHZDVLWVFRPSRVDELOLW\7KURXJKVRPHYHU\HOHJDQWGHVLJQFKRLFHVDQGVLPSOH\HW
SRZHUIXO DEVWUDFWLRQV WKDW ZHUH WDNHQ IURP WKH REMHFWRULHQWHG DQG IXQFWLRQDO
SURJUDPPLQJ ZRUOGV 0DUWLQ 2GHUVN\ KDV PDQDJHG WR FUHDWH D ODQJXDJH ZLWK KLJK
FRKHVLRQDQGRUWKRJRQDOGHHSDEVWUDFWLRQVWKDWLQYLWHVFRPSRVDELOLW\LQDOOGLPHQVLRQV
RIVRIWZDUHGHVLJQ6FDODLVWUXO\D6&$ODEOH/$QJXDJHWKDWVFDOHVZLWKXVDJHIURP
VFULSWLQJDOOWKHZD\XSWRODUJHVFDOHHQWHUSULVHDSSOLFDWLRQVDQGPLGGOHZDUH6FDOD
ZDVERUQRXWRIDFDGHPLDEXWLWKDVJURZQLQWRDSUDJPDWLFDQGSUDFWLFDOODQJXDJH
WKDWLVYHU\PXFKUHDG\IRUUHDOZRUOGSURGXFWLRQXVH
:KDWH[FLWHVPHPRVWDERXWWKLVERRNLVWKDWLW¦VVRSUDFWLFDO'HDQDQG$OH[KDYHGRQH
DIDQWDVWLFMREQRWRQO\E\H[SODLQLQJWKHODQJXDJHWKURXJKLQWHUHVWLQJGLVFXVVLRQVDQG
VDPSOHV EXW DOVR E\ SXWWLQJ LW LQ WKH FRQWH[W RI WKH UHDO ZRUOG ,W;V ZULWWHQ IRU WKH
SURJUDPPHUZKRZDQWVWRJHWWKLQJVGRQH,KDGWKHSOHDVXUHRIJHWWLQJWRNQRZ'HDQ
VRPH \HDUV DJR ZKHQ ZH ZHUH ERWK SDUW RI WKH DVSHFWRULHQWHG SURJUDPPLQJ FRP
PXQLW\'HDQKROGVDUDUHPL[RIGHHSDQDO\WLFDODFDGHPLFWKLQNLQJDQGDSUDJPDWLF
JHWWKLQJVGRQHNLQGRIPHQWDOLW\$OH[ZKRP,¦YHKDGWKHSOHDVXUHWRPHHWRQFHLV
OHDGLQJWKH$3,WHDPDW7ZLWWHU,QF$OH[KDVSOD\HGDOHDGLQJUROHLQPRYLQJ7ZLWWHU¦V
FRGHDQGLQIUDVWUXFWXUHWR6FDODPDNLQJLWRQHRQWKHILUVWFRPSDQLHVWRVXFFHVVIXOO\
GHSOR\6FDODLQSURGXFWLRQ

xv

Download at WoweBook.Com
<RXDUHDERXWWROHDUQKRZWRZULWHUHXVDEOHFRPSRQHQWVXVLQJPL[LQDQGIXQFWLRQ
FRPSRVLWLRQKRZWRZULWHFRQFXUUHQWDSSOLFDWLRQVXVLQJ6FDOD¦V$FWRUVKRZWRPDNH
HIIHFWLYHXVHRI6FDOD¦V;0/;3DWKVXSSRUWKRZWRXWLOL]H6FDOD;VULFKIOH[LEOHDQG
H[SUHVVLYH V\QWD[ WR EXLOG 'RPDLQ6SHFLILF /DQJXDJHV KRZ WR HIIHFWLYHO\ WHVW \RXU
6FDODFRGHKRZWRXVH6FDODZLWKSRSXODUIUDPHZRUNVVXFKDV6SULQJ+DGRRSDQG
7HUUDFRWWDDQGPXFKPXFKPRUH(QMR\WKHULGH,VXUHGLG
¢-RQDV%RQpU
,QGHSHQGHQW&RQVXOWDQW6FDODEOH6ROXWLRQV$%
$XJXVW

xvi | Foreword

Download at WoweBook.Com
Preface

3URJUDPPLQJ6FDODLQWURGXFHVDQH[FLWLQJQHZODQJXDJHWKDWRIIHUVDOOWKHEHQHILWVRI
DPRGHUQREMHFWPRGHOIXQFWLRQDOSURJUDPPLQJDQGDQDGYDQFHGW\SHV\VWHP3DFNHG
ZLWKFRGHH[DPSOHVWKLVFRPSUHKHQVLYHERRNWHDFKHV\RXKRZWREHSURGXFWLYHZLWK
6FDODTXLFNO\DQGH[SODLQVZKDWPDNHVWKLVODQJXDJHLGHDOIRUWRGD\¦VVFDODEOHGLV
WULEXWHG FRPSRQHQWEDVHG DSSOLFDWLRQV WKDW VXSSRUW FRQFXUUHQF\ DQG GLVWULEXWLRQ
<RX¦OODOVROHDUQKRZ6FDODWDNHVDGYDQWDJHRIWKHDGYDQFHG-DYD9LUWXDO0DFKLQHDVD
SODWIRUPIRUSURJUDPPLQJODQJXDJHV
/HDUQPRUHDWKWWSSURJUDPPLQJVFDODFRPRUDWWKHERRN¦VFDWDORJSDJH

Welcome to Programming Scala


3URJUDPPLQJODQJXDJHVEHFRPHSRSXODUIRUPDQ\UHDVRQV6RPHWLPHVSURJUDPPHUV
RQDJLYHQSODWIRUPSUHIHUDSDUWLFXODUODQJXDJHRURQHLVLQVWLWXWLRQDOL]HGE\DYHQGRU
0RVW0DF26SURJUDPPHUVXVH2EMHFWLYH&0RVW:LQGRZVSURJUDPPHUVXVH&
DQG1(7ODQJXDJHV0RVWHPEHGGHGV\VWHPVGHYHORSHUVXVH&DQG&
6RPHWLPHVSRSXODULW\GHULYHGIURPWHFKQLFDOPHULWJLYHVZD\WRIDVKLRQDQGIDQDWL
FLVP & -DYD DQG 5XE\ KDYH EHHQ WKH REMHFWV RI IDQDWLFDO GHYRWLRQ DPRQJ
SURJUDPPHUV
6RPHWLPHVDODQJXDJHEHFRPHVSRSXODUEHFDXVHLWILWVWKHQHHGVRILWVHUD-DYDZDV
LQLWLDOO\ VHHQ DV D SHUIHFW ILW IRU EURZVHUEDVHG ULFK FOLHQW DSSOLFDWLRQV 6PDOOWDON
FDSWXUHG WKH HVVHQFH RI REMHFWRULHQWHG SURJUDPPLQJ 223  DV WKDW PRGHO RI SUR
JUDPPLQJHQWHUHGWKHPDLQVWUHDP
7RGD\FRQFXUUHQF\KHWHURJHQHLW\DOZD\VRQVHUYLFHVDQGHYHUVKULQNLQJGHYHORS
PHQWVFKHGXOHVDUHGULYLQJLQWHUHVWLQIXQFWLRQDOSURJUDPPLQJ )3 ,WDSSHDUVWKDWWKH
GRPLQDQFHRIREMHFWRULHQWHGSURJUDPPLQJPD\EHRYHU0L[LQJSDUDGLJPVLVEHFRP
LQJSRSXODUHYHQQHFHVVDU\
:HJUDYLWDWHGWR6FDODIURPRWKHUODQJXDJHVEHFDXVH6FDODHPERGLHVPDQ\RIWKHRS
WLPDOTXDOLWLHVZHZDQWLQDJHQHUDOSXUSRVHSURJUDPPLQJODQJXDJHIRUWKHNLQGVRI
DSSOLFDWLRQVZHEXLOGWRGD\UHOLDEOHKLJKSHUIRUPDQFHKLJKO\FRQFXUUHQW,QWHUQHWDQG
HQWHUSULVHDSSOLFDWLRQV

xvii

Download at WoweBook.Com
6FDODLVDPXOWLSDUDGLJPODQJXDJHVXSSRUWLQJERWKREMHFWRULHQWHGDQGIXQFWLRQDO
SURJUDPPLQJDSSURDFKHV6FDODLVVFDODEOHVXLWDEOHIRUHYHU\WKLQJIURPVKRUWVFULSWV
XSWRODUJHVFDOHFRPSRQHQWEDVHGDSSOLFDWLRQV6FDODLVVRSKLVWLFDWHGLQFRUSRUDWLQJ
VWDWHRIWKHDUWLGHDVIURPWKHKDOOVRIFRPSXWHUVFLHQFHGHSDUWPHQWVZRUOGZLGH<HW
6FDODLVSUDFWLFDO,WVFUHDWRU0DUWLQ2GHUVN\SDUWLFLSDWHGLQWKHGHYHORSPHQWRI-DYD
IRU\HDUVDQGXQGHUVWDQGVWKHQHHGVRISURIHVVLRQDOGHYHORSHUV
%RWKRIXVZHUHVHGXFHGE\6FDODE\LWVFRQFLVHHOHJDQWDQGH[SUHVVLYHV\QWD[DQGE\
WKHEUHDGWKRIWRROVLWSXWDWRXUGLVSRVDO,QWKLVERRNZHVWULYHWRGHPRQVWUDWHZK\
DOOWKHVHTXDOLWLHVPDNH6FDODDFRPSHOOLQJDQGLQGLVSHQVDEOHSURJUDPPLQJODQJXDJH
,I\RXDUHDQH[SHULHQFHGGHYHORSHUZKRZDQWVDIDVWWKRURXJKLQWURGXFWLRQWR6FDOD
WKLVERRNLVIRU\RX<RXPD\EHHYDOXDWLQJ6FDODDVDUHSODFHPHQWIRURUFRPSOHPHQW
WR\RXUFXUUHQWODQJXDJHV0D\EH\RXKDYHDOUHDG\GHFLGHGWRXVH6FDODDQG\RXQHHG
WR OHDUQ LWV IHDWXUHV DQG KRZ WR XVH LW ZHOO (LWKHU ZD\ ZH KRSH WR LOOXPLQDWH WKLV
SRZHUIXOODQJXDJHIRU\RXLQDQDFFHVVLEOHZD\
:HDVVXPHWKDW\RXDUHZHOOYHUVHGLQREMHFWRULHQWHGSURJUDPPLQJEXWZHGRQ¦W
DVVXPHWKDW\RXKDYHSULRUH[SRVXUHWRIXQFWLRQDOSURJUDPPLQJ:HDVVXPHWKDW\RX
DUHH[SHULHQFHGLQRQHRUPRUHRWKHUSURJUDPPLQJODQJXDJHV:HGUDZSDUDOOHOVWR
IHDWXUHVLQ-DYD&5XE\DQGRWKHUODQJXDJHV,I\RXNQRZDQ\RIWKHVHODQJXDJHV
ZH¦OOSRLQWRXWVLPLODUIHDWXUHVLQ6FDODDVZHOODVPDQ\IHDWXUHVWKDWDUHQHZ
:KHWKHU\RXFRPHIURPDQREMHFWRULHQWHGRUIXQFWLRQDOSURJUDPPLQJEDFNJURXQG
\RXZLOOVHHKRZ6FDODHOHJDQWO\FRPELQHVERWKSDUDGLJPVGHPRQVWUDWLQJWKHLUFRP
SOHPHQWDU\QDWXUH%DVHGRQPDQ\H[DPSOHV\RXZLOOXQGHUVWDQGKRZDQGZKHQWR
DSSO\223DQG)3WHFKQLTXHVWRPDQ\GLIIHUHQWGHVLJQSUREOHPV
,QWKHHQGZHKRSHWKDW\RXWRRZLOOEHVHGXFHGE\6FDOD(YHQLI6FDODGRHVQRWHQG
XSEHFRPLQJ\RXUGD\WRGD\ODQJXDJHZHKRSH\RXZLOOJDLQLQVLJKWVWKDW\RXFDQ
DSSO\UHJDUGOHVVRIZKLFKODQJXDJH\RXDUHXVLQJ

Conventions Used in This Book


7KHIROORZLQJW\SRJUDSKLFDOFRQYHQWLRQVDUHXVHGLQWKLVERRN
,WDOLF
,QGLFDWHVQHZWHUPV85/VHPDLODGGUHVVHVILOHQDPHVDQGILOHH[WHQVLRQV0DQ\
LWDOLFL]HGWHUPVDUHGHILQHGLQWKH*ORVVDU\RQSDJH
Constant width
8VHGIRUSURJUDPOLVWLQJVDVZHOODVZLWKLQSDUDJUDSKVWRUHIHUWRSURJUDPHOHPHQWV
VXFKDVYDULDEOHRUIXQFWLRQQDPHVGDWDEDVHVGDWDW\SHVHQYLURQPHQWYDULDEOHV
VWDWHPHQWVDQGNH\ZRUGV
Constant width bold
6KRZVFRPPDQGVRURWKHUWH[WWKDWVKRXOGEHW\SHGOLWHUDOO\E\WKHXVHU

xviii | Preface

Download at WoweBook.Com
Constant width italic
6KRZVWH[WWKDWVKRXOGEHUHSODFHGZLWKXVHUVXSSOLHGYDOXHVRUE\YDOXHVGHWHU
PLQHGE\FRQWH[W

7KLVLFRQVLJQLILHVDWLSVXJJHVWLRQRUJHQHUDOQRWH

7KLVLFRQLQGLFDWHVDZDUQLQJRUFDXWLRQ

Using Code Examples


7KLVERRNLVKHUHWRKHOS\RXJHW\RXUMREGRQH,QJHQHUDO\RXPD\XVHWKHFRGHLQ
WKLVERRNLQ\RXUSURJUDPVDQGGRFXPHQWDWLRQ<RXGRQRWQHHGWRFRQWDFWXVIRU
SHUPLVVLRQXQOHVV\RX¦UHUHSURGXFLQJDVLJQLILFDQWSRUWLRQRIWKHFRGH)RUH[DPSOH
ZULWLQJDSURJUDPWKDWXVHVVHYHUDOFKXQNVRIFRGHIURPWKLVERRNGRHVQRWUHTXLUH
SHUPLVVLRQ6HOOLQJRUGLVWULEXWLQJD&'520RIH[DPSOHVIURP2¦5HLOO\ERRNVGRHV
UHTXLUH SHUPLVVLRQ $QVZHULQJ D TXHVWLRQ E\ FLWLQJ WKLV ERRN DQG TXRWLQJ H[DPSOH
FRGHGRHVQRWUHTXLUHSHUPLVVLRQ,QFRUSRUDWLQJDVLJQLILFDQWDPRXQWRIH[DPSOHFRGH
IURPWKLVERRNLQWR\RXUSURGXFW¦VGRFXPHQWDWLRQGRHVUHTXLUHSHUPLVVLRQ
:HDSSUHFLDWHEXWGRQRWUHTXLUHDWWULEXWLRQ$QDWWULEXWLRQXVXDOO\LQFOXGHVWKHWLWOH
DXWKRUSXEOLVKHUDQG,6%1)RUH[DPSOH£3URJUDPPLQJ6FDODE\'HDQ:DPSOHUDQG
$OH[3D\QH&RS\ULJKW'HDQ:DPSOHUDQG$OH[3D\QH¤
,I\RXIHHO\RXUXVHRIFRGHH[DPSOHVIDOOVRXWVLGHIDLUXVHRUWKHSHUPLVVLRQJLYHQDERYH
IHHOIUHHWRFRQWDFWXVDWSHUPLVVLRQV#RUHLOO\FRP

Getting the Code Examples


<RX FDQ GRZQORDG WKH FRGH H[DPSOHV IURP KWWSH[DPSOHVRUHLOO\FRP
8Q]LSWKHILOHVWRDFRQYHQLHQWORFDWLRQ6HHWKH5($'0(W[WILOHLQ
WKHGLVWULEXWLRQIRULQVWUXFWLRQVRQEXLOGLQJDQGXVLQJWKHH[DPSOHV
6RPHRIWKHH[DPSOHILOHVFDQEHUXQDVVFULSWVXVLQJWKHscalaFRPPDQG2WKHUVPXVW
EHFRPSLOHGLQWRFODVVILOHV6RPHILOHVFRQWDLQGHOLEHUDWHHUURUVDQGZRQ¦WFRPSLOH:H
KDYHDGRSWHGDILOHQDPLQJFRQYHQWLRQWRLQGLFDWHHDFKRIWKHVHFDVHVDOWKRXJKDV\RX
OHDUQ6FDODLWVKRXOGEHFRPHREYLRXVIURPWKHFRQWHQWVRIWKHILOHVLQPRVWFDVHV
VFULSWVFDOD
)LOHVWKDWHQGLQVFULSWVFDODFDQEHUXQRQDFRPPDQGOLQHXVLQJscalaHJscala
foo-script.scala <RX FDQ DOVR VWDUW scala LQ WKH LQWHUSUHWHU PRGH ZKHQ \RX

Preface | xix

Download at WoweBook.Com
GRQ¦WVSHFLI\DVFULSWILOH DQGORDGDQ\VFULSWILOHLQWKHLQWHUSUHWHUXVLQJWKH:load
filenameFRPPDQG
ZRQWFRPSLOHVFDOD
)LOHVWKDWHQGLQZRQWFRPSLOHVFDODFRQWDLQGHOLEHUDWHHUURUVWKDWZLOOFDXVHWKHP
WRIDLOWRFRPSLOH:HXVHWKLVQDPLQJFRQYHQWLRQDORQJZLWKRQHRUPRUHHP
EHGGHGFRPPHQWVDERXWWKHHUURUVVRLWZLOOEHFOHDUWKDWWKH\DUHLQYDOLG$OVR
WKHVHILOHVDUHVNLSSHGE\WKHEXLOGSURFHVVIRUWKHH[DPSOHV
VDNHVFDOD
)LOHVQDPHGVDNHVFDODDUHXVHGE\RXUEXLOGWRROFDOOHG sake7KH5($'0(W[W
ILOHGHVFULEHVWKLVWRRO
VFDOD
$OORWKHU6FDODILOHVPXVWEHFRPSLOHGXVLQJ scalac,QWKHGLVWULEXWLRQWKH\DUH
XVHGHLWKHUE\RWKHUFRPSLOHGRUVFULSWILOHVVXFKDVWHVWVQRWDOORIZKLFKDUHOLVWHG
LQWKLVERRN

Safari® Books Online


6DIDUL%RRNV2QOLQHLVDQRQGHPDQGGLJLWDOOLEUDU\WKDWOHWV\RXHDVLO\
VHDUFKRYHUWHFKQRORJ\DQGFUHDWLYHUHIHUHQFHERRNVDQGYLGHRVWR
ILQGWKHDQVZHUV\RXQHHGTXLFNO\
:LWKDVXEVFULSWLRQ\RXFDQUHDGDQ\SDJHDQGZDWFKDQ\YLGHRIURPRXUOLEUDU\RQOLQH
5HDGERRNVRQ\RXUFHOOSKRQHDQGPRELOHGHYLFHV$FFHVVQHZWLWOHVEHIRUHWKH\DUH
DYDLODEOHIRUSULQWDQGJHWH[FOXVLYHDFFHVVWRPDQXVFULSWVLQGHYHORSPHQWDQGSRVW
IHHGEDFNIRUWKHDXWKRUV&RS\DQGSDVWHFRGHVDPSOHVRUJDQL]H\RXUIDYRULWHVGRZQ
ORDGFKDSWHUVERRNPDUNNH\VHFWLRQVFUHDWHQRWHVSULQWRXWSDJHVDQGEHQHILWIURP
WRQVRIRWKHUWLPHVDYLQJIHDWXUHV
2¦5HLOO\0HGLDKDVXSORDGHGWKLVERRNWRWKH6DIDUL%RRNV2QOLQHVHUYLFH7RKDYHIXOO
GLJLWDODFFHVVWRWKLVERRNDQGRWKHUVRQVLPLODUWRSLFVIURP2¦5HLOO\DQGRWKHUSXE
OLVKHUVVLJQXSIRUIUHHDWKWWSP\VDIDULERRNVRQOLQHFRP

How to Contact Us
3OHDVHDGGUHVVFRPPHQWVDQGTXHVWLRQVFRQFHUQLQJWKLVERRNWRWKHSXEOLVKHU
2¦5HLOO\0HGLD,QF
*UDYHQVWHLQ+LJKZD\1RUWK
6HEDVWRSRO&$
 LQWKH8QLWHG6WDWHVRU&DQDGD

xx | Preface

Download at WoweBook.Com
 LQWHUQDWLRQDORUORFDO
 ID[
:HKDYHDZHESDJHIRUWKLVERRNZKHUHZHOLVWHUUDWDH[DPSOHVDQGDQ\DGGLWLRQDO
LQIRUPDWLRQ<RXFDQDFFHVVWKLVSDJHDW
KWWSRUHLOO\FRPFDWDORJ
7RFRPPHQWRUDVNWHFKQLFDOTXHVWLRQVDERXWWKLVERRNVHQGHPDLOWR
ERRNTXHVWLRQV#RUHLOO\FRP
)RU PRUH LQIRUPDWLRQ DERXW RXU ERRNV FRQIHUHQFHV 5HVRXUFH &HQWHUV DQG WKH
2¦5HLOO\1HWZRUNVHHRXUZHEVLWHDW
KWWSRUHLOO\FRP

Acknowledgments
$VZHGHYHORSHGWKLVERRNPDQ\SHRSOHUHDGHDUO\GUDIWVDQGVXJJHVWHGQXPHURXV
LPSURYHPHQWVWRWKHWH[WIRUZKLFKZHDUHHWHUQDOO\JUDWHIXO:HDUHHVSHFLDOO\JUDWHIXO
WR6WHYH-HQVHQ5DPQLYDV/DGGDG0DUFHO0ROLQD%LOO9HQQHUVDQG-RQDV%RQpUIRU
WKHLUH[WHQVLYHIHHGEDFN
0XFKRIWKHIHHGEDFNZHUHFHLYHGFDPHWKURXJKWKH6DIDUL5RXJK&XWVUHOHDVHVDQG
WKH RQOLQH HGLWLRQ DYDLODEOH DW KWWSSURJUDPPLQJVFDODFRP :H DUH JUDWHIXO IRU WKH
IHHGEDFNSURYLGHGE\ LQQRSDUWLFXODURUGHU ,XOLDQ'UDJRV1LNRODM/LQGEHUJ0DWW
+HOOLJH'DYLG9\GUD5LFN\&ODUNVRQ$OH[&UXLVH-RVK&URQHPH\HU7\OHU-HQQLQJV
$ODQ6XS\QXN7RQ\+LOOHUVRQ5RJHU9DXJKQ$UEL6RRND]LDQ%UXFH/HLGO'DQLHO
6REUDO(GHU$QGUHV$YLOD0DUHN.XELFD+HQULN+XWWXQHQ%KDVNDU0DGGDOD*HG
%\UQH'HUHN0DKDU*HRIIUH\:LVHPDQ3HWHU5DZVWKRUQH*HRIIUH\:LVHPDQ-RH
%RZEHHU $OH[DQGHU %DWWLVWL 5RE 'LFNHQV 7LP 0DF(DFKHUQ -DVRQ +DUULV 6WHYHQ
*UDG\%RE)ROOHN$ULHO2UWL]3DUWK0DOZDQNDU5HLG+RFKVWHGOHU-DVRQ=DXJJ-RQ
+DQVRQ 0DULR *OHLFKPDQQ 'DYLG *DWHV =HI +HPHO 0LFKDHO <HH 0DULXV .UHLV
0DUWLQ6VVNUDXW-DYLHU9HJDV7RELDV+DXWK)UDQFHVFR%RFKLFFKLR6WHSKHQ'XQFDQ
-U 3DWULN 'XGLWV -DQ 1LHKXVPDQQ %LOO %XUGLFN 'DYLG +ROEURRN 6KDORP 'HLWFK
-HVSHU 1RUGHQEHUJ (VD /DLQH *OHE )UDQN 6LPRQ $QGHUVVRQ 3DWULN 'XGLWV &KULV
/HZLV-XOLDQ+RZDUWK'LUN.X]HPF]DN+HQUL*HUULWV-RKQ+HLQW]6WXDUW5RHEXFN
DQG-XQJKR.LP0DQ\RWKHUUHDGHUVIRUZKRPZHRQO\KDYHXVHUQDPHVDOVRSURYLGHG
IHHGEDFN:HZLVKWRWKDQN=DFN-RVK*HZLOOLJHUVDEFRDWHVEUDGWHWRSMFMPNOHLQW
GDQGR\RQ$UHNUXHDFDQJLDQRYNHOPDQEU\DQO-HIIPED[WHUSMEN[HQKLSHU
WUDFNHUFWUDQ5DP5FRG\1RODQ-RVKXD$MD\-RHDQGDQRQ\PRXVFRQWULEXWRUV
:HDSRORJL]HLIZHKDYHRYHUORRNHGDQ\RQH
2XUHGLWRU0LNH/RXNLGHVNQRZVKRZWRSXVKDQGSURGJHQWOH+H¦VEHHQDJUHDWKHOS
WKURXJKRXW WKLV FUD]\ SURFHVV 0DQ\ RWKHU SHRSOH DW 2¦5HLOO\ ZHUH DOZD\V WKHUH WR
DQVZHURXUTXHVWLRQVDQGKHOSXVPRYHIRUZDUG

Preface | xxi

Download at WoweBook.Com
:HWKDQN-RQDV%RQpUIRUZULWLQJWKH)RUHZRUGIRUWKHERRN-RQDVLVDORQJWLPHIULHQG
DQGFROODERUDWRUIURPWKHDVSHFWRULHQWHGSURJUDPPLQJ $23 FRPPXQLW\)RU\HDUV
KHKDVGRQHSLRQHHULQJZRUNLQWKH-DYDFRPPXQLW\1RZKHLVDSSO\LQJKLVHQHUJLHV
WRSURPRWLQJ6FDODDQGJURZLQJWKDWFRPPXQLW\
%LOO9HQQHUVJUDFLRXVO\SURYLGHGWKHTXRWHRQWKHEDFNFRYHU7KHILUVWSXEOLVKHGERRN
RQ6FDOD3URJUDPPLQJLQ6FDOD $UWLPD WKDWKHFRZURWHZLWK0DUWLQ2GHUVN\DQG
/H[6SRRQLVLQGLVSHQVDEOHIRUWKH6FDODGHYHORSHU%LOOKDVDOVRFUHDWHGWKHZRQGHUIXO
6FDOD7HVWOLEUDU\
:HKDYHOHDUQHGDORWIURPIHOORZGHYHORSHUVDURXQGWKHZRUOG%HVLGHV-RQDVDQG%LOO
'HEDVLVK *KRVK -DPHV ,U\ 'DQLHO 6SLHZDN 'DYLG 3ROODFN 3DXO 6QLYHO\ 2OD %LQL
'DQLHO6REUDO-RVK6XHUHWK5REH\3RLQWHU1DWKDQ+DPEOHQ-RUJH2UWL]DQGRWKHUV
KDYHLOOXPLQDWHGGDUNFRUQHUVZLWKWKHLUEORJHQWULHVIRUXPGLVFXVVLRQVDQGSHUVRQDO
FRQYHUVDWLRQV
'HDQWKDQNVKLVFROOHDJXHVDW2EMHFW0HQWRUDQGVHYHUDOGHYHORSHUVDWFOLHQWVLWHVIRU
PDQ\VWLPXODWLQJGLVFXVVLRQVRQODQJXDJHVVRIWZDUHGHVLJQDQGWKHSUDJPDWLFLVVXHV
IDFLQJ GHYHORSHUV LQ LQGXVWU\ 7KH PHPEHUV RI WKH &KLFDJR $UHD 6FDOD (QWKXVLDVWV
&$6( JURXSKDYHDOVREHHQDVRXUFHRIYDOXDEOHIHHGEDFNDQGLQVSLUDWLRQ
$OH[ WKDQNV KLV FROOHDJXHV DW 7ZLWWHU IRU WKHLU HQFRXUDJHPHQW DQG VXSHUE ZRUN LQ
GHPRQVWUDWLQJ6FDOD¦VHIIHFWLYHQHVVDVDODQJXDJH+HDOVRWKDQNVWKH%D\$UHD6FDOD
(QWKXVLDVWV %$6( IRUWKHLUPRWLYDWLRQDQGFRPPXQLW\
0RVWRIDOOZHWKDQN0DUWLQ2GHUVN\DQGKLVWHDPIRUFUHDWLQJ6FDOD

xxii | Preface

Download at WoweBook.Com
CHAPTER 1
Zero to Sixty: Introducing Scala

Why Scala?
7RGD\¦VHQWHUSULVHDQG,QWHUQHWDSSOLFDWLRQVPXVWEDODQFHDQXPEHURIFRQFHUQV7KH\
PXVWEHLPSOHPHQWHGTXLFNO\DQGUHOLDEO\1HZIHDWXUHVPXVWEHDGGHGLQVKRUWLQ
FUHPHQWDOF\FOHV%H\RQGVLPSO\SURYLGLQJEXVLQHVVORJLFDSSOLFDWLRQVPXVWVXSSRUW
VHFXUHDFFHVVSHUVLVWHQFHRIGDWDWUDQVDFWLRQDOEHKDYLRUDQGRWKHUDGYDQFHGIHDWXUHV
$SSOLFDWLRQV PXVW EH KLJKO\ DYDLODEOH DQG VFDODEOH UHTXLULQJ GHVLJQV WKDW VXSSRUW
FRQFXUUHQF\DQGGLVWULEXWLRQ$SSOLFDWLRQVDUHQHWZRUNHGDQGSURYLGHLQWHUIDFHVIRU
ERWKSHRSOHDQGRWKHUDSSOLFDWLRQVWRXVH
7RPHHWWKHVHFKDOOHQJHVPDQ\GHYHORSHUVDUHORRNLQJIRUQHZODQJXDJHVDQGWRROV
9HQHUDEOHVWDQGE\VOLNH-DYD&DQG&DUHQRORQJHURSWLPDOIRUGHYHORSLQJWKH
QH[WJHQHUDWLRQRIDSSOLFDWLRQV

If You Are a Java Programmer…


-DYDZDVRIILFLDOO\LQWURGXFHGE\6XQ0LFURV\VWHPVLQ0D\RIDWWKHDGYHQWRI
ZLGHVSUHDGLQWHUHVWLQWKH,QWHUQHW-DYDZDVLPPHGLDWHO\KDLOHGDVDQLGHDOODQJXDJH
IRU ZULWLQJ EURZVHUEDVHG DSSOHWV ZKHUH D VHFXUH SRUWDEOH DQG GHYHORSHUIULHQGO\
DSSOLFDWLRQ ODQJXDJH ZDV QHHGHG 7KH UHLJQLQJ ODQJXDJH RI WKH GD\ & ZDV QRW
VXLWDEOHIRUWKLVGRPDLQ
7RGD\-DYDLVPRUHRIWHQXVHGIRUVHUYHUVLGHDSSOLFDWLRQV,WLVRQHRIWKHPRVWSRSXODU
ODQJXDJHVLQXVHIRUWKHGHYHORSPHQWRIZHEDQGHQWHUSULVHDSSOLFDWLRQV
+RZHYHU-DYDZDVDFKLOGRILWVWLPH1RZLWVKRZVLWVDJH,Q-DYDSURYLGHGD
V\QWD[VLPLODUHQRXJKWR&WRHQWLFH&GHYHORSHUVZKLOHDYRLGLQJPDQ\RIWKDW
ODQJXDJH¦VGHILFLHQFLHVDQG£VKDUSHGJHV¤-DYDDGRSWHGWKHPRVWXVHIXOLGHDVIRUWKH
GHYHORSPHQWSUREOHPVRILWVHUDVXFKDVREMHFWRULHQWHGSURJUDPPLQJ 223 ZKLOH
GLVFDUGLQJPRUHWURXEOHVRPHWHFKQLTXHVVXFKDVPDQXDOPHPRU\PDQDJHPHQW7KHVH
GHVLJQFKRLFHVVWUXFNDQH[FHOOHQWEDODQFHWKDWPLQLPL]HGFRPSOH[LW\DQGPD[LPL]HG
GHYHORSHUSURGXFWLYLW\ZKLOHWUDGLQJRIISHUIRUPDQFHFRPSDUHGWRQDWLYHO\FRPSLOHG

Download at WoweBook.Com
FRGH :KLOH -DYD KDV HYROYHG VLQFH LWV ELUWK PDQ\ SHRSOH EHOLHYH LW KDV JURZQ WRR
FRPSOH[ZLWKRXWDGHTXDWHO\DGGUHVVLQJVRPHQHZHUGHYHORSPHQWFKDOOHQJHV
'HYHORSHUVZDQWODQJXDJHVWKDWDUHPRUHVXFFLQFWDQGIOH[LEOHWRLPSURYHWKHLUSUR
GXFWLYLW\7KLVLVRQHUHDVRQZK\VRFDOOHGVFULSWLQJODQJXDJHVOLNH5XE\DQG3\WKRQ
KDYHEHFRPHPRUHSRSXODUUHFHQWO\
7KHQHYHUHQGLQJQHHGWRVFDOHLVGULYLQJDUFKLWHFWXUHVWRZDUGSHUYDVLYHFRQFXUUHQF\
+RZHYHU-DYD¦VFRQFXUUHQF\PRGHOZKLFKLVEDVHGRQV\QFKURQL]HGDFFHVVWRVKDUHG
PXWDEOHVWDWHUHVXOWVLQFRPSOH[DQGHUURUSURQHSURJUDPV
:KLOHWKH-DYDODQJXDJHLVVKRZLQJLWVDJHWKH-DYD9LUWXDO0DFKLQH -90 RQZKLFK
LWUXQVFRQWLQXHVWRVKLQH7KHRSWLPL]DWLRQVSHUIRUPHGE\WRGD\¦V-90DUHH[WUDRU
GLQDU\DOORZLQJE\WHFRGHWRRXWSHUIRUPQDWLYHO\FRPSLOHGFRGHLQPDQ\FDVHV7RGD\
PDQ\GHYHORSHUVEHOLHYHWKDWXVLQJWKH-90ZLWKQHZODQJXDJHVLVWKHSDWKIRUZDUG
6XQLVHPEUDFLQJWKLVWUHQGE\HPSOR\LQJPDQ\RIWKHOHDGGHYHORSHUVRI-5XE\DQG
-\WKRQZKLFKDUH-90SRUWVRI5XE\DQG3\WKRQUHVSHFWLYHO\
7KHDSSHDORI6FDODIRUWKH-DYDGHYHORSHULVWKDWLWJLYHV\RXDQHZHUPRUHPRGHUQ
ODQJXDJH ZKLOH OHYHUDJLQJ WKH -90¦V DPD]LQJ SHUIRUPDQFH DQG WKH ZHDOWK RI -DYD
OLEUDULHVWKDWKDYHEHHQGHYHORSHGIRURYHUDGHFDGH

If You Are a Ruby, Python, etc. Programmer…


'\QDPLFDOO\ W\SHG ODQJXDJHV OLNH 5XE\ 3\WKRQ *URRY\ -DYD6FULSW DQG 6PDOOWDON
RIIHUYHU\KLJKSURGXFWLYLW\GXHWRWKHLUIOH[LELOLW\SRZHUIXOPHWDSURJUDPPLQJDQG
HOHJDQFH

Statically Typed Versus Dynamically Typed Languages


2QHRIWKHIXQGDPHQWDOODQJXDJHGHVLJQFKRLFHVLVVWDWLFYHUVXVG\QDPLFW\SLQJ
7KHZRUG£W\SLQJ¤LVXVHGLQPDQ\FRQWH[WVLQVRIWZDUH7KHIROORZLQJLVD£SODXVLEOH¤
GHILQLWLRQWKDWLVXVHIXOIRURXUSXUSRVHV
$W\SHV\VWHPLVDWUDFWDEOHV\QWDFWLFPHWKRGIRUSUHVHUYLQJWKHDEVHQFHRIFHUWDLQ
SURJUDPEHKDYLRUVE\FODVVLI\LQJSKUDVHVDFFRUGLQJWRWKHNLQGVRIYDOXHVWKH\
FRPSXWH
¢%HQMDPLQ&3LHUFH7\SHVDQG3URJUDPPLQJ/DQJXDJHV 0,73UHVV
1RWHWKHHPSKDVLVRQKRZDW\SHV\VWHPDOORZVUHDVRQLQJDERXWZKDWDV\VWHPH[
FOXGHVIURPKDSSHQLQJ7KDW¦VJHQHUDOO\HDVLHUWKDQWU\LQJWRGHWHUPLQHWKHVHWRIDOO
DOORZHGSRVVLELOLWLHV$W\SHV\VWHPLVXVHGWRFDWFKYDULRXVHUURUVOLNHXQVXSSRUWHG
RSHUDWLRQVRQSDUWLFXODUGDWDVWUXFWXUHVDWWHPSWLQJWRFRPELQHGDWDLQDQXQGHILQHG
ZD\ HJWU\LQJWRDGGDQLQWHJHUWRDVWULQJ EUHDNLQJDEVWUDFWLRQVHWF
,QIRUPDOO\LQVWDWLFW\SLQJDYDULDEOHLVERXQGWRDSDUWLFXODUW\SHIRULWVOLIHWLPH,WV
W\SHFDQ¦WEHFKDQJHGDQGLWFDQRQO\UHIHUHQFHW\SHFRPSDWLEOHLQVWDQFHV7KDWLVLID
YDULDEOHUHIHUVWRDYDOXHRIW\SH A\RXFDQ¦WDVVLJQDYDOXHRIDGLIIHUHQWW\SH BWRLW
XQOHVVBLVDVXEW\SHRIAIRUVRPHUHDVRQDEOHGHILQLWLRQRI£VXEW\SH¤

2 | Chapter 1:—Zero to Sixty: Introducing Scala

Download at WoweBook.Com
,QG\QDPLFW\SLQJWKHW\SHLVERXQGWRWKHYDOXHQRWWKHYDULDEOH6RDYDULDEOHPLJKW
UHIHUWRDYDOXHRIW\SHAWKHQEHUHDVVLJQHGODWHUWRDYDOXHRIDQXQUHODWHGW\SHX
7KHWHUPG\QDPLFDOO\W\SHGLVXVHGEHFDXVHWKHW\SHRIDYDULDEOHLVHYDOXDWHGZKHQLW
LVXVHGGXULQJUXQWLPHZKLOHLQDVWDWLFDOO\W\SHGODQJXDJHWKHW\SHLVHYDOXDWHGDWSDUVH
WLPH
7KLVPD\VHHPOLNHDVPDOOGLVWLQFWLRQEXWLWKDVDSHUYDVLYHLPSDFWRQWKHSKLORVRSK\
GHVLJQDQGLPSOHPHQWDWLRQRIDODQJXDJH:H¦OOH[SORUHVRPHRIWKHVHLPSOLFDWLRQVDV
ZHJRWKURXJKWKHERRN
6FDODDQG-DYDDUHVWDWLFDOO\W\SHGODQJXDJHVZKHUHDV5XE\3\WKRQ*URRY\-DYD
6FULSWDQG6PDOOWDONDUHG\QDPLFDOO\W\SHGODQJXDJHV
)RUVLPSOLFLW\ZHZLOORIWHQXVHWKHWHUPV VWDWLFODQJXDJHDQGG\QDPLFODQJXDJHDV
VKRUWKDQGVIRUVWDWLFDOO\W\SHGODQJXDJHDQGG\QDPLFDOO\W\SHGODQJXDJHUHVSHFWLYHO\
$QRUWKRJRQDOGHVLJQFRQVLGHUDWLRQLVVWURQJYHUVXVZHDNW\SLQJ,QVWURQJW\SLQJHYHU\
YDULDEOH IRUVWDWLFW\SLQJ RUYDOXH IRUG\QDPLFW\SLQJ PXVWKDYHDQXQDPELJXRXV
W\SH,QZHDNW\SLQJDVSHFLILFW\SHLVQRWUHTXLUHG:KLOHPRVWODQJXDJHVDOORZVRPH
PL[WXUHRIVWURQJYHUVXVZHDNW\SLQJ6FDOD-DYDDQG5XE\DUHSUHGRPLQDQWO\VWURQJO\
W\SHGODQJXDJHV6RPHODQJXDJHVOLNH&DQG3HUODUHPRUHZHDNO\W\SHG

'HVSLWHWKHLUSURGXFWLYLW\DGYDQWDJHVG\QDPLFODQJXDJHVPD\QRWEHWKHEHVWFKRLFHV
IRUDOODSSOLFDWLRQVSDUWLFXODUO\IRUYHU\ODUJHFRGHEDVHVDQGKLJKSHUIRUPDQFHDSSOL
FDWLRQV7KHUHLVDORQJVWDQGLQJVSLULWHGGHEDWHLQWKHSURJUDPPLQJFRPPXQLW\DERXW
WKHUHODWLYHPHULWVRIG\QDPLFYHUVXVVWDWLFW\SLQJ0DQ\RIWKHSRLQWVRIFRPSDULVRQ
DUHVRPHZKDWVXEMHFWLYH:HZRQ¦WJRWKURXJKDOOWKHDUJXPHQWVKHUHEXWZHZLOORIIHU
DIHZWKRXJKWVIRUFRQVLGHUDWLRQ
2SWLPL]LQJWKHSHUIRUPDQFHRIDG\QDPLFODQJXDJHLVPRUHFKDOOHQJLQJWKDQIRUDVWDWLF
ODQJXDJH,QDVWDWLFODQJXDJHRSWLPL]HUVFDQH[SORLWWKHW\SHLQIRUPDWLRQWRPDNH
GHFLVLRQV ,Q D G\QDPLF ODQJXDJH IHZHU VXFK FOXHV DUH DYDLODEOH IRU WKH RSWLPL]HU
PDNLQJRSWLPL]DWLRQFKRLFHVKDUGHU:KLOHUHFHQWDGYDQFHPHQWVLQRSWLPL]DWLRQVIRU
G\QDPLFODQJXDJHVDUHSURPLVLQJWKH\ODJEHKLQGWKHVWDWHRIWKHDUWIRUVWDWLFODQ
JXDJHV6RLI\RXUHTXLUHYHU\KLJKSHUIRUPDQFHVWDWLFODQJXDJHVDUHSUREDEO\DVDIHU
FKRLFH
6WDWLF ODQJXDJHV FDQ DOVR EHQHILW WKH GHYHORSPHQW SURFHVV ,QWHJUDWHG GHYHORSPHQW
HQYLURQPHQW ,'(  IHDWXUHV OLNH DXWRFRPSOHWLRQ VRPHWLPHV FDOOHG FRGH VHQVH  DUH
HDVLHUWRLPSOHPHQWIRUVWDWLFODQJXDJHVDJDLQEHFDXVHRIWKHH[WUDW\SHLQIRUPDWLRQ
DYDLODEOH 7KH PRUH H[SOLFLW W\SH LQIRUPDWLRQ LQ VWDWLF FRGH SURPRWHV EHWWHU £VHOI
GRFXPHQWDWLRQ¤ZKLFKFDQEHLPSRUWDQWIRUFRPPXQLFDWLQJLQWHQWDPRQJGHYHORSHUV
HVSHFLDOO\DVDSURMHFWJURZV
:KHQXVLQJDVWDWLFODQJXDJH\RXKDYHWRWKLQNDERXWDSSURSULDWHW\SHFKRLFHVPRUH
RIWHQZKLFKIRUFHV\RXWRZHLJKGHVLJQFKRLFHVPRUHFDUHIXOO\:KLOHWKLVPD\VORZ
GRZQGDLO\GHVLJQGHFLVLRQVWKLQNLQJWKURXJKWKHW\SHVLQWKHDSSOLFDWLRQFDQUHVXOW
LQDPRUHFRKHUHQWGHVLJQRYHUWLPH

Why Scala? | 3

Download at WoweBook.Com
$QRWKHUVPDOOEHQHILWRIVWDWLFODQJXDJHVLVWKHH[WUDFKHFNLQJWKHFRPSLOHUSHUIRUPV
:HWKLQNWKLVDGYDQWDJHLVRIWHQRYHUVROGDVW\SHPLVPDWFKHUURUVDUHDVPDOOIUDFWLRQ
RIWKHUXQWLPHHUURUV\RXW\SLFDOO\VHH7KHFRPSLOHUFDQ¦WILQGORJLFHUURUVZKLFKDUH
IDUPRUHVLJQLILFDQW2QO\DFRPSUHKHQVLYHDXWRPDWHGWHVWVXLWHFDQILQGORJLFHUURUV
)RUG\QDPLFDOO\W\SHGODQJXDJHVWKHWHVWVPXVWFRYHUSRVVLEOHW\SHHUURUVWRR,I\RX
DUHFRPLQJIURPDG\QDPLFDOO\W\SHGODQJXDJH\RXPD\ILQGWKDW\RXUWHVWVXLWHVDUH
DOLWWOHVPDOOHUDVDUHVXOWEXWQRWWKDWPXFKVPDOOHU
0DQ\GHYHORSHUVZKRILQGVWDWLFODQJXDJHVWRRYHUERVHRIWHQEODPHVWDWLFW\SLQJIRU
WKHYHUERVLW\ZKHQWKHUHDOSUREOHPLVDODFNRIW\SHLQIHUHQFH,QW\SHLQIHUHQFHWKH
FRPSLOHULQIHUVWKHW\SHVRIYDOXHVEDVHGRQWKHFRQWH[W)RUH[DPSOHWKHFRPSLOHUZLOO
UHFRJQL]H WKDW x = 1 + 3 PHDQV WKDW x PXVW EH DQ LQWHJHU 7\SH LQIHUHQFH UHGXFHV
YHUERVLW\ VLJQLILFDQWO\ PDNLQJ WKH FRGH IHHO PRUH OLNH FRGH ZULWWHQ LQ D G\QDPLF
ODQJXDJH
:HKDYHZRUNHGZLWKERWKVWDWLFDQGG\QDPLFODQJXDJHVDWYDULRXVWLPHV:HILQG
ERWKNLQGVRIODQJXDJHVFRPSHOOLQJIRUGLIIHUHQWUHDVRQV:HEHOLHYHWKHPRGHUQVRIW
ZDUHGHYHORSHUPXVWPDVWHUDUDQJHRIODQJXDJHVDQGWRROV6RPHWLPHVDG\QDPLF
ODQJXDJHZLOOEHWKHULJKWWRROIRUWKHMRE$WRWKHUWLPHVDVWDWLFODQJXDJHOLNH6FDODLV
MXVWZKDW\RXQHHG

Introducing Scala
6FDOD LV D ODQJXDJH WKDW DGGUHVVHV WKH PDMRU QHHGV RI WKH PRGHUQ GHYHORSHU ,W LV D
VWDWLFDOO\W\SHGPL[HGSDUDGLJP-90ODQJXDJHZLWKDVXFFLQFWHOHJDQWDQGIOH[LEOH
V\QWD[DVRSKLVWLFDWHGW\SHV\VWHPDQGLGLRPVWKDWSURPRWHVFDODELOLW\IURPVPDOO
LQWHUSUHWHGVFULSWVWRODUJHVRSKLVWLFDWHGDSSOLFDWLRQV7KDW¦VDPRXWKIXOVROHW¦VORRN
DWHDFKRIWKRVHLGHDVLQPRUHGHWDLO
6WDWLFDOO\W\SHG
$VZHGHVFULEHGLQWKHSUHYLRXVVHFWLRQDVWDWLFDOO\W\SHGODQJXDJHELQGVWKHW\SH
WRDYDULDEOHIRUWKHOLIHWLPHRIWKDWYDULDEOH,QFRQWUDVWG\QDPLFDOO\W\SHGODQ
JXDJHVELQGWKHW\SHWRWKHDFWXDOYDOXHUHIHUHQFHGE\DYDULDEOHPHDQLQJWKDWWKH
W\SHRIDYDULDEOHFDQFKDQJHDORQJZLWKWKHYDOXHLWUHIHUHQFHV
2IWKHVHWRIQHZHU-90ODQJXDJHV6FDODLVRQHRIWKHIHZWKDWLVVWDWLFDOO\W\SHG
DQGLWLVWKHEHVWNQRZQDPRQJWKHP
0L[HGSDUDGLJP¢REMHFWRULHQWHGSURJUDPPLQJ
6FDOD IXOO\ VXSSRUWV REMHFWRULHQWHG SURJUDPPLQJ 223  6FDOD LPSURYHV XSRQ
-DYD¦VVXSSRUWIRU223ZLWKWKHDGGLWLRQRIWUDLWVDFOHDQZD\RILPSOHPHQWLQJ
FODVVHVXVLQJPL[LQFRPSRVLWLRQ6FDOD¦VWUDLWVZRUNPXFKOLNH5XE\¦VPRGXOHV,I
\RX¦UH D -DYD SURJUDPPHU WKLQN RI WUDLWV DV XQLI\LQJ LQWHUIDFHV ZLWK WKHLU
LPSOHPHQWDWLRQV
,Q6FDODHYHU\WKLQJLVUHDOO\DQREMHFW6FDODGRHVQRWKDYHSULPLWLYHW\SHVOLNH
-DYD ,QVWHDG DOO QXPHULF W\SHV DUH WUXH REMHFWV +RZHYHU IRU RSWLPDO

4 | Chapter 1:—Zero to Sixty: Introducing Scala

Download at WoweBook.Com
SHUIRUPDQFH6FDODXVHVWKHXQGHUO\LQJSULPLWLYHVW\SHVRIWKHUXQWLPHZKHQHYHU
SRVVLEOH$OVR6FDODGRHVQRWVXSSRUW£VWDWLF¤RUFODVVOHYHOPHPEHUVRIW\SHVVLQFH
WKH\DUHQRWDVVRFLDWHGZLWKDQDFWXDOLQVWDQFH,QVWHDG6FDODVXSSRUWVDVLQJOHWRQ
REMHFW FRQVWUXFW WR VXSSRUW WKRVH FDVHV ZKHUH H[DFWO\ RQH LQVWDQFH RI D W\SH LV
QHHGHG
0L[HGSDUDGLJP¢IXQFWLRQDOSURJUDPPLQJ
6FDODIXOO\VXSSRUWVIXQFWLRQDOSURJUDPPLQJ )3 )3LVDSURJUDPPLQJSDUDGLJP
WKDWLVROGHUWKDQ223EXWLWKDVEHHQVKHOWHUHGLQWKHLYRU\WRZHUVRIDFDGHPLD
XQWLOUHFHQWO\,QWHUHVWLQ)3LVLQFUHDVLQJEHFDXVHRIWKHZD\VLWVLPSOLILHVFHUWDLQ
GHVLJQSUREOHPVHVSHFLDOO\FRQFXUUHQF\£3XUH¤IXQFWLRQDOODQJXDJHVGRQ¦WDOORZ
IRUDQ\PXWDEOHVWDWHWKHUHE\DYRLGLQJWKHQHHGIRUV\QFKURQL]DWLRQRQVKDUHG
DFFHVVWRPXWDEOHVWDWH,QVWHDGSURJUDPVZULWWHQLQSXUHIXQFWLRQDOODQJXDJHV
FRPPXQLFDWHE\SDVVLQJPHVVDJHVEHWZHHQFRQFXUUHQWDXWRQRPRXVSURFHVVHV
6FDODVXSSRUWVWKLVPRGHOZLWKLWV$FWRUVOLEUDU\EXWLWDOORZVIRUERWKPXWDEOH
DQGLPPXWDEOHYDULDEOHV
)XQFWLRQVDUH£ILUVWFODVV¤FLWL]HQVLQ)3PHDQLQJWKH\FDQEHDVVLJQHGWRYDULDEOHV
SDVVHGWRRWKHUIXQFWLRQVHWFMXVWOLNHRWKHUYDOXHV7KLVIHDWXUHSURPRWHVFRP
SRVLWLRQRIDGYDQFHGEHKDYLRUXVLQJSULPLWLYHRSHUDWLRQV%HFDXVH6FDODDGKHUHV
WRWKHGLFWXPWKDWHYHU\WKLQJLVDQREMHFWIXQFWLRQVDUHWKHPVHOYHVREMHFWVLQ6FDOD
6FDODDOVRRIIHUVFORVXUHVDIHDWXUHWKDWG\QDPLFODQJXDJHVOLNH3\WKRQDQG5XE\
KDYHDGRSWHGIURPWKHIXQFWLRQDOSURJUDPPLQJZRUOGDQGRQHVDGO\DEVHQWIURP
UHFHQWYHUVLRQVRI-DYD&ORVXUHVDUHIXQFWLRQVWKDWUHIHUHQFHYDULDEOHVIURPWKH
VFRSHHQFORVLQJWKHIXQFWLRQGHILQLWLRQ7KDWLVWKHYDULDEOHVDUHQ¦WSDVVHGLQDV
DUJXPHQWV RU GHILQHG DV ORFDO YDULDEOHV ZLWKLQ WKH IXQFWLRQ $ FORVXUH £FORVHV
DURXQG¤WKHVHUHIHUHQFHVVRWKHIXQFWLRQLQYRFDWLRQFDQVDIHO\UHIHUWRWKHYDULDEOHV
HYHQ ZKHQ WKH YDULDEOHV KDYH JRQH RXW RI VFRSH &ORVXUHV DUH VXFK D SRZHUIXO
DEVWUDFWLRQ WKDW REMHFW V\VWHPV DQG IXQGDPHQWDO FRQWURO VWUXFWXUHV DUH RIWHQ
LPSOHPHQWHGXVLQJWKHP
$-90DQG1(7ODQJXDJH
:KLOH6FDODLVSULPDULO\NQRZQDVD-90ODQJXDJHPHDQLQJWKDW6FDODJHQHUDWHV
-90E\WHFRGHD1(7YHUVLRQRI6FDODWKDWJHQHUDWHV&RPPRQ/DQJXDJH5XQWLPH
&/5  E\WH FRGH LV DOVR XQGHU GHYHORSPHQW :KHQ ZH UHIHU WR WKH XQGHUO\LQJ
£UXQWLPH¤ZHZLOOXVXDOO\GLVFXVVWKH-90EXWPRVWRIZKDWZHZLOOVD\DSSOLHV
HTXDOO\WRERWKUXQWLPHV:KHQZHGLVFXVV-90VSHFLILFGHWDLOVWKH\JHQHUDOL]H
WRWKH1(7YHUVLRQH[FHSWZKHUHQRWHG
7KH6FDODFRPSLOHUXVHVFOHYHUWHFKQLTXHVWRPDS6FDODH[WHQVLRQVWRYDOLGE\WH
FRGHLGLRPV)URP6FDOD\RXFDQHDVLO\LQYRNHE\WHFRGHWKDWRULJLQDWHGDV-DYD
VRXUFH IRUWKH-90 RU&VRXUFH IRU1(7 &RQYHUVHO\\RXFDQLQYRNH6FDOD
FRGHIURP-DYD&HWF5XQQLQJRQWKH-90DQG&/5DOORZVWKH6FDODGHYHORSHU
WROHYHUDJHDYDLODEOHOLEUDULHVDQGWRLQWHURSHUDWHZLWKRWKHUODQJXDJHVKRVWHGRQ
WKRVHUXQWLPHV

Why Scala? | 5

Download at WoweBook.Com
$VXFFLQFWHOHJDQWDQGIOH[LEOHV\QWD[
-DYDV\QWD[FDQEHYHUERVH6FDODXVHVDQXPEHURIWHFKQLTXHVWRPLQLPL]HXQ
QHFHVVDU\V\QWD[PDNLQJ6FDODFRGHDVVXFFLQFWDVFRGHLQPRVWG\QDPLFDOO\W\SHG
ODQJXDJHV7\SHLQIHUHQFHPLQLPL]HVWKHQHHGIRUH[SOLFLWW\SHLQIRUPDWLRQLQPDQ\
FRQWH[WV'HFODUDWLRQVRIW\SHVDQGIXQFWLRQVDUHYHU\FRQFLVH
6FDODDOORZVIXQFWLRQQDPHVWRLQFOXGHQRQDOSKDQXPHULFFKDUDFWHUV&RPELQHG
ZLWKVRPHV\QWDFWLFVXJDUWKLVIHDWXUHSHUPLWVWKHXVHUWRGHILQHPHWKRGVWKDWORRN
DQGEHKDYHOLNHRSHUDWRUV$VDUHVXOWOLEUDULHVRXWVLGHWKHFRUHRIWKHODQJXDJH
FDQIHHO£QDWLYH¤WRXVHUV
$VRSKLVWLFDWHGW\SHV\VWHP
6FDODH[WHQGVWKHW\SHV\VWHPRI-DYDZLWKPRUHIOH[LEOHJHQHULFVDQGDQXPEHURI
PRUHDGYDQFHGW\SLQJFRQVWUXFWV7KHW\SHV\VWHPFDQEHLQWLPLGDWLQJDWILUVWEXW
PRVWRIWKHWLPH\RXZRQ¦WQHHGWRZRUU\DERXWWKHDGYDQFHGFRQVWUXFWV7\SH
LQIHUHQFHKHOSVE\DXWRPDWLFDOO\LQIHUULQJW\SHVLJQDWXUHVVRWKDWWKHXVHUGRHVQ¦W
KDYHWRSURYLGHWULYLDOW\SHLQIRUPDWLRQPDQXDOO\:KHQ\RXQHHGWKHPWKRXJK
WKHDGYDQFHGW\SHIHDWXUHVSURYLGH\RXZLWKJUHDWHUIOH[LELOLW\IRUVROYLQJGHVLJQ
SUREOHPVLQDW\SHVDIHZD\
6FDODEOH¢DUFKLWHFWXUHV
6FDODLVGHVLJQHGWRVFDOHIURPVPDOOLQWHUSUHWHGVFULSWVWRODUJHGLVWULEXWHGDS
SOLFDWLRQV6FDODSURYLGHVIRXUODQJXDJHPHFKDQLVPVWKDWSURPRWHVFDODEOHFRP
SRVLWLRQRIV\VWHPV H[SOLFLWVHOIW\SHV DEVWUDFWW\SHPHPEHUVDQGJHQHULFV
 QHVWHGFODVVHVDQG PL[LQFRPSRVLWLRQXVLQJWUDLWV
1RRWKHUODQJXDJHSURYLGHVDOOWKHVHPHFKDQLVPV7RJHWKHUWKH\DOORZDSSOLFD
WLRQVWREHFRQVWUXFWHGIURPUHXVDEOH£FRPSRQHQWV¤LQDW\SHVDIHDQGVXFFLQFW
PDQQHU$VZHZLOOVHHPDQ\FRPPRQGHVLJQSDWWHUQVDQGDUFKLWHFWXUDOWHFKQL
TXHVOLNHGHSHQGHQF\LQMHFWLRQDUHHDV\WRLPSOHPHQWLQ6FDODZLWKRXWWKHERLOHU
SODWHFRGHRUOHQJWK\;0/FRQILJXUDWLRQILOHVWKDWFDQPDNH-DYDGHYHORSPHQW
WHGLRXV
6FDODEOH¢SHUIRUPDQFH
%HFDXVH6FDODFRGHUXQVRQWKH-90DQGWKH&/5LWEHQHILWVIURPDOOWKHSHUIRUP
DQFHRSWLPL]DWLRQVSURYLGHGE\WKRVHUXQWLPHVDQGDOOWKHWKLUGSDUW\WRROVWKDW
VXSSRUWSHUIRUPDQFHDQGVFDODELOLW\VXFKDVSURILOHUVGLVWULEXWHGFDFKHOLEUDULHV
FOXVWHULQJPHFKDQLVPVHWF,I\RXWUXVW-DYD¦VDQG&¦VSHUIRUPDQFH\RXFDQWUXVW
6FDOD¦VSHUIRUPDQFH2IFRXUVHVRPHSDUWLFXODUFRQVWUXFWVLQWKHODQJXDJHDQG
VRPHSDUWVRIWKHOLEUDU\PD\SHUIRUPVLJQLILFDQWO\EHWWHURUZRUVHWKDQDOWHUQDWLYH
RSWLRQVLQRWKHUODQJXDJHV$VDOZD\V\RXVKRXOGSURILOH\RXUFRGHDQGRSWLPL]H
LWZKHQQHFHVVDU\
,WPLJKWDSSHDUWKDW223DQG)3DUHLQFRPSDWLEOH,QIDFWDGHVLJQSKLORVRSK\RI6FDOD
LVWKDW223DQG)3DUHPRUHV\QHUJLVWLFWKDQRSSRVHG7KHIHDWXUHVRIRQHDSSURDFK
FDQHQKDQFHWKHRWKHU

6 | Chapter 1:—Zero to Sixty: Introducing Scala

Download at WoweBook.Com
,Q)3IXQFWLRQVKDYHQRVLGHHIIHFWVDQGYDULDEOHVDUHLPPXWDEOHZKLOHLQ223PX
WDEOHVWDWHDQGVLGHHIIHFWVDUHFRPPRQHYHQHQFRXUDJHG6FDODOHWV\RXFKRRVHWKH
DSSURDFKWKDWEHVWILWV\RXUGHVLJQSUREOHPV)XQFWLRQDOSURJUDPPLQJLVHVSHFLDOO\
XVHIXOIRUFRQFXUUHQF\VLQFHLWHOLPLQDWHVWKHQHHGWRV\QFKURQL]HDFFHVVWRPXWDEOH
VWDWH+RZHYHU£SXUH¤)3FDQEHUHVWULFWLYH6RPHGHVLJQSUREOHPVDUHHDVLHUWRVROYH
ZLWKPXWDEOHREMHFWV
7KHQDPH6FDODLVDFRQWUDFWLRQRIWKHZRUGVVFDODEOHODQJXDJH:KLOHWKLVVXJJHVWV
WKDWWKHSURQXQFLDWLRQVKRXOGEHVFDOHDKWKHFUHDWRUVRI6FDODDFWXDOO\SURQRXQFHLW
VFDKODKOLNHWKH,WDOLDQZRUGIRU£VWDLUV¤7KHWZR£D¤VDUHSURQRXQFHGWKHVDPH
6FDODZDVVWDUWHGE\0DUWLQ2GHUVN\LQ0DUWLQLVDSURIHVVRULQWKH6FKRRORI
&RPSXWHUDQG&RPPXQLFDWLRQ6FLHQFHVDWWKH(FROH3RO\WHFKQLTXH)pGpUDOHGH/DX
VDQQH (3)/ +HVSHQWKLVJUDGXDWH\HDUVZRUNLQJLQWKHJURXSKHDGHGE\1LNODXV
:LUWKRI3DVFDOIDPH0DUWLQZRUNHGRQ3L]]DDQHDUO\IXQFWLRQDOODQJXDJHRQWKH
-90+HODWHUZRUNHGRQ*-DSURWRW\SHRIZKDWODWHUEHFDPH*HQHULFVLQ-DYDZLWK
3KLOLS:DGOHURI+DVNHOOIDPH0DUWLQZDVKLUHGE\6XQ0LFURV\VWHPVWRSURGXFHWKH
UHIHUHQFHLPSOHPHQWDWLRQRIjavacWKH-DYDFRPSLOHUWKDWVKLSVZLWKWKH-DYD'HYHORSHU
.LW -'. WRGD\
0DUWLQ2GHUVN\¦VEDFNJURXQGDQGH[SHULHQFHDUHHYLGHQWLQWKHODQJXDJH$V\RXOHDUQ
6FDOD \RX FRPH WR XQGHUVWDQG WKDW LW LV WKH SURGXFW RI FDUHIXOO\ FRQVLGHUHG GHVLJQ
GHFLVLRQVH[SORLWLQJWKHVWDWHRIWKHDUWLQW\SHWKHRU\223DQG)30DUWLQ¦VH[SH
ULHQFHZLWKWKH-90LVHYLGHQWLQ6FDOD¦VHOHJDQWLQWHJUDWLRQZLWKWKDWSODWIRUP7KH
V\QWKHVLVLWFUHDWHVEHWZHHQ223DQG)3LVDQH[FHOOHQW£EHVWRIERWKZRUOGV¤VROXWLRQ

The Seductions of Scala


7RGD\RXULQGXVWU\LVIRUWXQDWHWRKDYHDZLGHYDULHW\RIODQJXDJHRSWLRQV7KHSRZHU
IOH[LELOLW\DQGHOHJDQFHRIG\QDPLFDOO\W\SHGODQJXDJHVKDYHPDGHWKHPYHU\SRSXODU
DJDLQ<HWWKHZHDOWKRI-DYDDQG1(7OLEUDULHVDQGWKHSHUIRUPDQFHRIWKH-90DQG
&/5PHHWPDQ\SUDFWLFDOQHHGVIRUHQWHUSULVHDQG,QWHUQHWSURMHFWV
6FDODLVFRPSHOOLQJEHFDXVHLWIHHOVOLNHDG\QDPLFDOO\W\SHGVFULSWLQJODQJXDJHGXHWR
LWVVXFFLQFWV\QWD[DQGW\SHLQIHUHQFH<HW6FDODJLYHV\RXDOOWKHEHQHILWVRIVWDWLFW\SLQJ
DPRGHUQREMHFWPRGHOIXQFWLRQDOSURJUDPPLQJDQGDQDGYDQFHGW\SHV\VWHP7KHVH
WRROVOHW\RXEXLOGVFDODEOHPRGXODUDSSOLFDWLRQVWKDWFDQUHXVHOHJDF\-DYDDQG1(7
$3,VDQGOHYHUDJHWKHSHUIRUPDQFHRIWKH-90DQG&/5
6FDODLVDODQJXDJHIRUSURIHVVLRQDOGHYHORSHUV&RPSDUHGWRODQJXDJHVOLNH-DYDDQG
5XE\6FDODLVDPRUHGLIILFXOWODQJXDJHWRPDVWHUEHFDXVHLWUHTXLUHVFRPSHWHQF\ZLWK
223)3DQGVWDWLFW\SLQJWRXVHLWPRVWHIIHFWLYHO\,WLVWHPSWLQJWRSUHIHUWKHUHODWLYH
VLPSOLFLW\RIG\QDPLFDOO\W\SHGODQJXDJHV<HWWKLVVLPSOLFLW\FDQEHGHFHSWLYH,QD
G\QDPLFDOO\W\SHGODQJXDJHLWLVRIWHQQHFHVVDU\WRXVHPHWDSURJUDPPLQJIHDWXUHVWR
LPSOHPHQWDGYDQFHGGHVLJQV:KLOHPHWDSURJUDPPLQJLVSRZHUIXOXVLQJLWZHOOWDNHV
H[SHULHQFHDQGWKHUHVXOWLQJFRGHWHQGVWREHKDUGWRXQGHUVWDQGPDLQWDLQDQGGHEXJ

Why Scala? | 7

Download at WoweBook.Com
,Q 6FDOD PDQ\ RI WKH VDPH GHVLJQ JRDOV FDQ EH DFKLHYHG LQ D W\SHVDIH PDQQHU E\
H[SORLWLQJLWVW\SHV\VWHPDQGPL[LQFRPSRVLWLRQWKURXJKWUDLWV
:HIHHOWKDWWKHH[WUDHIIRUWUHTXLUHGGD\WRGD\WRXVH6FDODZLOOSURPRWHPRUHFDUHIXO
UHIOHFWLRQDERXW\RXUGHVLJQV2YHUWLPHWKLVGLVFLSOLQHZLOO\LHOGPRUHFRKHUHQWPRG
XODUDQGPDLQWDLQDEOHDSSOLFDWLRQV)RUWXQDWHO\\RXGRQ¦WQHHGDOORIWKHVRSKLVWLFD
WLRQRI6FDODDOORIWKHWLPH0XFKRI\RXUFRGHZLOOKDYHWKHVLPSOLFLW\DQGFODULW\RI
FRGHZULWWHQLQ\RXUIDYRULWHG\QDPLFDOO\W\SHGODQJXDJH
$QDOWHUQDWLYHVWUDWHJ\LVWRFRPELQHVHYHUDOVLPSOHUODQJXDJHVHJ-DYDIRUREMHFW
RULHQWHGFRGHDQG(UODQJIRUIXQFWLRQDOFRQFXUUHQWFRGH6XFKDGHFRPSRVLWLRQFDQ
ZRUNEXWRQO\LI\RXUV\VWHPGHFRPSRVHVFOHDQO\LQWRVXFKGLVFUHWHSDUWVDQG\RXU
WHDP FDQ PDQDJH D KHWHURJHQHRXV HQYLURQPHQW 6FDOD LV DWWUDFWLYH IRU VLWXDWLRQV LQ
ZKLFKDVLQJOHDOOLQRQHODQJXDJHLVSUHIHUUHG7KDWVDLG6FDODFRGHFDQKDSSLO\FR
H[LVWZLWKRWKHUODQJXDJHVHVSHFLDOO\RQWKH-90RU1(7

Installing Scala
7RJHWXSDQGUXQQLQJDVTXLFNO\DVSRVVLEOHWKLVVHFWLRQGHVFULEHVKRZWRLQVWDOOWKH
FRPPDQGOLQHWRROVIRU6FDODZKLFKDUHDOO\RXQHHGWRZRUNZLWKWKHH[DPSOHVLQWKH
ERRN )RU GHWDLOV RQ XVLQJ 6FDOD LQ YDULRXV HGLWRUV DQG ,'(V VHH £,QWHJUDWLRQ ZLWK
,'(V¤RQSDJH7KHH[DPSOHVXVHGLQWKLVERRNZHUHZULWWHQDQGFRPSLOHGXVLQJ
6FDOD YHUVLRQ ILQDO WKH ODWHVW UHOHDVH DW WKH WLPH RI WKLV ZULWLQJ DQG £QLJKWO\
EXLOGV¤RI6FDODYHUVLRQZKLFKPD\EHILQDOL]HGE\WKHWLPH\RXUHDGWKLV

9HUVLRQ  LQWURGXFHV PDQ\ QHZ IHDWXUHV ZKLFK ZH ZLOO KLJKOLJKW
WKURXJKRXWWKHERRN

:HZLOOZRUNZLWKWKH-90YHUVLRQRI6FDODLQWKLVERRN)LUVW\RXPXVWKDYH-DYD
RUJUHDWHULQVWDOOHG RUJUHDWHULVUHFRPPHQGHG ,I\RXQHHGWRLQVWDOO-DYDJRWR
KWWSZZZMDYDFRPHQGRZQORDGPDQXDOMVSDQGIROORZWKHLQVWUXFWLRQVWRLQVWDOO-DYD
RQ\RXUPDFKLQH
7KH RIILFLDO 6FDOD ZHEVLWH LV KWWSZZZVFDODODQJRUJ 7R LQVWDOO 6FDOD JR WR WKH
GRZQORDGVSDJH'RZQORDGWKHLQVWDOOHUIRU\RXUHQYLURQPHQWDQGIROORZWKHLQVWUXF
WLRQVRQWKHGRZQORDGVSDJH
7KHHDVLHVWFURVVSODWIRUPLQVWDOOHULVWKH,]3DFNLQVWDOOHU'RZQORDGWKH6FDOD-$5ILOH
HLWKHUVFDODILQDOLQVWDOOHUMDURUVFDOD1LQVWDOOHUMDUZKHUH NLVWKHODWHVW
UHOHDVHRIWKHYHUVLRQ*RWRWKHGRZQORDGGLUHFWRU\LQDWHUPLQDOZLQGRZDQG
LQVWDOO 6FDOD ZLWK WKH java FRPPDQG $VVXPLQJ \RX GRZQORDGHG VFDODILQDO
LQVWDOOHUMDUUXQWKHIROORZLQJFRPPDQGZKLFKZLOOJXLGH\RXWKURXJKWKHSURFHVV
java -jar scala-2.8.0.final-installer.jar

8 | Chapter 1:—Zero to Sixty: Introducing Scala

Download at WoweBook.Com
2Q0DF26;WKHHDVLHVWURXWHWRDZRUNLQJ6FDODLQVWDOODWLRQLVYLD
0DF3RUWV)ROORZWKHLQVWDOODWLRQLQVWUXFWLRQVDWKWWSZZZPDFSRUWV
RUJWKHQsudo port install scala<RX¦OOEHXSDQGUXQQLQJLQDIHZ
PLQXWHV

7KURXJKRXWWKLVERRNZHZLOOXVHWKHV\PEROscala-homeWRUHIHUWRWKH£URRW¤GLUHFWRU\
RI\RXU6FDODLQVWDOODWLRQ

2Q 8QL[ /LQX[ DQG 0DF 26 ; V\VWHPV \RX ZLOO QHHG WR UXQ WKLV
FRPPDQGDVWKH rootXVHURUXVLQJWKH sudoFRPPDQGLI\RXZDQWWR
LQVWDOO 6FDOD XQGHU D V\VWHP GLUHFWRU\ HJ scala-home  XVUORFDO
VFDODILQDO

$V DQ DOWHUQDWLYH \RX FDQ GRZQORDG DQG H[SDQG WKH FRPSUHVVHG 7$5 ILOH HJ
VFDODILQDOWJ] RU=,3ILOH VFDODILQDO]LS 2Q8QL[OLNHV\VWHPVH[SDQG
WKHFRPSUHVVHGILOHLQWRDORFDWLRQRI\RXUFKRRVLQJ$IWHUZDUGDGGWKH scala-home
ELQ VXEGLUHFWRU\ LQ WKH QHZ GLUHFWRU\ WR \RXU PATH )RU H[DPSOH LI \RX LQVWDOOHG
LQWRXVUORFDOVFDODILQDOWKHQDGGXVUORFDOVFDODILQDOELQWR\RXUPATH
7RWHVW\RXULQVWDOODWLRQUXQWKHIROORZLQJFRPPDQGRQWKHFRPPDQGOLQH
scala -version

:H¦OOOHDUQPRUHDERXWWKHscalaFRPPDQGOLQHWRROODWHU<RXVKRXOGJHWVRPHWKLQJ
OLNHWKHIROORZLQJRXWSXW
Scala code runner version 2.8.0.final -- Copyright 2002-2009, LAMP/EPFL

2IFRXUVHWKHYHUVLRQQXPEHU\RXVHHZLOOEHGLIIHUHQWLI\RXLQVWDOOHGDGLIIHUHQWUH
OHDVH)URPQRZRQZKHQZHVKRZFRPPDQGRXWSXWWKDWFRQWDLQVWKHYHUVLRQQXPEHU
ZH¦OOVKRZLWDVversion 2.8.0.final
&RQJUDWXODWLRQV\RXKDYHLQVWDOOHG6FDOD,I\RXJHWDQHUURUPHVVDJHDORQJWKHOLQHV
RI scala: command not foundPDNHVXUH\RXUHQYLURQPHQW¦V PATHLVVHWSURSHUO\WR
LQFOXGHWKHFRUUHFWELQGLUHFWRU\

6FDODYHUVLRQV;DQGHDUOLHUDUHFRPSDWLEOHZLWK-'.DQGODWHU
6FDODYHUVLRQGURSVFRPSDWLELOLW\1RWHWKDW6FDODXVHVPDQ\
-'.FODVVHVDVLWVRZQIRUH[DPSOHWKH StringFODVV2Q1(76FDOD
XVHVWKHFRUUHVSRQGLQJ1(7FODVVHV

<RXFDQDOVRILQGGRZQORDGVIRUWKH$3,GRFXPHQWDWLRQDQGWKHVRXUFHVIRU6FDODLWVHOI
RQWKHVDPHGRZQORDGVSDJH

Installing Scala | 9

Download at WoweBook.Com
For More Information
$V\RXH[SORUH6FDOD\RXZLOOILQGRWKHUXVHIXOUHVRXUFHVWKDWDUHDYDLODEOHRQKWWS
VFDODODQJRUJ<RXZLOOILQGOLQNVIRUGHYHORSPHQWVXSSRUWWRROVDQGOLEUDULHVWXWRULDOV
WKHODQJXDJHVSHFLILFDWLRQ>6FDOD6SHF@DQGDFDGHPLFSDSHUVWKDWGHVFULEHIHDWXUHV
RIWKHODQJXDJH
7KHGRFXPHQWDWLRQIRUWKH6FDODWRROVDQG$3,VDUHHVSHFLDOO\XVHIXO<RXFDQEURZVH
WKH$3,DWKWWSZZZVFDODODQJRUJGRFXILOHVDSLLQGH[KWPO7KLVGRFXPHQWDWLRQZDV
JHQHUDWHGXVLQJWKHscaladocWRRODQDORJRXVWR-DYD¦VjavadocWRRO6HH£7KHVFDODGRF
&RPPDQG/LQH7RRO¤RQSDJHIRUPRUHLQIRUPDWLRQ
<RXFDQDOVRGRZQORDGDFRPSUHVVHGILOHRIWKH$3,GRFXPHQWDWLRQIRUORFDOEURZVLQJ
XVLQJWKHDSSURSULDWHOLQNRQWKHGRZQORDGVSDJHRU\RXFDQLQVWDOOLWZLWKWKH sbaz
SDFNDJHWRRODVIROORZV
sbaz install scala-devel-docs

sbazLVLQVWDOOHGLQWKHVDPHELQGLUHFWRU\DVWKHscalaDQGscalacFRPPDQGOLQHWRROV
7KHLQVWDOOHGGRFXPHQWDWLRQDOVRLQFOXGHVGHWDLOVRQWKHVFDODWRROFKDLQ LQFOXGLQJ
sbaz DQGFRGHH[DPSOHV)RUPRUHLQIRUPDWLRQRQWKH6FDODFRPPDQGOLQHWRROVDQG
RWKHUUHVRXUFHVVHH&KDSWHU

A Taste of Scala
,W¦VWLPHWRZKHW\RXUDSSHWLWHZLWKVRPHUHDO6FDODFRGH,QWKHIROORZLQJH[DPSOHV
ZH¦OOGHVFULEHMXVWHQRXJKRIWKHGHWDLOVVR\RXXQGHUVWDQGZKDW¦VJRLQJRQ7KHJRDO
LVWRJLYH\RXDVHQVHRIZKDWSURJUDPPLQJLQ6FDODLVOLNH:H¦OOH[SORUHWKHGHWDLOVRI
WKHIHDWXUHVLQVXEVHTXHQWFKDSWHUV
)RURXUILUVWH[DPSOH\RXFRXOGUXQLWRQHRIWZRZD\VLQWHUDFWLYHO\RUDVD£VFULSW¤
/HW¦VVWDUWZLWKWKHLQWHUDFWLYHPRGH6WDUWWKHVFDODLQWHUSUHWHUE\W\SLQJscalaDQGWKH
UHWXUQNH\RQ\RXUFRPPDQGOLQH<RX¦OOVHHWKHIROORZLQJRXWSXW 6RPHRIWKHYHUVLRQ
QXPEHUVPD\YDU\
Welcome to Scala version 2.8.0.final (Java ...).
Type in expressions to have them evaluated.
Type :help for more information.

scala>

7KHODVWOLQHLVWKHSURPSWWKDWLVZDLWLQJIRU\RXULQSXW7KHLQWHUDFWLYHPRGHRIWKH
scalaFRPPDQGLVYHU\FRQYHQLHQWIRUH[SHULPHQWDWLRQ VHH£7KHVFDOD&RPPDQG/LQH
7RRO¤RQSDJHIRUPRUHGHWDLOV $QLQWHUDFWLYHLQWHUSUHWHUOLNHWKLVLVFDOOHGD5(3/
5HDG(YDOXDWH3ULQW/RRS

10 | Chapter 1:—Zero to Sixty: Introducing Scala

Download at WoweBook.Com
7\SHLQWKHIROORZLQJWZROLQHVRIFRGH
val book = "Programming Scala"
println(book)

7KHDFWXDOLQSXWDQGRXWSXWVKRXOGORRNOLNHWKHIROORZLQJ
scala> val book = "Programming Scala"
book: java.lang.String = Programming Scala

scala> println(book)
Programming Scala

scala>

7KHILUVWOLQHXVHVWKH valNH\ZRUGWRGHFODUHDUHDGRQO\YDULDEOHQDPHG book1RWH


WKDWWKHRXWSXWUHWXUQHGIURPWKHLQWHUSUHWHUVKRZV\RXWKHW\SHDQGYDOXHRI book
7KLVFDQEHYHU\KDQG\IRUXQGHUVWDQGLQJFRPSOH[GHFODUDWLRQV7KHVHFRQGOLQHSULQWV
WKHYDOXHRIbookZKLFKLV£3URJUDPPLQJ6FDOD¤

([SHULPHQWLQJZLWKWKHscalaFRPPDQGLQWKHLQWHUDFWLYHPRGH 5(3/
LVDJUHDWZD\WROHDUQWKHGHWDLOVRI6FDOD

0DQ\RIWKHH[DPSOHVLQWKLVERRNFDQEHH[HFXWHGLQWKHLQWHUSUHWHUOLNHWKLV+RZHYHU
LW¦VRIWHQPRUHFRQYHQLHQWWRXVHWKHVHFRQGRSWLRQZHPHQWLRQHGZULWLQJ6FDODVFULSWV
LQDWH[WHGLWRURU,'(DQGH[HFXWLQJWKHPZLWKWKHVDPH scalaFRPPDQG:H¦OOGR
WKDWIRUPRVWRIWKHUHPDLQLQJH[DPSOHVLQWKLVFKDSWHU
,Q\RXUWH[WHGLWRURIFKRLFHVDYHWKH6FDODFRGHLQWKHIROORZLQJH[DPSOHWRDILOH
QDPHGXSSHUVFULSWVFDODLQDGLUHFWRU\RI\RXUFKRRVLQJ
// code-examples/IntroducingScala/upper1-script.scala

class Upper {
def upper(strings: String*): Seq[String] = {
strings.map((s:String) => s.toUpperCase())
}
}

val up = new Upper


Console.println(up.upper("A", "First", "Scala", "Program"))

7KLV6FDODVFULSWFRQYHUWVVWULQJVWRXSSHUFDVH
%\WKHZD\WKDW¦VDFRPPHQWRQWKHILUVWOLQH ZLWKWKHQDPHRIWKHVRXUFHILOHIRUWKH
FRGHH[DPSOH 6FDODIROORZVWKHVDPHFRPPHQWFRQYHQWLRQVDV-DYD&&HWF
$// commentJRHVWRWKHHQGRIDOLQHZKLOHD/* comment */FDQFURVVOLQHERXQGDULHV

A Taste of Scala | 11

Download at WoweBook.Com
7RUXQWKLVVFULSWJRWRDFRPPDQGZLQGRZFKDQJHWRWKHVDPHGLUHFWRU\DQGUXQ
WKHIROORZLQJFRPPDQG
scala upper1-script.scala

7KHILOHLVLQWHUSUHWHGPHDQLQJLWLVFRPSLOHGDQGH[HFXWHGLQRQHVWHS<RXVKRXOG
JHWWKHIROORZLQJRXWSXW
Array(A, FIRST, SCALA, PROGRAM)

Interpreting Versus Compiling and Running Scala Code


7RVXPPDUL]HLI\RXW\SH scalaRQWKHFRPPDQGOLQHZLWKRXWDILOHDUJXPHQWWKH
LQWHUSUHWHUUXQVLQLQWHUDFWLYHPRGH<RXW\SHLQGHILQLWLRQVDQGVWDWHPHQWVWKDWDUH
HYDOXDWHGRQWKHIO\,I\RXJLYHWKHFRPPDQGDVFDODVRXUFHILOHDUJXPHQWLWFRPSLOHV
DQGUXQVWKHILOHDVDVFULSWDVLQRXUscala upper1-script.scalaH[DPSOH)LQDOO\\RX
FDQFRPSLOH6FDODILOHVVHSDUDWHO\DQGH[HFXWHWKH classILOHDVORQJDVLWKDVD main
PHWKRGMXVWDV\RXZRXOGQRUPDOO\GRZLWKWKH javaFRPPDQG :H¦OOVKRZDQH[
DPSOHVKRUWO\
7KHUHDUHVRPHVXEWOHWLHV\RX¦OOQHHGWRXQGHUVWDQGDERXWWKHOLPLWDWLRQVRIXVLQJWKH
LQWHUSUHWHUPRGHVYHUVXVVHSDUDWHFRPSLODWLRQDQGH[HFXWLRQVWHSV:HGLVFXVVWKHVH
VXEWOHWLHVLQ£&RPPDQG/LQH7RROV¤RQSDJH
:KHQHYHUZHUHIHUWRH[HFXWLQJDVFULSWZHPHDQUXQQLQJD6FDODVRXUFHILOHZLWKWKH
scalaFRPPDQG

,QWKHFXUUHQWH[DPSOHWKHupperPHWKRGLQWKHUpperFODVV QRSXQLQWHQGHG FRQYHUWV


WKHLQSXWVWULQJVWRXSSHUFDVHDQGUHWXUQVWKHPLQDQDUUD\7KHODVWOLQHLQWKHH[DPSOH
FRQYHUWVIRXUVWULQJVDQGSULQWVWKHUHVXOWLQJArray
/HW¦VH[DPLQHWKHFRGHLQGHWDLOVRZHFDQEHJLQWROHDUQ6FDODV\QWD[7KHUHDUHDORW
RIGHWDLOVLQMXVWVL[OLQHVRIFRGH:H¦OOH[SODLQWKHJHQHUDOLGHDVKHUH$OOWKHLGHDV
XVHGLQWKLVH[DPSOHZLOOEHH[SODLQHGPRUHWKRURXJKO\LQODWHUVHFWLRQVRIWKHERRN
,QWKHH[DPSOHWKHUpperFODVVEHJLQVZLWKWKHclassNH\ZRUG7KHFODVVERG\LVLQVLGH
WKHRXWHUPRVWFXUO\EUDFHV {...} 
7KHupperPHWKRGGHILQLWLRQEHJLQVRQWKHVHFRQGOLQHZLWKWKHdefNH\ZRUGIROORZHG
E\WKHPHWKRGQDPHDQGDQDUJXPHQWOLVWWKHUHWXUQW\SHRIWKHPHWKRGDQHTXDOV
VLJQ = DQGWKHQWKHPHWKRGERG\
7KHDUJXPHQWOLVWLQSDUHQWKHVHVLVDFWXDOO\DYDULDEOHOHQJWKDUJXPHQWOLVWRIStringV
LQGLFDWHGE\WKH String*W\SHIROORZLQJWKHFRORQ7KDWLV\RXFDQSDVVLQDVPDQ\
FRPPDVHSDUDWHGVWULQJVDV\RXZDQW LQFOXGLQJDQHPSW\OLVW 7KHVHVWULQJVDUHVWRUHG
LQDSDUDPHWHUQDPHGstrings,QVLGHWKHPHWKRGstringsLVDFWXDOO\DQArray

12 | Chapter 1:—Zero to Sixty: Introducing Scala

Download at WoweBook.Com
:KHQH[SOLFLWW\SHLQIRUPDWLRQIRUYDULDEOHVLVZULWWHQLQWKHFRGHWKHVH
W\SHDQQRWDWLRQVIROORZWKHFRORQDIWHUWKHLWHPQDPH LH3DVFDOOLNH
V\QWD[ :K\GRHVQ¦W6FDODIROORZ-DYDFRQYHQWLRQV"5HFDOOWKDWW\SH
LQIRUPDWLRQLVRIWHQLQIHUUHGLQ6FDOD XQOLNH-DYD PHDQLQJZHGRQ¦W
DOZD\V VKRZ W\SH DQQRWDWLRQV H[SOLFLWO\ &RPSDUHG WR -DYD¦V
type itemFRQYHQWLRQWKHitem: typeFRQYHQWLRQLVHDVLHUIRUWKHFRP
SLOHUWRDQDO\]HXQDPELJXRXVO\ZKHQ\RXRPLWWKHFRORQDQGWKHW\SH
DQQRWDWLRQDQGMXVWZULWHitem

7KHPHWKRGUHWXUQW\SHDSSHDUVDIWHUWKHDUJXPHQWOLVW,QWKLVFDVHWKHUHWXUQW\SHLV
Seq[String]ZKHUHSeq £VHTXHQFH¤ LVDSDUWLFXODUNLQGRIFROOHFWLRQ,WLVDSDUDPH
WHUL]HGW\SH OLNHDJHQHULFW\SHLQ-DYD SDUDPHWHUL]HGKHUHZLWKString1RWHWKDW6FDOD
XVHVVTXDUHEUDFNHWV [...] IRUSDUDPHWHUL]HGW\SHVZKHUHDV-DYDXVHVDQJOHEUDFNHWV
<...> 

6FDODDOORZVDQJOHEUDFNHWVWREHXVHGLQPHWKRGQDPHVHJQDPLQJD
£OHVVWKDQ¤PHWKRG <LVFRPPRQ6RWRDYRLGDPELJXLWLHV6FDODXVHV
VTXDUHEUDFNHWVLQVWHDGIRUSDUDPHWHUL]HGW\SHV7KH\FDQ¦WEHXVHGLQ
PHWKRGQDPHV$OORZLQJ<DQG>LQPHWKRGQDPHVLVZK\6FDODGRHVQ¦W
IROORZ-DYD¦VFRQYHQWLRQIRUDQJOHEUDFNHWV

7KHERG\RIWKH upperPHWKRGFRPHVDIWHUWKHHTXDOVVLJQ = :K\DQHTXDOVVLJQ"


:K\QRWMXVWFXUO\EUDFHV {...} OLNHLQ-DYD"%HFDXVHVHPLFRORQVIXQFWLRQUHWXUQ
W\SHVPHWKRGDUJXPHQWVOLVWVDQGHYHQWKHFXUO\EUDFHVDUHVRPHWLPHVRPLWWHGXVLQJ
DQHTXDOVVLJQSUHYHQWVVHYHUDOSRVVLEOHSDUVLQJDPELJXLWLHV8VLQJDQHTXDOVVLJQDOVR
UHPLQGV XV WKDW HYHQ IXQFWLRQV DUH YDOXHV LQ 6FDOD ZKLFK LV FRQVLVWHQW ZLWK 6FDOD¦V
VXSSRUWRIIXQFWLRQDOSURJUDPPLQJGHVFULEHGLQPRUHGHWDLOLQ&KDSWHU
7KHPHWKRGERG\FDOOVWKH mapPHWKRGRQWKH stringsDUUD\ZKLFKWDNHVDIXQFWLRQ
OLWHUDODVDQDUJXPHQW)XQFWLRQOLWHUDOVDUH£DQRQ\PRXV¤IXQFWLRQV7KH\DUHVLPLODU
WRODPEGDVFORVXUHVEORFNVRUSURFVLQRWKHUODQJXDJHV,Q-DYD\RXZRXOGKDYHWRXVH
DQDQRQ\PRXVLQQHUFODVVKHUHWKDWLPSOHPHQWVDPHWKRGGHILQHGE\DQLQWHUIDFHHWF
,QWKLVFDVHZHSDVVHGLQWKHIROORZLQJIXQFWLRQOLWHUDO
(s:String) => s.toUpperCase()

,W WDNHV DQ DUJXPHQW OLVW ZLWK D VLQJOH String DUJXPHQW QDPHG s 7KH ERG\ RI WKH
IXQFWLRQOLWHUDOLVDIWHUWKH£DUURZ¤ =>,WFDOOV toUpperCase()RQ s7KHUHVXOWRIWKLV
FDOOLVUHWXUQHGE\WKHIXQFWLRQOLWHUDO,Q6FDODWKHODVWH[SUHVVLRQLQDIXQFWLRQLVWKH
UHWXUQYDOXHDOWKRXJK\RXFDQKDYHreturnVWDWHPHQWVHOVHZKHUHWRR7KHreturnNH\
ZRUGLVRSWLRQDOKHUHDQGLVUDUHO\XVHGH[FHSWZKHQUHWXUQLQJRXWRIWKHPLGGOHRID
EORFN HJLQDQifVWDWHPHQW 

A Taste of Scala | 13

Download at WoweBook.Com
7KHYDOXHRIWKHODVWH[SUHVVLRQLVWKHGHIDXOWUHWXUQYDOXHRIDIXQFWLRQ
1RreturnLVUHTXLUHG

6R mapSDVVHVHDFK StringLQ stringsWRWKHIXQFWLRQOLWHUDODQGEXLOGVXSDQHZFRO


OHFWLRQZLWKWKHUHVXOWVUHWXUQHGE\WKHIXQFWLRQOLWHUDO
7RH[HUFLVHWKHFRGHZHFUHDWHDQHZUpperLQVWDQFHDQGDVVLJQLWWRDYDULDEOHQDPHG
up$VLQ-DYD&DQGVLPLODUODQJXDJHVWKHV\QWD[new UpperFUHDWHVDQHZLQVWDQFH
7KHupYDULDEOHLVGHFODUHGDVDUHDGRQO\£YDOXH¤XVLQJWKHvalNH\ZRUG
)LQDOO\ ZH FDOO WKH upper PHWKRG RQ D OLVW RI VWULQJV DQG SULQW RXW WKH UHVXOW ZLWK
Console.println(...)ZKLFKLVHTXLYDOHQWWR-DYD¦VSystem.out.println(...)
:HFDQDFWXDOO\VLPSOLI\RXUVFULSWHYHQIXUWKHU&RQVLGHUWKLVVLPSOLILHGYHUVLRQRIWKH
VFULSW
// code-examples/IntroducingScala/upper2-script.scala

object Upper {
def upper(strings: String*) = strings.map(_.toUpperCase())
}

println(Upper.upper("A", "First", "Scala", "Program"))

7KLVFRGHGRHVH[DFWO\WKHVDPHWKLQJEXWZLWKDWKLUGIHZHUFKDUDFWHUV
2QWKHILUVWOLQHUpperLVQRZGHFODUHGDVDQobjectZKLFKLVDVLQJOHWRQ:HDUHGH
FODULQJDFODVVEXWWKH6FDODUXQWLPHZLOORQO\HYHUFUHDWHRQHLQVWDQFHRIUpper <RX
FDQ¦WZULWHnew UpperIRUH[DPSOH 6FDODXVHVobjectsIRUVLWXDWLRQVZKHUHRWKHUODQ
JXDJHVZRXOGXVH£FODVVOHYHO¤PHPEHUVOLNH staticVLQ-DYD:HGRQ¦WUHDOO\QHHG
PRUHWKDQRQHLQVWDQFHKHUHVRDVLQJOHWRQLVILQH

:K\ GRHVQ¦W 6FDOD VXSSRUW staticV" 6LQFH HYHU\WKLQJ LV DQ REMHFW LQ
6FDODWKH objectFRQVWUXFWNHHSVWKLVSROLF\FRQVLVWHQW-DYD¦V static
PHWKRGVDQGILHOGVDUHQRWWLHGWRDQDFWXDOLQVWDQFH

1RWHWKDWWKLVFRGHLVIXOO\WKUHDGVDIH:HGRQ¦WGHFODUHDQ\YDULDEOHVWKDWPLJKWFDXVH
WKUHDGVDIHW\LVVXHV7KH$3,PHWKRGVZHXVHDUHDOVRWKUHDGVDIH7KHUHIRUHZHGRQ¦W
QHHGPXOWLSOHLQVWDQFHV$VLQJOHWRQobjectZRUNVILQH
7KHLPSOHPHQWDWLRQRIupperRQWKHVHFRQGOLQHLVDOVRVLPSOHU6FDODFDQXVXDOO\LQIHU
WKHUHWXUQW\SHRIWKHPHWKRG EXWQRWWKHW\SHVRIWKHPHWKRGDUJXPHQWV VRZHGURS
WKHH[SOLFLWGHFODUDWLRQ$OVREHFDXVHWKHUHLVRQO\RQHH[SUHVVLRQLQWKHPHWKRGERG\
ZHGURSWKHEUDFHVDQGSXWWKHHQWLUHPHWKRGGHILQLWLRQRQRQHOLQH7KHHTXDOVVLJQ
EHIRUHWKHPHWKRGERG\WHOOVWKHFRPSLOHUDVZHOODVWKHKXPDQUHDGHUZKHUHWKH
PHWKRGERG\EHJLQV

14 | Chapter 1:—Zero to Sixty: Introducing Scala

Download at WoweBook.Com
:HKDYHDOVRH[SORLWHGDVKRUWKDQGIRUWKHIXQFWLRQOLWHUDO3UHYLRXVO\ZHZURWHLWDV
IROORZV
(s:String) => s.toUpperCase()

:HFDQVKRUWHQLWWRWKHIROORZLQJH[SUHVVLRQ
_.toUpperCase()

%HFDXVHmapWDNHVRQHDUJXPHQWDIXQFWLRQZHFDQXVHWKH£SODFHKROGHU¤LQGLFDWRU_
LQVWHDGRIDQDPHGSDUDPHWHU7KDWLVWKH_DFWVOLNHDQDQRQ\PRXVYDULDEOHWRZKLFK
HDFKVWULQJZLOOEHDVVLJQHGEHIRUH toUpperCaseLVFDOOHG1RWHWKDWWKH StringW\SHLV
LQIHUUHGIRUXVWRR$VZHZLOOVHH6FDODXVHV_DVD£ZLOGFDUG¤LQVHYHUDOFRQWH[WV
<RXFDQDOVRXVHWKLVVKRUWKDQGV\QWD[LQVRPHPRUHFRPSOH[IXQFWLRQOLWHUDOVDVZH
ZLOOVHHLQ&KDSWHU
2QWKHODVWOLQHXVLQJDQ objectUDWKHUWKDQD classVLPSOLILHVWKHFRGH,QVWHDGRI
FUHDWLQJDQLQVWDQFHZLWK new UpperZHFDQMXVWFDOOWKH upperPHWKRGRQWKH Upper
REMHFWGLUHFWO\ QRWHKRZWKLVORRNVOLNHWKHV\QWD[\RXZRXOGXVHZKHQFDOOLQJVWDWLF
PHWKRGVLQD-DYDFODVV 
)LQDOO\6FDODDXWRPDWLFDOO\LPSRUWVPDQ\PHWKRGVIRU,2OLNHprintlnVRZHGRQ¦W
QHHGWRFDOO Console.println():HFDQMXVWXVH printlnE\LWVHOI 6HH £7KH3UHGHI
2EMHFW¤RQSDJHIRUGHWDLOVRQWKHW\SHVDQGPHWKRGVWKDWDUHDXWRPDWLFDOO\LP
SRUWHGRUGHILQHG
/HW¦VGRRQHODVWUHIDFWRULQJ&RQYHUWWKHVFULSWLQWRDFRPSLOHGFRPPDQGOLQHWRRO
// code-examples/IntroducingScala/upper3.scala

object Upper {
def main(args: Array[String]) = {
args.map(_.toUpperCase()).foreach(printf("%s ",_))
println("")
}
}

1RZWKH upperPHWKRGKDVEHHQUHQDPHG main%HFDXVH UpperLVDQ objectWKLV main


PHWKRGZRUNVH[DFWO\OLNHDstatic mainPHWKRGLQD-DYDFODVV,WLVWKHHQWU\SRLQWWR
WKHUpperDSSOLFDWLRQ

,Q6FDODmainPXVWEHDPHWKRGLQDQobject ,Q-DYDmainPXVWEHD
staticPHWKRGLQDclass 7KHFRPPDQGOLQHDUJXPHQWVIRUWKHDSSOL
FDWLRQDUHSDVVHGWRmainLQDQDUUD\RIVWULQJVHJargs: Array[String]

7KHILUVWOLQHLQVLGHWKHmainPHWKRGXVHVWKHVDPHVKRUWKDQGQRWDWLRQIRUmapWKDWZH
MXVWH[DPLQHG
args.map(_.toUpperCase())...

A Taste of Scala | 15

Download at WoweBook.Com
7KHFDOOWRmapUHWXUQVDQHZFROOHFWLRQ:HLWHUDWHWKURXJKLWZLWKforeach:HXVHD
_SODFHKROGHUVKRUWFXWDJDLQLQDQRWKHUIXQFWLRQOLWHUDOWKDWZHSDVVWRforeach,QWKLV
FDVHHDFKVWULQJLQWKHFROOHFWLRQLVSDVVHGDVDQDUJXPHQWWRprintf
...foreach(printf("%s ",_))

7REHFOHDUWKHVHWZRXVHVRI _DUHFRPSOHWHO\LQGHSHQGHQWRIHDFKRWKHU0HWKRG
FKDLQLQJDQGIXQFWLRQOLWHUDOVKRUWKDQGVDVLQWKLVH[DPSOHFDQWDNHVRPHJHWWLQJXVHG
WREXWRQFH\RXDUHFRPIRUWDEOHZLWKWKHPWKH\\LHOGYHU\UHDGDEOHFRGHZLWKPLQLPDO
XVHRIWHPSRUDU\YDULDEOHV
7KHODVWOLQHLQmainDGGVDILQDOOLQHIHHGWRWKHRXWSXW
7KLVWLPH\RXPXVWILUVWFRPSLOHWKHFRGHWRD-90FODVVILOHXVLQJscalac
scalac upper3.scala

<RXVKRXOGQRZKDYHDILOHQDPHG8SSHUFODVVMXVWDVLI\RXKDGMXVWFRPSLOHGD-DYD
FODVV

<RXPD\KDYHQRWLFHGWKDWWKHFRPSLOHUGLGQRWFRPSODLQZKHQWKH
ILOHZDVQDPHGXSSHUVFDODDQGWKH objectZDVQDPHG Upper8QOLNH
-DYDWKHILOHQDPHGRHVQ¦WKDYHWRPDWFKWKHQDPHRIWKHW\SHZLWK
public VFRSH :H¦OO H[SORUH WKH YLVLELOLW\ UXOHV LQ £9LVLELOLW\
5XOHV¤RQSDJH ,QIDFWXQOLNH-DYD\RXFDQKDYHDVPDQ\SXEOLF
W\SHVLQDVLQJOHILOHDV\RXZDQW)XUWKHUPRUHWKHGLUHFWRU\ORFDWLRQRI
DILOHGRHVQ¦WKDYHWRPDWFKWKHSDFNDJHGHFODUDWLRQ+RZHYHU\RXFDQ
FHUWDLQO\IROORZWKH-DYDFRQYHQWLRQVLI\RXZDQWWR

1RZ\RXFDQH[HFXWHWKLVFRPPDQGIRUDQ\OLVWRIVWULQJV+HUHLVDQH[DPSOH
scala -cp . Upper Hello World!

7KH-cp .RSWLRQDGGVWKHFXUUHQWGLUHFWRU\WRWKHVHDUFK£FODVVSDWK¤<RXVKRXOGJHW
WKHIROORZLQJRXWSXW
HELLO WORLD!

7KHUHIRUHZHKDYHPHWWKHUHTXLUHPHQWWKDWDSURJUDPPLQJODQJXDJHERRNPXVWVWDUW
ZLWKD£KHOORZRUOG¤SURJUDP

A Taste of Concurrency
7KHUHDUHPDQ\UHDVRQVWREHVHGXFHGE\6FDOD2QHUHDVRQLVWKH$FWRUV$3,LQFOXGHG
LQWKH6FDODOLEUDU\ZKLFKLVEDVHGRQWKHUREXVW$FWRUVFRQFXUUHQF\PRGHOEXLOWLQWR
(UODQJ VHH>+DOOHU@ +HUHLVDQH[DPSOHWRZKHW\RXUDSSHWLWH
,QWKH$FWRUPRGHORIFRQFXUUHQF\ >$JKD@ LQGHSHQGHQWVRIWZDUHHQWLWLHVFDOOHG
$FWRUV VKDUH QR VWDWH LQIRUPDWLRQ ZLWK HDFK RWKHU ,QVWHDG WKH\ FRPPXQLFDWH E\

16 | Chapter 1:—Zero to Sixty: Introducing Scala

Download at WoweBook.Com
H[FKDQJLQJPHVVDJHV%\HOLPLQDWLQJWKHQHHGWRV\QFKURQL]HDFFHVVWRVKDUHGPXWDEOH
VWDWHLWLVIDUHDVLHUWRZULWHUREXVWFRQFXUUHQWDSSOLFDWLRQV
,QWKLVH[DPSOHLQVWDQFHVLQDJHRPHWULFShapeKLHUDUFK\DUHVHQWWRDQ$FWRUIRUGUDZ
LQJRQDGLVSOD\,PDJLQHDVFHQDULRZKHUHDUHQGHULQJ£IDUP¤JHQHUDWHVVFHQHVLQDQ
DQLPDWLRQ$VWKHUHQGHULQJRIDVFHQHLVFRPSOHWHGWKHVKDSH£SULPLWLYHV¤WKDWDUH
SDUWRIWKHVFHQHDUHVHQWWRDQ$FWRUIRUDGLVSOD\VXEV\VWHP
7REHJLQZHGHILQHDShapeFODVVKLHUDUFK\
// code-examples/IntroducingScala/shapes.scala

package shapes {
class Point(val x: Double, val y: Double) {
override def toString() = "Point(" + x + "," + y + ")"
}

abstract class Shape() {


def draw(): Unit
}

class Circle(val center: Point, val radius: Double) extends Shape {


def draw() = println("Circle.draw: " + this)
override def toString() = "Circle(" + center + "," + radius + ")"
}

class Rectangle(val lowerLeft: Point, val height: Double, val width: Double)
extends Shape {
def draw() = println("Rectangle.draw: " + this)
override def toString() =
"Rectangle(" + lowerLeft + "," + height + "," + width + ")"
}

class Triangle(val point1: Point, val point2: Point, val point3: Point)
extends Shape {
def draw() = println("Triangle.draw: " + this)
override def toString() =
"Triangle(" + point1 + "," + point2 + "," + point3 + ")"
}
}

7KHShapeFODVVKLHUDUFK\LVGHILQHGLQDshapesSDFNDJH<RXFDQGHFODUHWKHSDFNDJH
XVLQJ-DYDV\QWD[EXW6FDODDOVRVXSSRUWVDV\QWD[VLPLODUWR&¦V£QDPHVSDFH¤V\QWD[
ZKHUHWKHHQWLUHGHFODUDWLRQLVVFRSHGXVLQJFXUO\EUDFHVDVXVHGKHUH7KH-DYDVW\OH
SDFNDJHGHFODUDWLRQV\QWD[LVIDUPRUHFRPPRQO\XVHGKRZHYHUEHLQJERWKFRPSDFW
DQGUHDGDEOH
7KHPointFODVVUHSUHVHQWVDWZRGLPHQVLRQDOSRLQWRQDSODQH1RWHWKHDUJXPHQWOLVW
DIWHUWKHFODVVQDPH7KRVHDUHFRQVWUXFWRUSDUDPHWHUV,Q6FDODWKHZKROHFODVVERG\
LVWKHFRQVWUXFWRUVR\RXOLVWWKHDUJXPHQWVIRUWKHSULPDU\FRQVWUXFWRUDIWHUWKHFODVV
QDPH DQG EHIRUH WKH FODVV ERG\ :H¦OO VHH KRZ WR GHILQH DX[LOLDU\ FRQVWUXFWRUV LQ
£&RQVWUXFWRUV LQ 6FDOD¤ RQ SDJH   %HFDXVH ZH SXW WKH val NH\ZRUG EHIRUH HDFK
SDUDPHWHUGHFODUDWLRQWKH\DUHDXWRPDWLFDOO\FRQYHUWHGWRUHDGRQO\ILHOGVZLWKWKH

A Taste of Concurrency | 17

Download at WoweBook.Com
VDPHQDPHVZLWKSXEOLFUHDGHUPHWKRGVRIWKHVDPHQDPH7KDWLVZKHQ\RXLQVWDQ
WLDWHDPointLQVWDQFHHJpoint\RXFDQUHDGWKHILHOGVXVLQJpoint.xDQGpoint.y,I
\RXZDQWPXWDEOHILHOGVWKHQXVHWKHNH\ZRUGvar:H¦OOH[SORUHYDULDEOHGHFODUDWLRQV
DQGWKHvalDQGvarNH\ZRUGVLQ£9DULDEOH'HFODUDWLRQV¤RQSDJH
7KHERG\RIPointGHILQHVRQHPHWKRGDQRYHUULGHRIWKHIDPLOLDUtoStringPHWKRGLQ
-DYD OLNH ToStringLQ& 1RWHWKDW6FDODOLNH&UHTXLUHVWKH overrideNH\ZRUG
ZKHQHYHU \RX RYHUULGH D FRQFUHWH PHWKRG 8QOLNH & \RX GRQ¦W KDYH WR XVH D
virtualNH\ZRUGRQWKHRULJLQDOFRQFUHWHPHWKRG,QIDFWWKHUHLVQRvirtualNH\ZRUG
LQ6FDOD$VEHIRUHZHRPLWWKHFXUO\EUDFHV {...} DURXQGWKHERG\RItoStringVLQFH
LWKDVRQO\RQHH[SUHVVLRQ
ShapeLVDQDEVWUDFWFODVV$EVWUDFWFODVVHVLQ6FDODDUHVLPLODUWRWKRVHLQ-DYDDQG&
:HFDQ¦WLQVWDQWLDWHLQVWDQFHVRIDEVWUDFWFODVVHVHYHQZKHQDOOWKHLUILHOGDQGPHWKRG
PHPEHUVDUHFRQFUHWH
,QWKLVFDVH6KDSHGHFODUHVDQDEVWUDFWdrawPHWKRG:HNQRZLWLVDEVWUDFWEHFDXVHLW
KDVQRERG\1R abstractNH\ZRUGLVUHTXLUHGRQWKHPHWKRG$EVWUDFWPHWKRGVLQ
6FDOD DUH MXVW OLNH DEVWUDFW PHWKRGV LQ -DYD DQG & 6HH £2YHUULGLQJ 0HPEHUV RI
&ODVVHVDQG7UDLWV¤RQSDJHIRUPRUHGHWDLOV
7KHdrawPHWKRGUHWXUQVUnitZKLFKLVDW\SHWKDWLVURXJKO\HTXLYDOHQWWRvoidLQ&
GHULYHGODQJXDJHVOLNH-DYDHWF 6HH£7KH6FDOD7\SH+LHUDUFK\¤RQSDJHIRUPRUH
GHWDLOV
CircleLVGHFODUHGDVDFRQFUHWHVXEFODVVRIShape,WGHILQHVWKHdrawPHWKRGWRVLPSO\
SULQWDPHVVDJHWRWKHFRQVROHCircleDOVRRYHUULGHVtoString
Rectangle LV DOVR D FRQFUHWH VXEFODVV RI Shape WKDW GHILQHV draw DQG RYHUULGHV
toString)RUVLPSOLFLW\ZHDVVXPHLWLVQRWURWDWHGUHODWLYHWRWKH[DQG\D[HV+HQFH
DOOZHQHHGLVRQHSRLQWWKHORZHUOHIWKDQGSRLQWZLOOGRDQGWKHKHLJKWDQGZLGWKRI
WKHUHFWDQJOH
TriangleIROORZVWKHVDPHSDWWHUQ,WWDNHVWKUHHPointsDVLWVFRQVWUXFWRUDUJXPHQWV
%RWK drawPHWKRGVLQ Circle RectangleDQG TriangleXVH this$VLQ-DYDDQG&
thisLVKRZDQLQVWDQFHUHIHUVWRLWVHOI,QWKLVFRQWH[WZKHUHthisLVWKHULJKWKDQGVLGH
RID6WULQJFRQFDWHQDWLRQH[SUHVVLRQ XVLQJWKHSOXVVLJQ  this.toStringLVLQYRNHG
LPSOLFLWO\

2IFRXUVHLQDUHDODSSOLFDWLRQ\RXZRXOGQRWLPSOHPHQWGUDZLQJLQ
£GRPDLQPRGHO¤FODVVHVOLNHWKLVVLQFHWKHLPSOHPHQWDWLRQVZRXOGGH
SHQGRQGHWDLOVOLNHWKHRSHUDWLQJV\VWHPSODWIRUPJUDSKLFV$3,HWF
:HZLOOVHHDEHWWHUGHVLJQDSSURDFKZKHQZHGLVFXVVWUDLWVLQ&KDSWHU

1RZWKDWZHKDYHGHILQHGRXUVKDSHVW\SHVOHW¦VUHWXUQWR$FWRUV:HGHILQHDQ$FWRU
WKDWUHFHLYHV£PHVVDJHV¤WKDWDUHVKDSHVWRGUDZ

18 | Chapter 1:—Zero to Sixty: Introducing Scala

Download at WoweBook.Com
// code-examples/IntroducingScala/shapes-actor.scala

package shapes {
import scala.actors._
import scala.actors.Actor._

object ShapeDrawingActor extends Actor {


def act() {
loop {
receive {
case s: Shape => s.draw()
case "exit" => println("exiting..."); exit
case x: Any => println("Error: Unknown message! " + x)
}
}
}
}
}

7KH $FWRU LV GHFODUHG WR EH SDUW RI WKH shapes SDFNDJH 1H[W ZH KDYH WZR LPSRUW
VWDWHPHQWV
7KHILUVWLPSRUWVWDWHPHQWLPSRUWVDOOWKHW\SHVLQWKHscala.actorsSDFNDJH,Q6FDOD
WKHXQGHUVFRUH_LVXVHGWKHZD\WKHVWDU*LVXVHGLQ-DYD

%HFDXVH*LVDYDOLGFKDUDFWHUIRUDIXQFWLRQQDPHLWFDQ¦WEHXVHGDVWKH
importZLOGFDUG,QVWHDG_LVUHVHUYHGIRUWKLVSXUSRVH

$OOWKHPHWKRGVDQGSXEOLFILHOGVIURPActorDUHLPSRUWHGE\WKHVHFRQGimport7KHVH
DUHQRWstaticLPSRUWVIURPWKHActorW\SHDVWKH\ZRXOGEHLQ-DYD5DWKHUWKH\DUH
LPSRUWHGIURPDQobjectWKDWLVDOVRQDPHGActor7KHclassDQGobjectFDQKDYHWKH
VDPHQDPHDVZHZLOOVHHLQ£&RPSDQLRQ2EMHFWV¤RQSDJH
2XU$FWRUFODVVGHILQLWLRQShapeDrawingActorLVDQobjectWKDWH[WHQGVActor WKHW\SH
QRWWKH object 7KH actPHWKRGLVRYHUULGGHQWRGRWKHXQLTXHZRUNRIWKH$FWRU
%HFDXVH act LV DQ DEVWUDFW PHWKRG ZH GRQ¦W QHHG WR H[SOLFLWO\ RYHUULGH LW ZLWK WKH
overrideNH\ZRUG2XU$FWRUORRSVLQGHILQLWHO\ZDLWLQJIRULQFRPLQJPHVVDJHV
'XULQJHDFKSDVVLQWKHORRSWKHreceivePHWKRGLVFDOOHG,WEORFNVXQWLODQHZPHVVDJH
DUULYHV:K\LVWKHFRGHDIWHUreceiveHQFORVHGLQFXUO\EUDFHV{...}DQGQRWSDUHQWKHVHV
(...)":HZLOOOHDUQODWHUWKDWWKHUHDUHFDVHVZKHUHWKLVVXEVWLWXWLRQLVDOORZHGDQGLV
TXLWHXVHIXO VHH&KDSWHU )RUQRZZKDW\RXQHHGWRNQRZLVWKDWWKHH[SUHVVLRQV
LQVLGHWKHEUDFHVFRQVWLWXWHDVLQJOHIXQFWLRQOLWHUDOWKDWLVSDVVHGWRreceive7KLVIXQF
WLRQOLWHUDOGRHVDSDWWHUQPDWFKRQWKHPHVVDJHLQVWDQFHWRGHFLGHKRZWRKDQGOHWKH
PHVVDJH%HFDXVHRIWKH caseFODXVHVLWORRNVOLNHDW\SLFDOVZLWFKVWDWHPHQWLQ-DYD
IRUH[DPSOHDQGWKHEHKDYLRULVYHU\VLPLODU

A Taste of Concurrency | 19

Download at WoweBook.Com
7KHILUVWcaseGRHVDW\SHFRPSDULVRQZLWKWKHPHVVDJH 7KHUHLVQRH[SOLFLWYDULDEOH
IRUWKHPHVVDJHLQVWDQFHLQWKHFRGHLWLVLQIHUUHG ,IWKHPHVVDJHLVRIW\SHShapeWKH
ILUVWcasePDWFKHV7KHPHVVDJHLQVWDQFHLVFDVWWRDShapeDQGDVVLJQHGWRWKHYDULDEOH
sDQGWKHQWKHdrawPHWKRGLVFDOOHGRQLW
,I WKH PHVVDJH LV QRW D Shape WKH VHFRQG case LV WULHG ,I WKH PHVVDJH LV WKH VWULQJ
"exit"WKH$FWRUSULQWVDPHVVDJHDQGWHUPLQDWHVH[HFXWLRQ$FWRUVVKRXOGXVXDOO\
KDYHDZD\WRH[LWJUDFHIXOO\
7KHODVW caseFODXVHKDQGOHVDQ\RWKHUPHVVDJHLQVWDQFHWKHUHE\IXQFWLRQLQJDVWKH
GHIDXOWFDVH7KH$FWRUUHSRUWVDQHUURUDQGWKHQGURSVWKHPHVVDJHAnyLVWKHSDUHQW
RIDOOW\SHVLQWKH6FDODW\SHKLHUDUFK\OLNH ObjectLVWKHURRWW\SHLQ-DYDDQGRWKHU
ODQJXDJHV+HQFHWKLVFDVHFODXVHZLOOPDWFKDQ\PHVVDJHRIDQ\W\SH3DWWHUQPDWFKLQJ
LVHDJHUZHKDYHWRSXWWKLVFDVHFODXVHDWWKHHQGVRLWGRHVQ¦WFRQVXPHWKHPHVVDJHV
ZHDUHH[SHFWLQJ
5HFDOO WKDW ZH GHFODUHG draw DV DQ DEVWUDFW PHWKRG LQ Shape DQG ZH LPSOHPHQWHG
drawLQWKHFRQFUHWHVXEFODVVHV+HQFHWKHFRGHLQWKHILUVW caseVWDWHPHQWLQYRNHVD
SRO\PRUSKLFRSHUDWLRQ

Pattern Matching Versus Polymorphism


3DWWHUQPDWFKLQJSOD\VDFHQWUDOUROHLQIXQFWLRQDOSURJUDPPLQJMXVWDVSRO\PRUSKLVP
SOD\VDFHQWUDOUROHLQREMHFWRULHQWHGSURJUDPPLQJ)XQFWLRQDOSDWWHUQPDWFKLQJLV
PXFK PRUH LPSRUWDQW DQG VRSKLVWLFDWHG WKDQ WKH FRUUHVSRQGLQJ switch/case VWDWH
PHQWVIRXQGLQPRVWLPSHUDWLYHODQJXDJHVOLNH-DYD:HZLOOH[DPLQH6FDOD¦VVXSSRUW
IRUSDWWHUQPDWFKLQJLQPRUHGHWDLOLQ&KDSWHU,QRXUH[DPSOHKHUHZHFDQEHJLQWR
VHHWKDWMRLQLQJIXQFWLRQDOVW\OHSDWWHUQPDWFKLQJZLWKREMHFWRULHQWHGSRO\PRUSKLF
GLVSDWFKLQJLVDSRZHUIXOFRPELQDWLRQWKDWLVDEHQHILWRIPL[HGSDUDGLJPODQJXDJHV
OLNH6FDOD

)LQDOO\KHUHLVDVFULSWWKDWXVHVWKHShapeDrawingActor$FWRU
// code-examples/IntroducingScala/shapes-actor-script.scala

import shapes._

ShapeDrawingActor.start()

ShapeDrawingActor ! new Circle(new Point(0.0,0.0), 1.0)


ShapeDrawingActor ! new Rectangle(new Point(0.0,0.0), 2, 5)
ShapeDrawingActor ! new Triangle(new Point(0.0,0.0),
new Point(1.0,0.0),
new Point(0.0,1.0))
ShapeDrawingActor ! 3.14159

ShapeDrawingActor ! "exit"

20 | Chapter 1:—Zero to Sixty: Introducing Scala

Download at WoweBook.Com
7KHVKDSHVLQWKHshapesSDFNDJHDUHLPSRUWHG
7KHShapeDrawingActor$FWRULVVWDUWHG%\GHIDXOWLWUXQVLQLWVRZQWKUHDG WKHUHDUH
DOWHUQDWLYHVZHZLOOGLVFXVVLQ&KDSWHU ZDLWLQJIRUPHVVDJHV
)LYHPHVVDJHVDUHVHQWWRWKH$FWRUXVLQJWKHV\QWD[actor ! message7KHILUVWPHVVDJH
VHQGVD CircleLQVWDQFH7KH$FWRU£GUDZV¤WKHFLUFOH7KHVHFRQGPHVVDJHVHQGVD
RectanglePHVVDJH7KH$FWRU£GUDZV¤WKHUHFWDQJOH7KHWKLUGPHVVDJHGRHVWKHVDPH
WKLQJIRUDTriangle7KHIRXUWKPHVVDJHVHQGVDDoubleWKDWLVDSSUR[LPDWHO\HTXDOWR
3L7KLVLVDQXQNQRZQPHVVDJHIRUWKH$FWRUVRLWMXVWSULQWVDQHUURUPHVVDJH7KH
ILQDOPHVVDJHVHQGVDQ£H[LW¤VWULQJZKLFKFDXVHVWKH$FWRUWRWHUPLQDWH
7R WU\ RXW WKH $FWRU H[DPSOH VWDUW E\ FRPSLOLQJ WKH ILUVW WZR ILOHV <RX FDQ JHW
WKH VRXUFHV IURP WKH 2¦5HLOO\ GRZQORDG VLWH VHH £*HWWLQJ WKH &RGH ([DP
SOHV¤RQSDJH[L[IRUGHWDLOV RU\RXFDQFUHDWHWKHP\RXUVHOI
8VHWKHIROORZLQJFRPPDQGWRFRPSLOHWKHILOHV
scalac shapes.scala shapes-actor.scala

:KLOHWKHVRXUFHILOHQDPHVDQGORFDWLRQVGRQ¦WKDYHWRPDWFKWKHILOHFRQWHQWV\RX
ZLOOQRWLFHWKDWWKHJHQHUDWHGFODVVILOHVDUHZULWWHQWRDVKDSHVGLUHFWRU\DQGWKHUHLV
RQHFODVVILOHIRUHDFKFODVVZHGHILQHG7KHFODVVILOHQDPHVDQGORFDWLRQVPXVWFRQIRUP
WRWKH-90UHTXLUHPHQWV
1RZ\RXFDQUXQWKHVFULSWWRVHHWKH$FWRULQDFWLRQ
scala -cp . shapes-actor-script.scala

<RXVKRXOGVHHWKHIROORZLQJRXWSXW
Circle.draw: Circle(Point(0.0,0.0),1.0)
Rectangle.draw: Rectangle(Point(0.0,0.0),2.0,5.0)
Triangle.draw: Triangle(Point(0.0,0.0),Point(1.0,0.0),Point(0.0,1.0))
Error: Unknown message! 3.14159
exiting...

)RUPRUHRQ$FWRUVVHH&KDSWHU

Recap and What’s Next


:HPDGHWKHFDVHIRU6FDODDQGJRW\RXVWDUWHGZLWKWZRVDPSOH6FDODSURJUDPVRQH
RIZKLFKJDYH\RXDWDVWHRI6FDOD¦V$FWRUVOLEUDU\IRUFRQFXUUHQF\1H[WZH¦OOGLYHLQWR
PRUH6FDODV\QWD[HPSKDVL]LQJYDULRXVNH\VWURNHHFRQRPLFDOZD\VRIJHWWLQJORWVRI
ZRUNGRQH

Recap and What’s Next | 21

Download at WoweBook.Com
Download at WoweBook.Com
CHAPTER 2
Type Less, Do More

In This Chapter
:HHQGHGWKHSUHYLRXVFKDSWHUZLWKDIHZ£WHDVHU¤H[DPSOHVRI6FDODFRGH7KLVFKDSWHU
GLVFXVVHVXVHVRI6FDODWKDWSURPRWHVXFFLQFWIOH[LEOHFRGH:H¦OOGLVFXVVRUJDQL]DWLRQ
RIILOHVDQGSDFNDJHVLPSRUWLQJRWKHUW\SHVYDULDEOHGHFODUDWLRQVPLVFHOODQHRXVV\Q
WD[FRQYHQWLRQVDQGDIHZRWKHUFRQFHSWV:H¦OOHPSKDVL]HKRZWKHFRQFLVHV\QWD[RI
6FDODKHOSV\RXZRUNEHWWHUDQGIDVWHU
6FDOD¦VV\QWD[LVHVSHFLDOO\XVHIXOZKHQZULWLQJVFULSWV6HSDUDWHFRPSLOHDQGUXQVWHSV
DUHQ¦WUHTXLUHGIRUVLPSOHSURJUDPVWKDWKDYHIHZGHSHQGHQFLHVRQOLEUDULHVRXWVLGHRI
ZKDW6FDODSURYLGHV<RXFRPSLOHDQGUXQVXFKSURJUDPVLQRQHVKRWZLWKWKH scala
FRPPDQG,I\RX¦YHGRZQORDGHGWKHH[DPSOHFRGHIRUWKLVERRNPDQ\RIWKHVPDOOHU
H[DPSOHVFDQEHUXQXVLQJWKH scalaFRPPDQGHJ scala filename.scala6HHWKH
5($'0(W[WILOHVLQHDFKFKDSWHU¦VFRGHH[DPSOHVIRUPRUHGHWDLOV6HHDOVR£&RP
PDQG/LQH7RROV¤RQSDJHIRUPRUHLQIRUPDWLRQDERXWXVLQJWKHscalaFRPPDQG

Semicolons
<RXPD\KDYHDOUHDG\QRWLFHGWKDWWKHUHZHUHYHU\IHZVHPLFRORQVLQWKHFRGHH[DPSOHV
LQWKHSUHYLRXVFKDSWHU<RXFDQXVHVHPLFRORQVWRVHSDUDWHVWDWHPHQWVDQGH[SUHV
VLRQVDVLQ-DYD&3+3DQGVLPLODUODQJXDJHV,QPRVWFDVHVWKRXJK6FDODEHKDYHV
OLNHPDQ\VFULSWLQJODQJXDJHVLQWUHDWLQJWKHHQGRIWKHOLQHDVWKHHQGRIDVWDWHPHQW
RUDQH[SUHVVLRQ:KHQDVWDWHPHQWRUH[SUHVVLRQLVWRRORQJIRURQHOLQH6FDODFDQ
XVXDOO\LQIHUZKHQ\RXDUHFRQWLQXLQJRQWRWKHQH[WOLQHDVVKRZQLQWKLVH[DPSOH
// code-examples/TypeLessDoMore/semicolon-example-script.scala

// Trailing equals sign indicates more code on next line


def equalsign = {
val reallySuperLongValueNameThatGoesOnForeverSoYouNeedANewLine =
"wow that was a long value name"

println(reallySuperLongValueNameThatGoesOnForeverSoYouNeedANewLine)

23

Download at WoweBook.Com
}

// Trailing opening curly brace indicates more code on next line


def equalsign2(s: String) = {
println("equalsign2: " + s)
}

// Trailing comma, operator, etc. indicates more code on next line


def commas(s1: String,
s2: String) = {
println("comma: " + s1 +
", " + s2)
}

:KHQ\RXZDQWWRSXWPXOWLSOHVWDWHPHQWVRUH[SUHVVLRQVRQWKHVDPHOLQH\RXFDQ
XVH VHPLFRORQV WR VHSDUDWH WKHP :H XVHG WKLV WHFKQLTXH LQ WKH ShapeDrawingActor
H[DPSOHLQ£$7DVWHRI&RQFXUUHQF\¤RQSDJH
case "exit" => println("exiting..."); exit

7KLVFRGHFRXOGDOVREHZULWWHQDVIROORZV
...
case "exit" =>
println("exiting...")
exit
...

<RXPLJKWZRQGHUZK\\RXGRQ¦WQHHGFXUO\EUDFHV {...} DURXQGWKHWZRVWDWHPHQWV


DIWHUWKH case ... =>OLQH<RXFDQSXWWKHPLQLI\RXZDQWEXWWKHFRPSLOHUNQRZV
ZKHQ\RX¦YHUHDFKHGWKHHQGRIWKH£EORFN¤ZKHQLWILQGVWKHQH[WcaseFODXVHRUWKH
FXUO\EUDFH } WKDWHQGVWKHHQFORVLQJEORFNIRUDOOWKHcaseFODXVHV
2PLWWLQJRSWLRQDOVHPLFRORQVPHDQVIHZHUFKDUDFWHUVWRW\SHDQGIHZHUFKDUDFWHUVWR
FOXWWHU\RXUFRGH%UHDNLQJVHSDUDWHVWDWHPHQWVRQWRWKHLURZQOLQHVLQFUHDVHV\RXU
FRGH¦VUHDGDELOLW\

Variable Declarations
6FDODDOORZV\RXWRGHFLGHZKHWKHUDYDULDEOHLVLPPXWDEOH UHDGRQO\ RUQRW UHDG
ZULWH  ZKHQ \RX GHFODUH LW $Q LPPXWDEOH £YDULDEOH¤ LV GHFODUHG ZLWK WKH NH\ZRUG
val WKLQNYDOXHREMHFW 
val array: Array[String] = new Array(5)

7R EH PRUH SUHFLVH WKH array UHIHUHQFH FDQQRW EH FKDQJHG WR SRLQW WR D GLIIHUHQW
ArrayEXWWKHDUUD\LWVHOIFDQEHPRGLILHGDVVKRZQLQWKHIROORZLQJscalaVHVVLRQ
scala> val array: Array[String] = new Array(5)
array: Array[String] = Array(null, null, null, null, null)

scala> array = new Array(2)


<console>:5: error: reassignment to val
array = new Array(2)

24 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
^

scala> array(0) = "Hello"

scala> array
res3: Array[String] = Array(Hello, null, null, null, null)

scala>

$QLPPXWDEOHvalPXVWEHLQLWLDOL]HG¢WKDWLVGHILQHG¢ZKHQLWLVGHFODUHG
$PXWDEOHYDULDEOHLVGHFODUHGZLWKWKHNH\ZRUGvar
scala> var stockPrice: Double = 100.
stockPrice: Double = 100.0

scala> stockPrice = 10.


stockPrice: Double = 10.0

scala>

6FDODDOVRUHTXLUHV\RXWRLQLWLDOL]HDvarZKHQLWLVGHFODUHG<RXFDQDVVLJQDQHZYDOXH
WRD varDVRIWHQDV\RXZDQW$JDLQWREHSUHFLVHWKH stockPriceUHIHUHQFHFDQEH
FKDQJHGWRSRLQWWRDGLIIHUHQW DoubleREMHFW HJ 10. ,QWKLVFDVHWKHREMHFWWKDW
stockPriceUHIHUVWRFDQ¦WEHFKDQJHGEHFDXVHDoublesLQ6FDODDUHLPPXWDEOH
7KHUHDUHDIHZH[FHSWLRQVWRWKHUXOHWKDW\RXPXVWLQLWLDOL]HvalVDQGvarVZKHQWKH\
DUHGHFODUHG%RWKNH\ZRUGVFDQEHXVHGZLWKFRQVWUXFWRUSDUDPHWHUV:KHQXVHGDV
FRQVWUXFWRUSDUDPHWHUVWKHPXWDEOHRULPPXWDEOHYDULDEOHVVSHFLILHGZLOOEHLQLWLDOL]HG
ZKHQDQREMHFWLVLQVWDQWLDWHG%RWKNH\ZRUGVFDQEHXVHGWRGHFODUH£DEVWUDFW¤ XQ
LQLWLDOL]HG YDULDEOHVLQDEVWUDFWW\SHV$OVRGHULYHGW\SHVFDQRYHUULGH valVGHFODUHG
LQVLGHSDUHQWW\SHV:H¦OOGLVFXVVWKHVHH[FHSWLRQVLQ&KDSWHU
6FDODHQFRXUDJHV\RXWRXVHLPPXWDEOHYDOXHVZKHQHYHUSRVVLEOH$VZHZLOOVHHWKLV
SURPRWHVEHWWHUREMHFWRULHQWHGGHVLJQDQGLVFRQVLVWHQWZLWKWKHSULQFLSOHVRI£SXUH¤
IXQFWLRQDOSURJUDPPLQJ,WPD\WDNHVRPHJHWWLQJXVHGWREXW\RX¦OOILQGDQHZIRXQG
FRQILGHQFHLQ\RXUFRGHZKHQLWLVZULWWHQLQDQLPPXWDEOHVW\OH

7KH varDQG valNH\ZRUGVRQO\VSHFLI\ZKHWKHUWKHUHIHUHQFHFDQEH


FKDQJHGWRUHIHUWRDGLIIHUHQWREMHFW var RUQRW val 7KH\GRQ¦WVSHF
LI\ZKHWKHURUQRWWKHREMHFWWKH\UHIHUHQFHLVPXWDEOH

Method Declarations
,Q&KDSWHUZHVDZVHYHUDOH[DPSOHVRIKRZWRGHILQHPHWKRGVZKLFKDUHIXQFWLRQV
WKDWDUHPHPEHUVRIDFODVV0HWKRGGHILQLWLRQVVWDUWZLWKWKH defNH\ZRUGIROORZHG
E\RSWLRQDODUJXPHQWOLVWVDFRORQFKDUDFWHU : DQGWKHUHWXUQW\SHRIWKHPHWKRGDQ
HTXDOVVLJQ = DQGILQDOO\WKHPHWKRGERG\0HWKRGVDUHLPSOLFLWO\GHFODUHG£DEVWUDFW¤

Method Declarations | 25

Download at WoweBook.Com
LI \RX OHDYH RII WKH HTXDOV VLJQ DQG PHWKRG ERG\ 7KH HQFORVLQJ W\SH LV WKHQ LWVHOI
DEVWUDFW:H¦OOGLVFXVVDEVWUDFWW\SHVLQPRUHGHWDLOLQ&KDSWHU
:HVDLG£RSWLRQDODUJXPHQWOLVWV¤PHDQLQJPRUHWKDQRQH6FDODOHWV\RXGHILQHPRUH
WKDQRQHDUJXPHQWOLVWIRUDPHWKRG7KLVLVUHTXLUHGIRUFXUU\LQJPHWKRGVZKLFKZH¦OO
GLVFXVVLQ£&XUU\LQJ¤RQSDJH,WLVDOVRYHU\XVHIXOIRUGHILQLQJ\RXURZQ'RPDLQ
6SHFLILF/DQJXDJHV '6/V DVZH¦OOVHHLQ&KDSWHU1RWHWKDWHDFKDUJXPHQWOLVWLV
VXUURXQGHGE\SDUHQWKHVHVDQGWKHDUJXPHQWVDUHVHSDUDWHGE\FRPPDV
,IDPHWKRGERG\KDVPRUHWKDQRQHH[SUHVVLRQ\RXPXVWVXUURXQGLWZLWKFXUO\EUDFHV
{...} <RXFDQRPLWWKHEUDFHVLIWKHPHWKRGERG\KDVMXVWRQHH[SUHVVLRQ

Method Default and Named Arguments (Scala Version 2.8)


0DQ\ ODQJXDJHV OHW \RX GHILQH GHIDXOW YDOXHV IRU VRPH RU DOO RI WKH DUJXPHQWV WR D
PHWKRG&RQVLGHUWKHIROORZLQJVFULSWZLWKDStringUtilREMHFWWKDWOHWV\RXMRLQDOLVW
RIVWULQJVZLWKDXVHUVSHFLILHGVHSDUDWRU
// code-examples/TypeLessDoMore/string-util-v1-script.scala
// Version 1 of "StringUtil".

object StringUtil {
def joiner(strings: List[String], separator: String): String =
strings.mkString(separator)

def joiner(strings: List[String]): String = joiner(strings, " ")


}
import StringUtil._ // Import the joiner methods.

println( joiner(List("Programming", "Scala")) )

7KHUHDUHDFWXDOO\WZR£RYHUORDGHG¤ joinerPHWKRGV7KHVHFRQGRQHXVHVDVLQJOH
VSDFHDVWKH£GHIDXOW¤VHSDUDWRU+DYLQJWZRPHWKRGVVHHPVDELWZDVWHIXO,WZRXOG
EH QLFH LI ZH FRXOG HOLPLQDWH WKH VHFRQG joiner PHWKRG DQG GHFODUH WKDW WKH
separatorDUJXPHQWLQWKHILUVWjoinerKDVDGHIDXOWYDOXH,QIDFWLQ6FDODYHUVLRQ
\RXFDQQRZGRWKLV
// code-examples/TypeLessDoMore/string-util-v2-v28-script.scala
// Version 2 of "StringUtil" for Scala v2.8 only.

object StringUtil {
def joiner(strings: List[String], separator: String = " "): String =
strings.mkString(separator)
}
import StringUtil._ // Import the joiner methods.

println(joiner(List("Programming", "Scala")))

7KHUHLVDQRWKHUDOWHUQDWLYHIRUHDUOLHUYHUVLRQVRI6FDOD<RXFDQXVHLPSOLFLWDUJXPHQWV
ZKLFKZHZLOOGLVFXVVLQ£,PSOLFLW)XQFWLRQ3DUDPHWHUV¤RQSDJH

26 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
6FDODYHUVLRQRIIHUVDQRWKHUHQKDQFHPHQWIRUPHWKRGDUJXPHQWOLVWVQDPHGDUJX
PHQWV:HFRXOGDFWXDOO\ZULWHWKHODVWOLQHRIWKHSUHYLRXVH[DPSOHLQVHYHUDOZD\V
$OORIWKHIROORZLQJprintlnVWDWHPHQWVDUHIXQFWLRQDOO\HTXLYDOHQW
println(joiner(List("Programming", "Scala")))
println(joiner(strings = List("Programming", "Scala")))
println(joiner(List("Programming", "Scala"), " ")) // #1
println(joiner(List("Programming", "Scala"), separator = " ")) // #2
println(joiner(strings = List("Programming", "Scala"), separator = " "))

:K\LVWKLVXVHIXO")LUVWLI\RXFKRRVHJRRGQDPHVIRUWKHPHWKRGDUJXPHQWVWKHQ
\RXUFDOOVWRWKRVHPHWKRGVGRFXPHQWHDFKDUJXPHQWZLWKDQDPH)RUH[DPSOHFRP
SDUHWKHWZROLQHVZLWKFRPPHQWVDQG,QWKHILUVWOLQHLWPD\QRWEHREYLRXV
ZKDW WKH VHFRQG " " DUJXPHQW LV IRU ,Q WKH VHFRQG FDVH ZH VXSSO\ WKH QDPH
separatorZKLFKVXJJHVWVWKHSXUSRVHRIWKHDUJXPHQW
7KHVHFRQGEHQHILWLVWKDW\RXFDQVSHFLI\WKHSDUDPHWHUVLQDQ\RUGHUZKHQ\RXVSHFLI\
WKHPE\QDPH&RPELQHGZLWKGHIDXOWYDOXHV\RXFDQZULWHFRGHOLNHWKHIROORZLQJ
// code-examples/TypeLessDoMore/user-profile-v28-script.scala
// Scala v2.8 only.

object OptionalUserProfileInfo {
val UnknownLocation = ""
val UnknownAge = -1
val UnknownWebSite = ""
}

class OptionalUserProfileInfo(
location: String = OptionalUserProfileInfo.UnknownLocation,
age: Int = OptionalUserProfileInfo.UnknownAge,
webSite: String = OptionalUserProfileInfo.UnknownWebSite)

println( new OptionalUserProfileInfo )


println( new OptionalUserProfileInfo(age = 29) )
println( new OptionalUserProfileInfo(age = 29, location="Earth") )

OptionalUserProfileInfoUHSUHVHQWVDOOWKH£RSWLRQDO¤XVHUSURILOHGDWDLQ\RXUQH[W
:HEVRFLDOQHWZRUNLQJVLWH,WGHILQHVGHIDXOWYDOXHVIRUDOOLWVILHOGV7KHVFULSW
FUHDWHVLQVWDQFHVZLWK]HURRUPRUHQDPHGSDUDPHWHUV7KHRUGHURIWKRVHSDUDPHWHUV
LVDUELWUDU\
7KHH[DPSOHVZHKDYHVKRZQXVHFRQVWDQWYDOXHVDVWKHGHIDXOWV0RVWODQJXDJHVZLWK
GHIDXOWDUJXPHQWYDOXHVRQO\DOORZFRQVWDQWVRURWKHUYDOXHVWKDWFDQEHGHWHUPLQHG
DWSDUVHWLPH+RZHYHULQ6FDODDQ\H[SUHVVLRQFDQEHXVHGDVWKHGHIDXOWDVORQJDV
LWFDQFRPSLOHZKHUHXVHG)RUH[DPSOHDQH[SUHVVLRQFRXOGQRWUHIHUWRDQLQVWDQFH
ILHOGWKDWZLOOEHFRPSXWHGLQVLGHWKHFODVVRUREMHFWERG\EXWLWFRXOGLQYRNHDPHWKRG
RQDVLQJOHWRQREMHFW
$UHODWHGOLPLWDWLRQLVWKDWDGHIDXOWH[SUHVVLRQIRURQHSDUDPHWHUFDQ¦WUHIHUWRDQRWKHU
SDUDPHWHULQWKHOLVWXQOHVVWKHSDUDPHWHUWKDWLVUHIHUHQFHGDSSHDUVHDUOLHULQWKHOLVW
DQGWKHSDUDPHWHUVDUHFXUULHGDFRQFHSWZH¦OOGLVFXVVLQ£&XUU\LQJ¤RQSDJH

Method Declarations | 27

Download at WoweBook.Com
)LQDOO\DQRWKHUFRQVWUDLQWRQQDPHGSDUDPHWHUVLVWKDWRQFH\RXSURYLGHDQDPHIRU
DSDUDPHWHULQDPHWKRGLQYRFDWLRQWKHUHVWRIWKHSDUDPHWHUVDSSHDULQJDIWHULWPXVW
DOVREHQDPHG)RUH[DPSOHnew OptionalUserProfileInfo(age = 29, "Earth")ZRXOG
QRWFRPSLOHEHFDXVHWKHVHFRQGDUJXPHQWLVQRWLQYRNHGE\QDPH
:H¦OOVHHDQRWKHUXVHIXOH[DPSOHRIQDPHGDQGGHIDXOWDUJXPHQWVZKHQZHGLVFXVV
FDVHFODVVHVLQ£&DVH&ODVVHV¤RQSDJH

Nesting Method Definitions


0HWKRGGHILQLWLRQVFDQDOVREHQHVWHG+HUHLVDQLPSOHPHQWDWLRQRIDIDFWRULDOFDOFX
ODWRUZKHUHZHXVHDFRQYHQWLRQDOWHFKQLTXHRIFDOOLQJDVHFRQGQHVWHGPHWKRGWRGR
WKHZRUN
// code-examples/TypeLessDoMore/factorial-script.scala

def factorial(i: Int): Int = {


def fact(i: Int, accumulator: Int): Int = {
if (i <= 1)
accumulator
else
fact(i - 1, i * accumulator)
}

fact(i, 1)
}

println( factorial(0) )
println( factorial(1) )
println( factorial(2) )
println( factorial(3) )
println( factorial(4) )
println( factorial(5) )

7KHVHFRQGPHWKRGFDOOVLWVHOIUHFXUVLYHO\SDVVLQJDQ accumulatorSDUDPHWHUZKHUH
WKHUHVXOWRIWKHFDOFXODWLRQLV£DFFXPXODWHG¤1RWHWKDWZHUHWXUQWKHDFFXPXODWHG
YDOXH ZKHQ WKH FRXQWHU i UHDFKHV  :H¦UH LJQRULQJ LQYDOLG QHJDWLYH LQWHJHUV 7KH
IXQFWLRQ DFWXDOO\ UHWXUQV  IRU i < 0  $IWHU WKH GHILQLWLRQ RI WKH QHVWHG PHWKRG
factorialFDOOVLWZLWKWKHSDVVHGLQYDOXHiDQGWKHLQLWLDODFFXPXODWRUYDOXHRI
/LNHDORFDOYDULDEOHGHFODUDWLRQLQPDQ\ODQJXDJHVDQHVWHGPHWKRGLVRQO\YLVLEOH
LQVLGHWKHHQFORVLQJPHWKRG,I\RXWU\WRFDOOfactRXWVLGHRIfactorial\RXZLOOJHWD
FRPSLOHUHUURU
'LG\RXQRWLFHWKDWZHXVHiDVDSDUDPHWHUQDPHWZLFHILUVWLQWKHfactorialPHWKRG
DQGDJDLQLQWKHQHVWHGfactPHWKRG"$VLQPDQ\ODQJXDJHVWKHXVHRIiDVDSDUDPHWHU
QDPHIRUfact£VKDGRZV¤WKHRXWHUXVHRIiDVDSDUDPHWHUQDPHIRUfactorial7KLVLV
ILQHEHFDXVHZHGRQ¦WQHHGWKHRXWHUYDOXHRI iLQVLGH fact:HRQO\XVHLWWKHILUVW
WLPHZHFDOOfactDWWKHHQGRIfactorial

28 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
:KDWLIZHQHHGWRXVHDYDULDEOHWKDWLVGHILQHGRXWVLGHDQHVWHGIXQFWLRQ"&RQVLGHU
WKLVFRQWULYHGH[DPSOH
// code-examples/TypeLessDoMore/count-to-script.scala

def countTo(n: Int):Unit = {


def count(i: Int): Unit = {
if (i <= n) {
println(i)
count(i + 1)
}
}
count(1)
}

countTo(5)

1RWHWKDWWKHQHVWHG countPHWKRGXVHVWKH nYDOXHWKDWLVSDVVHGDVDSDUDPHWHUWR


countTo7KHUHLVQRQHHGWRSDVV nDVDQDUJXPHQWWR count%HFDXVH countLVQHVWHG
LQVLGHcountTonLVYLVLEOHWRLW
7KHGHFODUDWLRQRIDILHOG PHPEHUYDULDEOH FDQEHSUHIL[HGZLWKNH\ZRUGVLQGLFDWLQJ
WKHYLVLELOLW\MXVWDVLQODQJXDJHVOLNH-DYDDQG&6LPLODUO\WKHGHFODUDWLRQRIDQRQ
QHVWHGPHWKRGFDQEHSUHIL[HGZLWKWKHVDPHNH\ZRUGV:HZLOOGLVFXVVWKHYLVLELOLW\
UXOHVDQGNH\ZRUGVLQ£9LVLELOLW\5XOHV¤RQSDJH

Inferring Type Information


6WDWLFDOO\W\SHGODQJXDJHVFDQEHYHU\YHUERVH&RQVLGHUWKLVW\SLFDOGHFODUDWLRQLQ-DYD
import java.util.Map;
import java.util.HashMap;
...
Map<Integer, String> intToStringMap = new HashMap<Integer, String>();

:HKDYHWRVSHFLI\WKHW\SHSDUDPHWHUV<Integer, String>WZLFH 6FDODXVHVWKHWHUP


W\SHDQQRWDWLRQVIRUH[SOLFLWW\SHGHFODUDWLRQVOLNHHashMap<Integer, String>
6FDODVXSSRUWVW\SHLQIHUHQFH VHHIRUH[DPSOH>7\SH,QIHUHQFH@DQG>3LHUFH@ 7KH
ODQJXDJH¦VFRPSLOHUFDQGLVFHUQTXLWHDELWRIW\SHLQIRUPDWLRQIURPWKHFRQWH[WZLWK
RXWH[SOLFLWW\SHDQQRWDWLRQV+HUH¦VWKHVDPHGHFODUDWLRQUHZULWWHQLQ6FDODZLWKLQ
IHUUHGW\SHLQIRUPDWLRQ
import java.util.Map
import java.util.HashMap
...
val intToStringMap: Map[Integer, String] = new HashMap

5HFDOOIURP&KDSWHUWKDW6FDODXVHVVTXDUHEUDFNHWV [...] IRUJHQHULFW\SHSDUDP


HWHUV:HVSHFLI\Map[Integer, String]RQWKHOHIWKDQGVLGHRIWKHHTXDOVVLJQ :HDUH
VWLFNLQJZLWK-DYDW\SHVIRUWKHH[DPSOH 2QWKHULJKWKDQGVLGHZHLQVWDQWLDWHWKH
DFWXDOW\SHZHZDQWDHashMapEXWZHGRQ¦WKDYHWRUHSHDWWKHW\SHSDUDPHWHUV

Inferring Type Information | 29

Download at WoweBook.Com
)RUFRPSOHWHQHVVVXSSRVHZHGRQ¦WDFWXDOO\FDUHLIWKHLQVWDQFHLVRIW\SHMap WKH-DYD
LQWHUIDFHW\SH ,WFDQEHRIW\SHHashMapIRUDOOZHFDUH
import java.util.Map
import java.util.HashMap
...
val intToStringMap2 = new HashMap[Integer, String]

7KLVGHFODUDWLRQUHTXLUHVQRW\SHDQQRWDWLRQVRQWKHOHIWKDQGVLGHEHFDXVHDOORIWKH
W\SHLQIRUPDWLRQQHHGHGLVRQWKHULJKWKDQGVLGH7KHFRPSLOHUDXWRPDWLFDOO\PDNHV
intToStringMap2DHashMap[Integer,String]
7\SHLQIHUHQFHLVXVHGIRUPHWKRGVWRR,QPRVWFDVHVWKHUHWXUQW\SHRIWKHPHWKRG
FDQEHLQIHUUHGVRWKH :DQGUHWXUQW\SHFDQEHRPLWWHG+RZHYHUW\SHDQQRWDWLRQV
DUHUHTXLUHGIRUDOOPHWKRGSDUDPHWHUV
3XUHIXQFWLRQDOODQJXDJHVOLNH+DVNHOO VHHHJ>2¦6XOOLYDQ@ XVHW\SHLQIHUHQFH
DOJRULWKPVOLNH+LQGOH\0LOQHU VHH>6SLHZDN@IRUDQHDVLO\GLJHVWHGH[SODQDWLRQ 
&RGHZULWWHQLQWKHVHODQJXDJHVUHTXLUHW\SHDQQRWDWLRQVOHVVRIWHQWKDQLQ6FDODEH
FDXVH6FDOD¦VW\SHLQIHUHQFHDOJRULWKPKDVWRVXSSRUWREMHFWRULHQWHGW\SLQJDVZHOODV
IXQFWLRQDOW\SLQJ6R6FDODUHTXLUHVPRUHW\SHDQQRWDWLRQVWKDQODQJXDJHVOLNH+DVNHOO
+HUHLVDVXPPDU\RIWKHUXOHVIRUZKHQH[SOLFLWW\SHDQQRWDWLRQVDUHUHTXLUHGLQ6FDOD

When Explicit Type Annotations Are Required


,Q SUDFWLFDO WHUPV \RX KDYH WR SURYLGH H[SOLFLW W\SH DQQRWDWLRQV IRU WKH IROORZLQJ
VLWXDWLRQV
 $YDULDEOHGHFODUDWLRQXQOHVV\RXDVVLJQDYDOXHWRWKHYDULDEOH HJ val name =
"Programming Scala"
 $OOPHWKRGSDUDPHWHUV HJdef deposit(amount: Money)...
 0HWKRGUHWXUQYDOXHVLQWKHIROORZLQJFDVHV
D :KHQ\RXH[SOLFLWO\FDOOreturnLQDPHWKRG HYHQDWWKHHQG
E :KHQDPHWKRGLVUHFXUVLYH
F :KHQ D PHWKRG LV RYHUORDGHG DQG RQH RI WKH PHWKRGV FDOOV DQRWKHU WKH
FDOOLQJPHWKRGQHHGVDUHWXUQW\SHDQQRWDWLRQ
G :KHQWKHLQIHUUHGUHWXUQW\SHZRXOGEHPRUHJHQHUDOWKDQ\RXLQWHQGHGHJ
Any

7KHAnyW\SHLVWKHURRWRIWKH6FDODW\SHKLHUDUFK\ VHH£7KH6FDOD7\SH
+LHUDUFK\¤RQSDJHIRUPRUHGHWDLOV ,IDEORFNRIFRGHUHWXUQVD
YDOXHRIW\SHAnyXQH[SHFWHGO\FKDQFHVDUHJRRGWKDWWKHW\SHLQIHUHQFHU
FRXOGQ¦WILJXUHRXWZKDWW\SHWRUHWXUQVRLWFKRVHWKHPRVWJHQHULFW\SH
SRVVLEOH

30 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
/HW¦VORRNDWH[DPSOHVZKHUHH[SOLFLWGHFODUDWLRQVRIPHWKRGUHWXUQW\SHVDUHUHTXLUHG
,QWKHIROORZLQJVFULSWWKHupCasePHWKRGKDVDFRQGLWLRQDOUHWXUQVWDWHPHQWIRU]HUR
OHQJWKVWULQJV
// code-examples/TypeLessDoMore/method-nested-return-script.scala
// ERROR: Won't compile until you put a String return type on upCase.

def upCase(s: String) = {


if (s.length == 0)
return s
else
s.toUpperCase()
}

println( upCase("") )
println( upCase("Hello") )

5XQQLQJWKLVVFULSWJLYHV\RXWKHIROORZLQJHUURU
... 6: error: method upCase has return statement; needs result type
return s
^

<RXFDQIL[WKLVHUURUE\FKDQJLQJWKHILUVWOLQHRIWKHPHWKRGWRWKHIROORZLQJ
def upCase(s: String): String = {

$FWXDOO\IRUWKLVSDUWLFXODUVFULSWDQDOWHUQDWLYHIL[LVWRUHPRYHWKH returnNH\ZRUG
IURPWKHOLQH,WLVQRWQHHGHGIRUWKHFRGHWRZRUNSURSHUO\EXWLWLOOXVWUDWHVRXUSRLQW
5HFXUVLYHPHWKRGVDOVRUHTXLUHDQH[SOLFLWUHWXUQW\SH5HFDOORXU factorialPHWKRG
LQ£1HVWLQJ0HWKRG'HILQLWLRQV¤RQSDJH/HW¦VUHPRYHWKH: IntUHWXUQW\SHRQWKH
QHVWHGfactPHWKRG
// code-examples/TypeLessDoMore/method-recursive-return-script.scala
// ERROR: Won't compile until you put an Int return type on "fact".

def factorial(i: Int) = {


def fact(i: Int, accumulator: Int) = {
if (i <= 1)
accumulator
else
fact(i - 1, i * accumulator)
}

fact(i, 1)
}

1RZLWIDLOVWRFRPSLOH
... 9: error: recursive method fact needs result type
fact(i - 1, i * accumulator)
^

Inferring Type Information | 31

Download at WoweBook.Com
2YHUORDGHGPHWKRGVFDQVRPHWLPHVUHTXLUHDQH[SOLFLWUHWXUQW\SH:KHQRQHVXFK
PHWKRGFDOOVDQRWKHUZHKDYHWRDGGDUHWXUQW\SHWRWKHRQHGRLQJWKHFDOOLQJDVLQ
WKLVH[DPSOH
// code-examples/TypeLessDoMore/method-overloaded-return-script.scala
// Version 1 of "StringUtil" (with a compilation error).
// ERROR: Won't compile: needs a String return type on the second "joiner".

object StringUtil {
def joiner(strings: List[String], separator: String): String =
strings.mkString(separator)

def joiner(strings: List[String]) = joiner(strings, " ")


}
import StringUtil._ // Import the joiner methods.

println( joiner(List("Programming", "Scala")) )

7KHWZRjoinerPHWKRGVFRQFDWHQDWHDListRIVWULQJVWRJHWKHU7KHILUVWPHWKRGDOVR
WDNHVDQDUJXPHQWIRUWKHVHSDUDWRUVWULQJ7KHVHFRQGPHWKRGFDOOVWKHILUVWZLWKD
£GHIDXOW¤VHSDUDWRURIDVLQJOHVSDFH
,I\RXUXQWKLVVFULSW\RXJHWWKHIROORZLQJHUURU
... 9: error: overloaded method joiner needs result type
def joiner(strings: List[String]) = joiner(strings, "")
^

6LQFHWKHVHFRQGjoinerPHWKRGFDOOVWKHILUVWLWUHTXLUHVDQH[SOLFLWStringUHWXUQW\SH
,WVKRXOGORRNOLNHWKLV
def joiner(strings: List[String]): String = joiner(strings, " ")

7KHILQDOVFHQDULRFDQEHVXEWOHZKHQDPRUHJHQHUDOUHWXUQW\SHLVLQIHUUHGWKDQZKDW
\RXH[SHFWHG<RXXVXDOO\VHHWKLVHUURUZKHQ\RXDVVLJQDYDOXHUHWXUQHGIURPDIXQF
WLRQ WR D YDULDEOH ZLWK D PRUH VSHFLILF W\SH )RU H[DPSOH \RX ZHUH H[SHFWLQJ D
StringEXWWKHIXQFWLRQLQIHUUHGDQ AnyIRUWKHUHWXUQHGREMHFW/HW¦VVHHDFRQWULYHG
H[DPSOHWKDWUHIOHFWVDEXJZKHUHWKLVVFHQDULRFDQRFFXU
// code-examples/TypeLessDoMore/method-broad-inference-return-script.scala
// ERROR: Won't compile; needs a String return type on the second "joiner".

def makeList(strings: String*) = {


if (strings.length == 0)
List(0) // #1
else
strings.toList
}

val list: List[String] = makeList()

5XQQLQJWKLVVFULSWUHWXUQVWKHIROORZLQJHUURU
...11: error: type mismatch;
found : List[Any]
required: List[String]

32 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
val list: List[String] = makeList()
^

:HLQWHQGHGIRU makeListWRUHWXUQD List[String]EXWZKHQ strings.lengthHTXDOV


]HURZHUHWXUQHG List(0)LQFRUUHFWO\£DVVXPLQJ¤WKDWWKLVH[SUHVVLRQLVWKHFRUUHFW
ZD\WRFUHDWHDQHPSW\OLVW,QIDFWZHUHWXUQHGDList[Int]ZLWKRQHHOHPHQW0:H
VKRXOG KDYH UHWXUQHG List() 6LQFH WKH else H[SUHVVLRQ UHWXUQV D List[String] WKH
UHVXOWRIstrings.toListWKHLQIHUUHGUHWXUQW\SHIRUWKHPHWKRGLVWKHFORVHVWFRPPRQ
VXSHUW\SHRIList[Int]DQGList[String]ZKLFKLVList[Any]1RWHWKDWWKHFRPSLOD
WLRQHUURUGRHVQ¦WRFFXULQWKHIXQFWLRQGHILQLWLRQ:HRQO\VHHLWZKHQZHDWWHPSWWR
DVVLJQWKHYDOXHUHWXUQHGIURPmakeListWRDList[String]YDULDEOH
,QWKLVFDVHIL[LQJWKHEXJLVWKHVROXWLRQ$OWHUQDWLYHO\ZKHQWKHUHLVQ¦WDEXJLWPD\
EHWKDWWKHFRPSLOHUMXVWQHHGVWKH£KHOS¤RIDQH[SOLFLWUHWXUQW\SHGHFODUDWLRQ,QYHV
WLJDWHWKHPHWKRGWKDWDSSHDUVWRUHWXUQWKHXQH[SHFWHGW\SH,QRXUH[SHULHQFH\RX
RIWHQILQGWKDW\RXPRGLILHGWKDWPHWKRG RUDQRWKHURQHLQWKHFDOOSDWK LQVXFKD
ZD\WKDWWKHFRPSLOHUQRZLQIHUVDPRUHJHQHUDOUHWXUQW\SHWKDQQHFHVVDU\$GGWKH
H[SOLFLWUHWXUQW\SHLQWKLVFDVH
$QRWKHUZD\WRSUHYHQWWKHVHSUREOHPVLVWRDOZD\VGHFODUHUHWXUQW\SHVIRUPHWKRGV
HVSHFLDOO\ZKHQGHILQLQJPHWKRGVIRUDSXEOLF$3,/HW¦VUHYLVLWRXUStringUtilH[DPSOH
DQGVHHZK\H[SOLFLWGHFODUDWLRQVDUHDJRRGLGHD DGDSWHGIURP>6PLWKD@ 
+HUHLVRXUStringUtil£$3,¤DJDLQZLWKDQHZPHWKRGtoCollection
// code-examples/TypeLessDoMore/string-util-v3.scala
// Version 3 of "StringUtil" (for all versions of Scala).

object StringUtil {
def joiner(strings: List[String], separator: String): String =
strings.mkString(separator)

def joiner(strings: List[String]): String = strings.mkString(" ")

def toCollection(string: String) = string.split(' ')


}

7KHtoCollectionPHWKRGVSOLWVDVWULQJRQVSDFHVDQGUHWXUQVDQArrayFRQWDLQLQJWKH
VXEVWULQJV7KHUHWXUQW\SHLVLQIHUUHGZKLFKLVDSRWHQWLDOSUREOHPDVZHZLOOVHH7KH
PHWKRG LV VRPHZKDW FRQWULYHG EXW LW ZLOO LOOXVWUDWH RXU SRLQW +HUH LV D FOLHQW RI
StringUtilWKDWXVHVWKLVPHWKRG
// code-examples/TypeLessDoMore/string-util-client.scala

import StringUtil._

object StringUtilClient {
def main(args: Array[String]) = {
args foreach { s => toCollection(s).foreach { x => println(x) } }
}
}

Inferring Type Information | 33

Download at WoweBook.Com
,I\RXFRPSLOHWKHVHILOHVZLWKscala\RXFDQUXQWKHFOLHQWDVIROORZV
$ scala -cp ... StringUtilClient "Programming Scala"
Programming
Scala

)RUWKH -cp ...FODVVSDWKDUJXPHQWXVHWKHGLUHFWRU\ZKHUH scalac


ZURWHWKHFODVVILOHVZKLFKGHIDXOWVWRWKHFXUUHQWGLUHFWRU\ LHXVH
-cp . ,I\RXXVHGWKHEXLOGSURFHVVLQWKHGRZQORDGHGFRGHH[DPSOHV
WKH FODVV ILOHV DUH ZULWWHQ WR WKH EXLOG GLUHFWRU\ XVLQJ scalac -d
build ... ,QWKLVFDVHXVH-cp build

(YHU\WKLQJ LV ILQH DW WKLV SRLQW EXW QRZ LPDJLQH WKDW WKH FRGH EDVH KDV JURZQ
StringUtilDQGLWVFOLHQWVDUHQRZEXLOWVHSDUDWHO\DQGEXQGOHGLQWRGLIIHUHQW-$5V
,PDJLQHDOVRWKDWWKHPDLQWDLQHUVRIStringUtilGHFLGHWRUHWXUQDListLQVWHDGRIWKH
GHIDXOW
object StringUtil {
...

def toCollection(string: String) = string.split(' ').toList // changed!


}

7KHRQO\GLIIHUHQFHLVWKHILQDOFDOOWR toListWKDWFRQYHUWVWKHFRPSXWHG ArrayWRD


List<RXUHFRPSLOH StringUtilDQGUHGHSOR\LWV-$57KHQ\RXUXQWKHVDPHFOLHQW
ZLWKRXWUHFRPSLOLQJLWILUVW
$ scala -cp ... StringUtilClient "Programming Scala"
java.lang.NoSuchMethodError: StringUtil$.toCollection(...
at StringUtilClient$$anonfun$main$1.apply(string-util-client.scala:6)
at StringUtilClient$$anonfun$main$1.apply(string-util-client.scala:6)
...

:KDWKDSSHQHG":KHQWKHFOLHQWZDVFRPSLOHGStringUtil.toCollectionUHWXUQHGDQ
Array7KHQ toCollectionZDVFKDQJHGWRUHWXUQ List,QERWKYHUVLRQVWKHPHWKRG
UHWXUQYDOXHZDVLQIHUUHG7KHUHIRUHWKHFOLHQWVKRXOGKDYHEHHQUHFRPSLOHGWRR
+RZHYHUKDGDQH[SOLFLWUHWXUQW\SHRISeqEHHQGHFODUHGZKLFKLVDSDUHQWIRUERWK
ArrayDQGListWKHQWKHLPSOHPHQWDWLRQFKDQJHZRXOGQRWKDYHIRUFHGDUHFRPSLODWLRQ
RIWKHFOLHQW

:KHQGHYHORSLQJ$3,VWKDWDUHEXLOWVHSDUDWHO\IURPWKHLUFOLHQWVGH
FODUHPHWKRGUHWXUQW\SHVH[SOLFLWO\DQGXVHWKHPRVWJHQHUDOUHWXUQW\SH
\RXFDQ7KLVLVHVSHFLDOO\LPSRUWDQWZKHQ$3,VGHFODUHDEVWUDFWPHWK
RGV VHHHJ&KDSWHU 

7KHUH LV DQRWKHU VFHQDULR WR ZDWFK IRU ZKHQ XVLQJ GHFODUDWLRQV RI FROOHFWLRQV OLNH
val map = Map()DVLQWKHIROORZLQJH[DPSOH

34 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
val map = Map()

map.update("book", "Programming Scala")


... 3: error: type mismatch;
found : java.lang.String("book")
required: Nothing
map.update("book", "Programming Scala")
^

:KDW KDSSHQHG" 7KH W\SH SDUDPHWHUV RI WKH JHQHULF W\SH Map ZHUH LQIHUUHG DV
[Nothing,Nothing]ZKHQWKHPDSZDVFUHDWHG :H¦OOGLVFXVV NothingLQ£7KH6FDOD
7\SH+LHUDUFK\¤RQSDJHEXWLWVQDPHLVVXJJHVWLYH :HDWWHPSWHGWRLQVHUWDQ
LQFRPSDWLEOHNH\YDOXHSDLURIW\SHVStringDQGString&DOOLWDMapWRQRZKHUH7KH
VROXWLRQ LV WR SDUDPHWHUL]H WKH LQLWLDO PDS GHFODUDWLRQ HJ val map = Map[String,
String]()RUWRVSHFLI\LQLWLDOYDOXHVVRWKDWWKHPDSSDUDPHWHUVDUHLQIHUUHGHJval
map = Map("Programming" → "Scala")
)LQDOO\WKHUHLVDVXEWOHEHKDYLRUZLWKLQIHUUHGUHWXUQW\SHVWKDWFDQFDXVHXQH[SHFWHG
DQGEDIIOLQJUHVXOWV VHH>6FDOD7LSV@ &RQVLGHUWKHIROORZLQJH[DPSOHscalaVHVVLRQ
scala> def double(i: Int) { 2 * i }
double: (Int)Unit

scala> println(double(2))
()

:K\GLGWKHVHFRQGFRPPDQGSULQW()LQVWHDGRI4"/RRNFDUHIXOO\DWZKDWWKHscala
LQWHUSUHWHUVDLGWKHILUVWFRPPDQGUHWXUQHGdouble (Int)Unit:HGHILQHGDPHWKRG
QDPHGdoubleWKDWWDNHVDQIntDUJXPHQWDQGUHWXUQVUnit7KHPHWKRGGRHVQ¦WUHWXUQ
DQIntDVZHZRXOGH[SHFW
7KHFDXVHRIWKLVXQH[SHFWHGEHKDYLRULVDPLVVLQJHTXDOVVLJQLQWKHPHWKRGGHILQLWLRQ
+HUHLVWKHGHILQLWLRQZHDFWXDOO\LQWHQGHG
scala> def double(i: Int) = { 2 * i }
double: (Int)Int

scala> println(double(2))
4

1RWHWKHHTXDOVVLJQEHIRUHWKHERG\RIdouble1RZWKHRXWSXWVD\VZHKDYHGHILQHG
doubleWRUHWXUQDQIntDQGWKHVHFRQGFRPPDQGGRHVZKDWZHH[SHFWLWWRGR
7KHUHLVDUHDVRQIRUWKLVEHKDYLRU6FDODUHJDUGVDPHWKRGZLWKWKHHTXDOVVLJQEHIRUH
WKHERG\DVDIXQFWLRQGHILQLWLRQDQGDIXQFWLRQDOZD\VUHWXUQVDYDOXHLQIXQFWLRQDO
SURJUDPPLQJ2QWKHRWKHUKDQGZKHQ6FDODVHHVDPHWKRGERG\ZLWKRXWWKHOHDGLQJ
HTXDOV VLJQ LW DVVXPHV WKH SURJUDPPHU LQWHQGHG WKH PHWKRG WR EH D £SURFHGXUH¤
GHILQLWLRQPHDQWIRUSHUIRUPLQJVLGHHIIHFWVRQO\ZLWKWKHUHWXUQYDOXHUnit,QSUDFWLFH
LWLVPRUHOLNHO\WKDWWKHSURJUDPPHUVLPSO\IRUJRWWRLQVHUWWKHHTXDOVVLJQ

Inferring Type Information | 35

Download at WoweBook.Com
:KHQWKHUHWXUQW\SHRIDPHWKRGLVLQIHUUHGDQG\RXGRQ¦WXVHDQHTXDOV
VLJQEHIRUHWKHRSHQLQJSDUHQWKHVLVIRUWKHPHWKRGERG\6FDODLQIHUVD
UnitUHWXUQW\SHHYHQZKHQWKHODVWH[SUHVVLRQLQWKHPHWKRGLVDYDOXH
RIDQRWKHUW\SH

%\WKHZD\ZKHUHGLGWKDW()FRPHIURPWKDWZDVSULQWHGEHIRUHZHIL[HGWKHEXJ",W
LV DFWXDOO\ WKH UHDO QDPH RI WKH VLQJOHWRQ LQVWDQFH RI WKH Unit W\SH 7KLV QDPH LV D
IXQFWLRQDOSURJUDPPLQJFRQYHQWLRQ

Literals
2IWHQDQHZREMHFWLVLQLWLDOL]HGZLWKDOLWHUDOYDOXHVXFKDVval book = "Programming
Scala"/HW¦VGLVFXVVWKHNLQGVRIOLWHUDOYDOXHVVXSSRUWHGE\6FDOD+HUHZH¦OOOLPLW
RXUVHOYHV WR OH[LFDO V\QWD[ OLWHUDOV :H¦OO FRYHU OLWHUDO V\QWD[ IRU IXQFWLRQV XVHG DV
YDOXHVQRWPHPEHUPHWKRGV WXSOHVDQGFHUWDLQW\SHVOLNHListsDQGMapsDVZHFRPH
WRWKHP

Integer Literals
,QWHJHUOLWHUDOVFDQEHH[SUHVVHGLQGHFLPDOKH[DGHFLPDORURFWDO7KHGHWDLOVDUHVXP
PDUL]HGLQ7DEOH
7DEOH,QWHJHUOLWHUDOV
Kind Format Examples
Decimal 0 or a nonzero digit followed by zero or more digits (0–9) 0, 1, 321
Hexadecimal 0x followed by one or more hexadecimal digits (0–9, A–F, a–f) 0xFF, 0x1a3b
Octal 0 followed by one or more octal digits (0–7) 013, 077

)RULongOLWHUDOVLWLVQHFHVVDU\WRDSSHQGWKHLRUlFKDUDFWHUDWWKHHQGRIWKHOLWHUDO
2WKHUZLVHDQ IntLVXVHG7KHYDOLGYDOXHVIRUDQLQWHJHUOLWHUDODUHERXQGHGE\WKH
W\SHRIWKHYDULDEOHWRZKLFKWKHYDOXHZLOOEHDVVLJQHG7DEOHGHILQHVWKHOLPLWV
ZKLFKDUHLQFOXVLYH
7DEOH5DQJHVRIDOORZHGYDOXHVIRULQWHJHUOLWHUDOV ERXQGDULHVDUHLQFOXVLYH
Target type Minimum (inclusive) Maximum (inclusive)
Long −263 263 − 1
Int −231 231 − 1
Short −215 215 − 1
Char 0 216 − 1
Byte −27 27 − 1

36 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
$FRPSLOHWLPHHUURURFFXUVLIDQLQWHJHUOLWHUDOQXPEHULVVSHFLILHGWKDWLVRXWVLGHWKHVH
UDQJHVDVLQWKHIROORZLQJH[DPSOHV
scala > val i = 12345678901234567890
<console>:1: error: integer number too large
val i = 12345678901234567890
scala> val b: Byte = 128
<console>:4: error: type mismatch;
found : Int(128)
required: Byte
val b: Byte = 128
^

scala> val b: Byte = 127


b: Byte = 127

Floating-Point Literals
)ORDWLQJSRLQWOLWHUDOVDUHH[SUHVVLRQVZLWK]HURRUPRUHGLJLWVIROORZHGE\DSHULRG
. IROORZHGE\]HURRUPRUHGLJLWV,IWKHUHDUHQRGLJLWVEHIRUHWKHSHULRGLHWKH
QXPEHULVOHVVWKDQWKHQWKHUHPXVWEHRQHRUPRUHGLJLWVDIWHUWKHSHULRG)RU
Float OLWHUDOV DSSHQG WKH F RU f FKDUDFWHU DW WKH HQG RI WKH OLWHUDO 2WKHUZLVH D
DoubleLVDVVXPHG<RXFDQRSWLRQDOO\DSSHQGDDRUdIRUDDouble
)ORDWLQJSRLQWOLWHUDOVFDQEHH[SUHVVHGZLWKRUZLWKRXWH[SRQHQWLDOV7KHIRUPDWRI
WKHH[SRQHQWLDOSDUWLVeRUEIROORZHGE\DQRSWLRQDO+RU-IROORZHGE\RQHRUPRUH
GLJLWV
+HUHDUHVRPHH[DPSOHIORDWLQJSRLQWOLWHUDOV
0.
.0
0.0
3.
3.14
.14
0.14
3e5
3E5
3.E5
3.e5
3.e+5
3.e-5
3.14e-5
3.14e-5f
3.14e-5F
3.14e-5d
3.14e-5D

Float FRQVLVWV RI DOO ,(((  ELW VLQJOHSUHFLVLRQ ELQDU\ IORDWLQJSRLQW YDOXHV
DoubleFRQVLVWVRIDOO,(((ELWGRXEOHSUHFLVLRQELQDU\IORDWLQJSRLQWYDOXHV

Literals | 37

Download at WoweBook.Com
7RDYRLGSDUVLQJDPELJXLWLHV\RXPXVWKDYHDWOHDVWRQHVSDFHDIWHUD
IORDWLQJSRLQWOLWHUDOLILWLVIROORZHGE\DWRNHQWKDWVWDUWVZLWKDOHWWHU
$OVRWKHH[SUHVVLRQ 1.toStringUHWXUQVWKHLQWHJHUYDOXH 1DVDVWULQJ
ZKLOH1. toStringXVHVWKHRSHUDWRUQRWDWLRQWRLQYRNHtoStringRQWKH
IORDWLQJSRLQWOLWHUDO1.

Boolean Literals
7KH ERROHDQ OLWHUDOV DUH true DQG false 7KH W\SH RI WKH YDULDEOH WR ZKLFK WKH\ DUH
DVVLJQHGZLOOEHLQIHUUHGWREHBoolean
scala> val b1 = true
b1: Boolean = true

scala> val b2 = false


b2: Boolean = false

Character Literals
$FKDUDFWHUOLWHUDOLVHLWKHUDSULQWDEOH8QLFRGHFKDUDFWHURUDQHVFDSHVHTXHQFHZULWWHQ
EHWZHHQVLQJOHTXRWHV$FKDUDFWHUZLWKD8QLFRGHYDOXHEHWZHHQDQGPD\DOVR
EHUHSUHVHQWHGE\DQRFWDOHVFDSHLHDEDFNVODVK \ IROORZHGE\DVHTXHQFHRIXSWR
WKUHHRFWDOFKDUDFWHUV,WLVDFRPSLOHWLPHHUURULIDEDFNVODVKFKDUDFWHULQDFKDUDFWHU
RUVWULQJOLWHUDOGRHVQRWVWDUWDYDOLGHVFDSHVHTXHQFH
+HUHDUHVRPHH[DPSOHV
'A'
'\u0041' // 'A' in Unicode
'\n'
'\012' // '\n' in octal
'\t'

7KHYDOLGHVFDSHVHTXHQFHVDUHVKRZQLQ7DEOH
7DEOH&KDUDFWHUHVFDSHVHTXHQFHV
Sequence Unicode Meaning
\b \u0008 Backspace (BS)
\t \u0009 Horizontal tab (HT)
\n \u000a Line feed (LF)
\f \u000c Form feed (FF)
\r \u000d Carriage return (CR)
\" \u0022 Double quote (")
\’ \u0027 Single quote (’)
\\ \u0009 Backslash (\)

38 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
String Literals
$VWULQJOLWHUDOLVDVHTXHQFHRIFKDUDFWHUVHQFORVHGLQGRXEOHTXRWHVRUWULSOHVRIGRXEOH
TXRWHVLH"""..."""
)RUVWULQJOLWHUDOVLQGRXEOHTXRWHVWKHDOORZHGFKDUDFWHUVDUHWKHVDPHDVWKHFKDUDFWHU
OLWHUDOV +RZHYHU LI D GRXEOH TXRWH " FKDUDFWHU DSSHDUV LQ WKH VWULQJ LW PXVW EH
£HVFDSHG¤ZLWKD\FKDUDFWHU+HUHDUHVRPHH[DPSOHV
"Programming\nScala"
"He exclaimed, \"Scala is great!\""
"First\tSecond"

7KHVWULQJOLWHUDOVERXQGHGE\WULSOHVRIGRXEOHTXRWHVDUHDOVRFDOOHGPXOWLOLQHVWULQJ
OLWHUDOV7KHVHVWULQJVFDQFRYHUVHYHUDOOLQHVWKHOLQHIHHGVZLOOEHSDUWRIWKHVWULQJ
7KH\FDQLQFOXGHDQ\FKDUDFWHUVLQFOXGLQJRQHRUWZRGRXEOHTXRWHVWRJHWKHUEXWQRW
WKUHHWRJHWKHU7KH\DUHXVHIXOIRUVWULQJVZLWK\FKDUDFWHUVWKDWGRQ¦WIRUPYDOLG8QL
FRGHRUHVFDSHVHTXHQFHVOLNHWKHYDOLGVHTXHQFHVOLVWHGLQ7DEOH5HJXODUH[SUHV
VLRQV DUH D W\SLFDO H[DPSOH ZKLFK ZH¦OO GLVFXVV LQ &KDSWHU  +RZHYHU LI HVFDSH
VHTXHQFHVDSSHDUWKH\DUHQ¦WLQWHUSUHWHG
+HUHDUHWKUHHH[DPSOHVWULQJV
"""Programming\nScala"""
"""He exclaimed, "Scala is great!" """
"""First line\n
Second line\t

Fourth line"""

1RWHWKDWZHKDGWRDGGDVSDFHEHIRUHWKHWUDLOLQJ"""LQWKHVHFRQGH[DPSOHWRSUHYHQW
DSDUVHHUURU7U\LQJWRHVFDSHWKHVHFRQG"WKDWHQGVWKH"Scala is great!"TXRWHLH
"Scala is great!\"GRHVQ¦WZRUN
&RS\DQGSDVWHWKHVHVWULQJVLQWRWKH scalaLQWHUSUHWHU'RWKHVDPHIRUWKHSUHYLRXV
VWULQJH[DPSOHV+RZDUHWKH\LQWHUSUHWHGGLIIHUHQWO\"

Symbol Literals
6FDODVXSSRUWVV\PEROVZKLFKDUHLQWHUQHGVWULQJVPHDQLQJWKDWWZRV\PEROVZLWKWKH
VDPH£QDPH¤ LHWKHVDPHFKDUDFWHUVHTXHQFH ZLOODFWXDOO\UHIHUWRWKHVDPHREMHFW
LQPHPRU\6\PEROVDUHXVHGOHVVRIWHQLQ6FDODWKDQLQVRPHRWKHUODQJXDJHVOLNH
5XE\6PDOOWDONDQG/LVS7KH\DUHXVHIXODVPDSNH\VLQVWHDGRIVWULQJV
$V\PEROOLWHUDOLVDVLQJOHTXRWH ' IROORZHGE\DOHWWHUIROORZHGE\]HURRUPRUH
GLJLWVDQGOHWWHUV1RWHWKDWDQH[SUHVVLRQOLNH'1LVLQYDOLGEHFDXVHWKHFRPSLOHUWKLQNV
LWLVDQLQFRPSOHWHFKDUDFWHUOLWHUDO
$V\PEROOLWHUDO'idLVDVKRUWKDQGIRUWKHH[SUHVVLRQscala.Symbol("id")

Literals | 39

Download at WoweBook.Com
,I \RX ZDQW WR FUHDWH D V\PERO WKDW FRQWDLQV ZKLWHVSDFH XVH HJ
scala.Symbol(" Programming Scala ")$OOWKHZKLWHVSDFHLVSUHVHUYHG

Tuples
+RZPDQ\WLPHVKDYH\RXZDQWHGWRUHWXUQWZRRUPRUHYDOXHVIURPDPHWKRG",Q
PDQ\ODQJXDJHVOLNH-DYD\RXRQO\KDYHDIHZRSWLRQVQRQHRIZKLFKLVYHU\DSSHDOLQJ
<RXFRXOGSDVVLQSDUDPHWHUVWRWKHPHWKRGWKDWZLOOEHPRGLILHGIRUDOORUVRPHRIWKH
£UHWXUQ¤YDOXHVZKLFKLVXJO\2U\RXFRXOGGHFODUHVRPHVPDOO£VWUXFWXUDO¤FODVVWKDW
KROGVWKHWZRRUPRUHYDOXHVWKHQUHWXUQDQLQVWDQFHRIWKDWFODVV
6FDODVXSSRUWVWXSOHVDJURXSLQJRIWZRRUPRUHLWHPVXVXDOO\FUHDWHGZLWKWKHOLWHUDO
V\QWD[RIDFRPPDVHSDUDWHGOLVWRIWKHLWHPVLQVLGHSDUHQWKHVHVHJ(x1, x2, ...)
7KHW\SHVRIWKHxLHOHPHQWVDUHXQUHODWHGWRHDFKRWKHU\RXFDQPL[DQGPDWFKW\SHV
7KHVH OLWHUDO £JURXSLQJV¤ DUH LQVWDQWLDWHG DV scala.TupleN LQVWDQFHV ZKHUH N LV WKH
QXPEHURILWHPVLQWKHWXSOH7KH6FDOD$3,GHILQHVVHSDUDWHTupleNFODVVHVIRUNEHWZHHQ
DQGLQFOXVLYH7XSOHLQVWDQFHVDUHLPPXWDEOHILUVWFODVVYDOXHVVR\RXFDQDVVLJQ
WKHPWRYDULDEOHVSDVVWKHPDVYDOXHVDQGUHWXUQWKHPIURPPHWKRGV
7KHIROORZLQJH[DPSOHGHPRQVWUDWHVWKHXVHRIWXSOHV
// code-examples/TypeLessDoMore/tuple-example-script.scala

def tupleator(x1: Any, x2: Any, x3: Any) = (x1, x2, x3)

val t = tupleator("Hello", 1, 2.3)


println( "Print the whole tuple: " + t )
println( "Print the first item: " + t._1 )
println( "Print the second item: " + t._2 )
println( "Print the third item: " + t._3 )

val (t1, t2, t3) = tupleator("World", '!', 0x22)


println( t1 + " " + t2 + " " + t3 )

5XQQLQJWKLVVFULSWZLWKscalaSURGXFHVWKHIROORZLQJRXWSXW
Print the whole tuple: (Hello,1,2.3)
Print the first item: Hello
Print the second item: 1
Print the third item: 2.3
World ! 34

7KHtupleatorPHWKRGVLPSO\UHWXUQVD£WXSOH¤ZLWKWKHLQSXWDUJXPHQWV7KHILUVW
VWDWHPHQWWKDWXVHVWKLVPHWKRGDVVLJQVWKHUHWXUQHGWXSOHWRDVLQJOHYDULDEOH t7KH
QH[W IRXU VWDWHPHQWV SULQW t LQ YDULRXV ZD\V 7KH ILUVW SULQW VWDWHPHQW FDOOV
Tuple3.toStringZKLFKZUDSVSDUHQWKHVHVDURXQGWKHLWHPOLVW7KHIROORZLQJWKUHH
VWDWHPHQWVSULQWHDFKLWHPLQ tVHSDUDWHO\7KHH[SUHVVLRQ t._NUHWULHYHVWKH NLWHP
VWDUWLQJDWQRW WKLVFKRLFHIROORZVIXQFWLRQDOSURJUDPPLQJFRQYHQWLRQV 

40 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
7KHODVWWZROLQHVVKRZWKDWZHFDQXVHDWXSOHH[SUHVVLRQRQWKHOHIWKDQGVLGHRIWKH
DVVLJQPHQW:HGHFODUHWKUHHvalV¢t1t2DQGt3¢WRKROGWKHLQGLYLGXDOLWHPVLQWKH
WXSOH,QHVVHQFHWKHWXSOHLWHPVDUHH[WUDFWHGDXWRPDWLFDOO\
1RWLFHKRZZHPL[HGW\SHVLQWKHWXSOHV<RXFDQVHHWKHW\SHVPRUHFOHDUO\LI\RXXVH
WKHLQWHUDFWLYHPRGHRIWKHscalaFRPPDQGZKLFKZHLQWURGXFHGLQ&KDSWHU
,QYRNH WKH scala FRPPDQG ZLWK QR VFULSW DUJXPHQW $W WKH scala> SURPSW HQWHU
val t = ("Hello",1,2.3)DQGVHHWKDW\RXJHWWKHIROORZLQJUHVXOWZKLFKVKRZV\RX
WKHW\SHRIHDFKHOHPHQWLQWKHWXSOH
scala> val t = ("Hello",1,2.3)
t: (java.lang.String, Int, Double) = (Hello,1,2.3)

,W¦VZRUWKQRWLQJWKDWWKHUH¦VPRUHWKDQRQHZD\WRGHILQHDWXSOH:H¦YHEHHQXVLQJ
WKHPRUHFRPPRQSDUHQWKHVL]HGV\QWD[EXW\RXFDQDOVRXVHWKHDUURZRSHUDWRUEH
WZHHQWZRYDOXHVDVZHOODVVSHFLDOIDFWRU\PHWKRGVRQWKHWXSOHUHODWHGFODVVHV
scala> 1 -> 2
res0: (Int, Int) = (1,2)

scala> Tuple2(1, 2)
res1: (Int, Int) = (1,2)

scala> Pair(1, 2)
res2: (Int, Int) = (1,2)

Option, Some, and None: Avoiding nulls


:H¦OO GLVFXVV WKH VWDQGDUG W\SH KLHUDUFK\ IRU 6FDOD LQ £7KH 6FDOD 7\SH +LHUDU
FK\¤ RQ SDJH  +RZHYHU WKUHH XVHIXO FODVVHV WR XQGHUVWDQG QRZ DUH WKH Option
FODVVDQGLWVWZRVXEFODVVHVSomeDQGNone
0RVWODQJXDJHVKDYHDVSHFLDONH\ZRUGRUREMHFWWKDW¦VDVVLJQHGWRUHIHUHQFHYDULDEOHV
ZKHQWKHUH¦VQRWKLQJHOVHIRUWKHPWRUHIHUWR,Q-DYDWKLVLVnullLQ5XE\LW¦Vnil,Q
-DYD nullLVDNH\ZRUGQRWDQREMHFWDQGWKXVLW¦VLOOHJDOWRFDOODQ\PHWKRGVRQLW
%XWWKLVLVDFRQIXVLQJFKRLFHRQWKHODQJXDJHGHVLJQHU¦VSDUW:K\UHWXUQDNH\ZRUG
ZKHQWKHSURJUDPPHUH[SHFWVDQREMHFW"
7REHPRUHFRQVLVWHQWZLWKWKHJRDORIPDNLQJHYHU\WKLQJDQREMHFWDVZHOODVWRFRQ
IRUP ZLWK IXQFWLRQDO SURJUDPPLQJ FRQYHQWLRQV 6FDOD HQFRXUDJHV \RX WR XVH WKH
OptionW\SHIRUYDULDEOHVDQGIXQFWLRQUHWXUQYDOXHVZKHQWKH\PD\RUPD\QRWUHIHUWR
DYDOXH:KHQWKHUHLVQRYDOXHXVHNoneDQobjectWKDWLVDVXEFODVVRIOption:KHQ
WKHUHLVDYDOXHXVHSomeZKLFKZUDSVWKHYDOXHSomeLVDOVRDVXEFODVVRIOption

NoneLVGHFODUHGDVDQobjectQRWDclassEHFDXVHZHUHDOO\RQO\QHHG
RQHLQVWDQFHRILW,QWKDWVHQVHLW¦VOLNHWKHnullNH\ZRUGEXWLWLVDUHDO
REMHFWZLWKPHWKRGV

Option, Some, and None: Avoiding nulls | 41

Download at WoweBook.Com
<RXFDQVHHOptionSomeDQGNoneLQDFWLRQLQWKHIROORZLQJH[DPSOHZKHUHZHFUHDWH
DPDSRIVWDWHFDSLWDOVLQWKH8QLWHG6WDWHV
// code-examples/TypeLessDoMore/state-capitals-subset-script.scala

val stateCapitals = Map(


"Alabama" -> "Montgomery",
"Alaska" -> "Juneau",
// ...
"Wyoming" -> "Cheyenne")

println( "Get the capitals wrapped in Options:" )


println( "Alabama: " + stateCapitals.get("Alabama") )
println( "Wyoming: " + stateCapitals.get("Wyoming") )
println( "Unknown: " + stateCapitals.get("Unknown") )

println( "Get the capitals themselves out of the Options:" )


println( "Alabama: " + stateCapitals.get("Alabama").get )
println( "Wyoming: " + stateCapitals.get("Wyoming").getOrElse("Oops!") )
println( "Unknown: " + stateCapitals.get("Unknown").getOrElse("Oops2!") )

7KHFRQYHQLHQW ->V\QWD[IRUGHILQLQJQDPHYDOXHSDLUVWRLQLWLDOL]HD MapZLOOEHGLV


FXVVHGLQ£7KH3UHGHI2EMHFW¤RQSDJH)RUQRZZHZDQWWRIRFXVRQWKHWZR
JURXSVRI printlnVWDWHPHQWVZKHUHZHVKRZZKDWKDSSHQVZKHQ\RXUHWULHYHWKH
YDOXHVIURPWKHPDS,I\RXUXQWKLVVFULSWZLWKWKH scalaFRPPDQG\RX¦OOJHWWKH
IROORZLQJRXWSXW
Get the capitals wrapped in Options:
Alabama: Some(Montgomery)
Wyoming: Some(Cheyenne)
Unknown: None
Get the capitals themselves out of the Options:
Alabama: Montgomery
Wyoming: Cheyenne
Unknown: Oops2!

7KHILUVWJURXSRI printlnVWDWHPHQWVLQYRNH toStringLPSOLFLWO\RQWKHLQVWDQFHVUH


WXUQHGE\ get:HDUHFDOOLQJ toStringRQ SomeRU NoneLQVWDQFHVEHFDXVHWKHYDOXHV
UHWXUQHGE\Map.getDUHDXWRPDWLFDOO\ZUDSSHGLQDSomeZKHQWKHUHLVDYDOXHLQWKH
PDSIRUWKHVSHFLILHGNH\1RWHWKDWWKH6FDODOLEUDU\GRHVQ¦WVWRUHWKHSomeLQWKHPDS
LWZUDSVWKHYDOXHLQD SomeXSRQUHWULHYDO&RQYHUVHO\ZKHQZHDVNIRUDPDSHQWU\
WKDWGRHVQ¦WH[LVWWKH NoneREMHFWLVUHWXUQHGUDWKHUWKDQ null7KLVRFFXUUHGLQWKH
ODVWprintlnRIWKHWKUHH
7KHVHFRQGJURXSRIprintlnVWDWHPHQWVJRHVDVWHSIXUWKHU$IWHUFDOOLQJMap.getWKH\
FDOO get RU getOrElse RQ HDFK Option LQVWDQFH WR UHWULHYH WKH YDOXH LW FRQWDLQV
Option.getUHTXLUHVWKDWWKH OptionLVQRWHPSW\¢WKDWLVWKH OptionLQVWDQFHPXVW
DFWXDOO\EHDSome,QWKLVFDVHgetUHWXUQVWKHYDOXHZUDSSHGE\WKHSomeDVGHPRQ
VWUDWHGLQWKH printlnZKHUHZHSULQWWKHFDSLWDORI$ODEDPD+RZHYHULIWKH Option
LVDFWXDOO\NoneWKHQNone.getWKURZVDNoSuchElementException

42 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
:HDOVRVKRZWKHDOWHUQDWLYHPHWKRG getOrElseLQWKHODVWWZR printlnVWDWHPHQWV
7KLVPHWKRGUHWXUQVHLWKHUWKHYDOXHLQWKHOptionLILWLVDSomeLQVWDQFHRULWUHWXUQV
WKHVHFRQGDUJXPHQWZHSDVVHGWR getOrElseLILWLVD NoneLQVWDQFH,QRWKHUZRUGV
WKHVHFRQGDUJXPHQWWRgetOrElseIXQFWLRQVDVWKHGHIDXOWUHWXUQYDOXH
6R getOrElseLVWKHPRUHGHIHQVLYHRIWKHWZRPHWKRGV,WDYRLGVDSRWHQWLDOWKURZQ
H[FHSWLRQ:H¦OOGLVFXVVWKHPHULWVRIDOWHUQDWLYHVOLNHgetYHUVXVgetOrElseLQ£([FHS
WLRQVDQGWKH$OWHUQDWLYHV¤RQSDJH
1RWHWKDWEHFDXVHWKHMap.getPHWKRGUHWXUQVDQOptionLWDXWRPDWLFDOO\GRFXPHQWV
WKHIDFWWKDWWKHUHPD\QRWEHDQLWHPPDWFKLQJWKHVSHFLILHGNH\7KHPDSKDQGOHV
WKLVVLWXDWLRQE\UHWXUQLQJDNone0RVWODQJXDJHVZRXOGUHWXUQnull RUWKHHTXLYDOHQW
ZKHQWKHUHLVQR£UHDO¤YDOXHWRUHWXUQ<RXOHDUQIURPH[SHULHQFHWRH[SHFWDSRVVLEOH
null8VLQJ OptionPDNHVWKHEHKDYLRUPRUHH[SOLFLWLQWKHPHWKRGVLJQDWXUHVRLW¦V
PRUHVHOIGRFXPHQWLQJ
$OVRWKDQNVWR6FDOD¦VVWDWLFW\SLQJ\RXFDQ¦WPDNHWKHPLVWDNHRIDWWHPSWLQJWRFDOO
DPHWKRGRQDYDOXHWKDWPLJKWDFWXDOO\EH null:KLOHWKLVPLVWDNHLVHDV\WRGRLQ
-DYD LW ZRQ¦W FRPSLOH LQ 6FDOD EHFDXVH \RX PXVW ILUVW H[WUDFW WKH YDOXH IURP WKH
Option6RWKHXVHRIOptionVWURQJO\HQFRXUDJHVPRUHUHVLOLHQWSURJUDPPLQJ
%HFDXVH6FDODUXQVRQWKH-90DQG1(7DQGEHFDXVHLWPXVWLQWHURSHUDWHZLWKRWKHU
OLEUDULHV6FDODKDVWRVXSSRUW null6WLOO\RXVKRXOGDYRLGXVLQJ nullLQ\RXUFRGH
7RQ\ +RDUH ZKR LQYHQWHG WKH QXOO UHIHUHQFH LQ  ZKLOH ZRUNLQJ RQ DQ REMHFW
RULHQWHGODQJXDJHFDOOHG$/*2/:FDOOHGLWVLQYHQWLRQKLV£ELOOLRQGROODUPLVWDNH¤
VHH>+RDUH@ 'RQ¦WFRQWULEXWHWRWKDWILJXUH
6RKRZZRXOG\RXZULWHDPHWKRGWKDWUHWXUQVDQ Option"+HUHLVDSRVVLEOHLPSOH
PHQWDWLRQ RI get WKDW FRXOG EH XVHG E\ D FRQFUHWH VXEFODVV RI Map Map.get LWVHOI LV
DEVWUDFW  )RU D PRUH VRSKLVWLFDWHG YHUVLRQ VHH WKH LPSOHPHQWDWLRQ RI get LQ
scala.collection.immutable.HashMapLQWKH6FDODOLEUDU\VRXUFHFRGHGLVWULEXWLRQ
def get(key: A): Option[B] = {
if (contains(key))
new Some(getValue(key))
else
None
}

7KHcontainsPHWKRGLVDOVRGHILQHGIRUMap,WUHWXUQVtrueLIWKHPDSFRQWDLQVDYDOXH
IRUWKHVSHFLILHGNH\7KHgetValuePHWKRGLVLQWHQGHGWREHDQLQWHUQDOPHWKRGWKDW
UHWULHYHVWKHYDOXHIURPWKHXQGHUO\LQJVWRUDJHZKDWHYHULWLV
1RWHKRZWKHYDOXHUHWXUQHGE\getValueLVZUDSSHGLQDSome[B]ZKHUHWKHW\SH BLV
LQIHUUHG+RZHYHULIWKHFDOOWR contains(key)UHWXUQV falseWKHQWKH object NoneLV
UHWXUQHG
<RXFDQXVHWKLVVDPHLGLRPZKHQ\RXUPHWKRGVUHWXUQDQOption:H¦OOH[SORUHRWKHU
XVHV IRU Option LQ VXEVHTXHQW VHFWLRQV ,WV SHUYDVLYH XVH LQ 6FDOD FRGH PDNHV LW DQ
LPSRUWDQWFRQFHSWWRJUDVS

Option, Some, and None: Avoiding nulls | 43

Download at WoweBook.Com
Organizing Code in Files and Namespaces
6FDODDGRSWVWKHSDFNDJHFRQFHSWWKDW-DYDXVHVIRUQDPHVSDFHVEXW6FDODRIIHUVDPRUH
IOH[LEOHV\QWD[-XVWDVILOHQDPHVGRQ¦WKDYHWRPDWFKWKHW\SHQDPHVWKHSDFNDJH
VWUXFWXUHGRHVQRWKDYHWRPDWFKWKHGLUHFWRU\VWUXFWXUH6R\RXFDQGHILQHSDFNDJHV
LQILOHVLQGHSHQGHQWRIWKHLU£SK\VLFDO¤ORFDWLRQ
7KHIROORZLQJH[DPSOHGHILQHVDFODVV MyClassLQDSDFNDJH com.example.mypkgXVLQJ
WKHFRQYHQWLRQDO-DYDV\QWD[
// code-examples/TypeLessDoMore/package-example1.scala

package com.example.mypkg

class MyClass {
// ...
}

7KHQH[WH[DPSOHVKRZVDFRQWULYHGH[DPSOHWKDWGHILQHVSDFNDJHVXVLQJWKHQHVWHG
SDFNDJHV\QWD[LQ6FDODZKLFKLVVLPLODUWRWKHnamespaceV\QWD[LQ&DQGWKHXVHRI
modulesDVQDPHVSDFHVLQ5XE\
// code-examples/TypeLessDoMore/package-example2.scala

package com {
package example {
package pkg1 {
class Class11 {
def m = "m11"
}
class Class12 {
def m = "m12"
}
}

package pkg2 {
class Class21 {
def m = "m21"
def makeClass11 = {
new pkg1.Class11
}
def makeClass12 = {
new pkg1.Class12
}
}
}

package pkg3.pkg31.pkg311 {
class Class311 {
def m = "m21"
}
}
}
}

44 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
7ZR SDFNDJHV pkg1 DQG pkg2 DUH GHILQHG XQGHU WKH com.example SDFNDJH $ WRWDO
RI WKUHH FODVVHV DUH GHILQHG EHWZHHQ WKH WZR SDFNDJHV 7KH makeClass11 DQG
makeClass12 PHWKRGV LQ Class21 LOOXVWUDWH KRZ WR UHIHUHQFH D W\SH LQ WKH £VLEOLQJ¤
SDFNDJH pkg1 <RX FDQ DOVR UHIHUHQFH WKHVH FODVVHV E\ WKHLU IXOO SDWKV
com.example.pkg1.Class11DQGcom.example.pkg1.Class12UHVSHFWLYHO\
7KHSDFNDJHpkg3.pkg31.pkg311VKRZVWKDW\RXFDQ£FKDLQ¤VHYHUDOSDFNDJHVWRJHWKHU
LQRQHFODXVH,WLVQRWQHFHVVDU\WRXVHDVHSDUDWHpackageFODXVHIRUHDFKSDFNDJH
)ROORZLQJWKHFRQYHQWLRQVRI-DYDWKHURRWSDFNDJHIRU6FDOD¦VOLEUDU\FODVVHVLVQDPHG
scala

6FDODGRHVQRWDOORZSDFNDJHGHFODUDWLRQVLQVFULSWVWKDWDUHH[HFXWHG
GLUHFWO\ZLWKWKH scalaLQWHUSUHWHU7KHUHDVRQKDVWRGRZLWKWKHZD\
WKH LQWHUSUHWHU FRQYHUWV VWDWHPHQWV LQ VFULSWV WR YDOLG 6FDOD FRGH
EHIRUH FRPSLOLQJ WR E\WH FRGH 6HH £7KH VFDOD &RPPDQG/LQH
7RRO¤RQSDJHIRUPRUHGHWDLOV

Importing Types and Their Members


7RXVHGHFODUDWLRQVLQSDFNDJHV\RXKDYHWRLPSRUWWKHPMXVWDV\RXGRLQ-DYDDQG
VLPLODUO\IRURWKHUODQJXDJHV+RZHYHUFRPSDUHGWR-DYD6FDODJUHDWO\H[SDQGV\RXU
RSWLRQV7KHIROORZLQJH[DPSOHLOOXVWUDWHVVHYHUDOZD\VWRLPSRUW-DYDW\SHV
// code-examples/TypeLessDoMore/import-example1.scala

import java.awt._
import java.io.File
import java.io.File._
import java.util.{Map, HashMap}

<RXFDQLPSRUWDOOW\SHVLQDSDFNDJHXVLQJWKHXQGHUVFRUH _ DVDZLOGFDUGDVVKRZQ
RQWKHILUVWOLQH<RXFDQDOVRLPSRUWLQGLYLGXDO6FDODRU-DYDW\SHVDVVKRZQRQWKH
VHFRQGOLQH
-DYDXVHVWKH£VWDU¤FKDUDFWHU * DVWKHZLOGFDUGIRUPDWFKLQJDOOW\SHVLQDSDFNDJHRU
DOOVWDWLFPHPEHUVRIDW\SHZKHQGRLQJ£VWDWLFLPSRUWV¤,Q6FDODWKLVFKDUDFWHULV
DOORZHGLQPHWKRGQDPHVVR_LVXVHGDVDZLOGFDUGDVZHVDZSUHYLRXVO\
$VVKRZQRQWKHWKLUGOLQH\RXFDQLPSRUWDOOWKHVWDWLFPHWKRGVDQGILHOGVLQ-DYD
W\SHV,I java.io.FileZHUHDFWXDOO\D6FDOD objectDVGLVFXVVHGSUHYLRXVO\WKHQWKLV
OLQHZRXOGLPSRUWWKHILHOGVDQGPHWKRGVIURPWKHREMHFW
)LQDOO\\RXFDQVHOHFWLYHO\LPSRUWMXVWWKHW\SHV\RXFDUHDERXW2QWKHIRXUWKOLQHZH
LPSRUWMXVWWKH java.util.MapDQG java.util.HashMapW\SHVIURPWKH java.utilSDFN
DJH&RPSDUHWKLVRQHOLQHLPSRUWVWDWHPHQWZLWKWKHWZROLQHLPSRUWVWDWHPHQWVZH
XVHG LQ RXU ILUVW H[DPSOH LQ £,QIHUULQJ 7\SH ,QIRUPDWLRQ¤ RQ SDJH  7KH\ DUH
IXQFWLRQDOO\HTXLYDOHQW

Importing Types and Their Members | 45

Download at WoweBook.Com
7KHQH[WH[DPSOHVKRZVPRUHDGYDQFHGRSWLRQVIRULPSRUWVWDWHPHQWV
// code-examples/TypeLessDoMore/import-example2-script.scala

def writeAboutBigInteger() = {

import java.math.BigInteger.{
ONE => _,
TEN,
ZERO => JAVAZERO }

// ONE is effectively undefined


// println( "ONE: "+ONE )
println( "TEN: "+TEN )
println( "ZERO: "+JAVAZERO )
}

writeAboutBigInteger()

7KLVH[DPSOHGHPRQVWUDWHVWZRIHDWXUHV)LUVWZHFDQSXWLPSRUWVWDWHPHQWVDOPRVW
DQ\ZKHUHZHZDQWQRWMXVWDWWKHWRSRIWKHILOHDVUHTXLUHGE\-DYD7KLVIHDWXUHDOORZV
XVWRVFRSHWKHLPSRUWVPRUHQDUURZO\)RUH[DPSOHZHFDQ¦WUHIHUHQFHWKHLPSRUWHG
BigIntegerGHILQLWLRQVRXWVLGHWKHVFRSHRIWKHPHWKRG$QRWKHUDGYDQWDJHRIWKLVIHD
WXUHLVWKDWLWSXWVDQLPSRUWVWDWHPHQWFORVHUWRZKHUHWKHLPSRUWHGLWHPVDUHDFWXDOO\
XVHG
7KH VHFRQG IHDWXUH VKRZQ LV WKH DELOLW\ WR UHQDPH LPSRUWHG LWHPV )LUVW WKH
java.math.BigInteger.ONEFRQVWDQWLVUHQDPHGWRWKHXQGHUVFRUHZLOGFDUG7KLVHIIHF
WLYHO\PDNHVLWLQYLVLEOHDQGXQDYDLODEOHWRWKHLPSRUWLQJVFRSH7KLVLVDXVHIXOWHFK
QLTXHZKHQ\RXZDQWWRLPSRUWHYHU\WKLQJH[FHSWDIHZSDUWLFXODULWHPV
1H[WWKHjava.math.BigInteger.TENFRQVWDQWLVLPSRUWHGZLWKRXWUHQDPLQJVRLWFDQ
EHUHIHUHQFHGVLPSO\DVTEN
)LQDOO\WKHjava.math.BigInteger.ZEROFRQVWDQWLVJLYHQWKH£DOLDV¤JAVAZERO
$OLDVLQJLVXVHIXOLI\RXZDQWWRJLYHWKHLWHPDPRUHFRQYHQLHQWQDPHRU\RXZDQWWR
DYRLGDPELJXLWLHVZLWKRWKHULWHPVLQVFRSHWKDWKDYHWKHVDPHQDPH

Imports are Relative


7KHUH¦VRQHRWKHULPSRUWDQWWKLQJWRNQRZDERXWLPSRUWVWKH\DUHUHODWLYH1RWHWKH
FRPPHQWVIRUWKHIROORZLQJLPSRUWV
// code-examples/TypeLessDoMore/relative-imports.scala
import scala.collection.mutable._
import collection.immutable._ // Since "scala" is already imported
import _root_.scala.collection.jcl._ // full path from real "root"
package scala.actors {
import remote._ // We're in the scope of "scala.actors"
}

46 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
1RWHWKDWWKHODVWLPSRUWVWDWHPHQWQHVWHGLQWKHscala.actorSDFNDJHVFRSHLVUHODWLYH
WRWKDWVFRSH
7KH>6FDOD:LNL@KDVRWKHUH[DPSOHVDWKWWSVFDODV\JQHFDFRPIDTVODQJXDJHKRZGR
LLPSRUW
,W¦VIDLUO\UDUHWKDW\RX¦OOKDYHSUREOHPVZLWKUHODWLYHLPSRUWVEXWWKHSUREOHPZLWK
WKLVFRQYHQWLRQLVWKDWWKH\VRPHWLPHVFDXVHVXUSULVHVHVSHFLDOO\LI\RXDUHDFFXVWRPHG
WRODQJXDJHVOLNH-DYDZKHUHLPSRUWVDUHDEVROXWH,I\RXJHWDP\VWLI\LQJFRPSLOHU
HUURUWKDWDSDFNDJHZDVQ¦WIRXQGFKHFNWKDWWKHVWDWHPHQWLVSURSHUO\UHODWLYHWRWKH
ODVWLPSRUWVWDWHPHQWRUDGGWKH _root_.SUHIL[$OVR\RXPLJKWVHHDQ,'(RURWKHU
WRROLQVHUWDQimport _root_...VWDWHPHQWLQ\RXUFRGH1RZ\RXNQRZZKDWLWPHDQV

5HPHPEHUWKDWLPSRUWVWDWHPHQWVDUHUHODWLYHQRWDEVROXWH7RFUHDWH
DQDEVROXWHSDWKVWDUWZLWK_root_

Abstract Types And Parameterized Types


:H PHQWLRQHG LQ £$ 7DVWH RI 6FDOD¤ RQ SDJH  WKDW 6FDOD VXSSRUWV SDUDPHWHUL]HG
W\SHVZKLFKDUHYHU\VLPLODUWRJHQHULFVLQ-DYD :HFRXOGXVHWKHWZRWHUPVLQWHU
FKDQJHDEO\ EXW LW¦V PRUH FRPPRQ WR XVH £SDUDPHWHUL]HG W\SHV¤ LQ WKH 6FDOD FRP
PXQLW\DQG£JHQHULFV¤LQWKH-DYDFRPPXQLW\ 7KHPRVWREYLRXVGLIIHUHQFHLVLQWKH
V\QWD[ZKHUH6FDODXVHVVTXDUHEUDFNHWV [...] ZKLOH-DYDXVHVDQJOHEUDFNHWV <...> 
)RUH[DPSOHDOLVWRIVWULQJVZRXOGEHGHFODUHGDVIROORZV
val languages: List[String] = ...

7KHUH DUH RWKHU LPSRUWDQW GLIIHUHQFHV ZLWK -DYD¦V JHQHULFV ZKLFK ZH¦OO H[SORUH LQ
£8QGHUVWDQGLQJ3DUDPHWHUL]HG7\SHV¤RQSDJH
)RUQRZZH¦OOPHQWLRQRQHRWKHUXVHIXOGHWDLOWKDW\RX¦OOHQFRXQWHUEHIRUHZHFDQ
H[SODLQLWLQGHSWKLQ&KDSWHU,I\RXORRNDWWKHGHFODUDWLRQRI scala.ListLQWKH
6FDODGRFV\RX¦OOVHHWKDWWKHGHFODUDWLRQLVZULWWHQDV ... class List[+A]7KH +LQ
IURQWRIWKHAPHDQVWKDWList[B]LVDVXEW\SHRIList[A]IRUDQ\BWKDWLVDVXEW\SHRI
A,IWKHUHLVD-LQIURQWRIDW\SHSDUDPHWHUWKHQWKHUHODWLRQVKLSJRHVWKHRWKHUZD\
Foo[B]ZRXOGEHDVXSHUW\SHRIFoo[A]LIWKHGHFODUDWLRQLVFoo[-A]
6FDODVXSSRUWVDQRWKHUW\SHDEVWUDFWLRQPHFKDQLVPFDOOHGDEVWUDFWW\SHVXVHGLQPDQ\
IXQFWLRQDOSURJUDPPLQJODQJXDJHVVXFKDV+DVNHOO$EVWUDFWW\SHVZHUHDOVRFRQVLG
HUHGIRULQFOXVLRQLQ-DYDZKHQJHQHULFVZHUHDGRSWHG:HZDQWWRLQWURGXFHWKHP
QRZ EHFDXVH \RX¦OO VHH PDQ\ H[DPSOHV RI WKHP EHIRUH ZH GLYH LQWR WKHLU GHWDLOV LQ
&KDSWHU)RUDYHU\GHWDLOHGFRPSDULVRQRIWKHVHWZRPHFKDQLVPVVHH>%UXFH@
$EVWUDFWW\SHVFDQEHDSSOLHGWRPDQ\RIWKHVDPHGHVLJQSUREOHPVIRUZKLFKSDUD
PHWHUL]HGW\SHVDUHXVHG+RZHYHUZKLOHWKHWZRPHFKDQLVPVRYHUODSWKH\DUHQRW
UHGXQGDQW(DFKKDVVWUHQJWKVDQGZHDNQHVVHVIRUFHUWDLQGHVLJQSUREOHPV

Abstract Types And Parameterized Types | 47

Download at WoweBook.Com
+HUHLVDQH[DPSOHWKDWXVHVDQDEVWUDFWW\SH
// code-examples/TypeLessDoMore/abstract-types-script.scala

import java.io._

abstract class BulkReader {


type In
val source: In
def read: String
}

class StringBulkReader(val source: String) extends BulkReader {


type In = String
def read = source
}

class FileBulkReader(val source: File) extends BulkReader {


type In = File
def read = {
val in = new BufferedInputStream(new FileInputStream(source))
val numBytes = in.available()
val bytes = new Array[Byte](numBytes)
in.read(bytes, 0, numBytes)
new String(bytes)
}
}

println( new StringBulkReader("Hello Scala!").read )


println( new FileBulkReader(new File("abstract-types-script.scala")).read )

5XQQLQJWKLVVFULSWZLWKscalaSURGXFHVWKHIROORZLQJRXWSXW
Hello Scala!
import java.io._

abstract class BulkReader {


...

7KH BulkReader DEVWUDFW FODVV GHFODUHV WKUHH DEVWUDFW PHPEHUV D type QDPHG In D
valILHOGsourceDQGDreadPHWKRG$VLQ-DYDLQVWDQFHVLQ6FDODFDQRQO\EHFUHDWHG
IURPFRQFUHWHFODVVHVZKLFKPXVWKDYHGHILQLWLRQVIRUDOOPHPEHUV
7KH GHULYHG FODVVHV StringBulkReader DQG FileBulkReader SURYLGH FRQFUHWH GHILQL
WLRQVIRUWKHVHDEVWUDFWPHPEHUV:H¦OOFRYHUWKHGHWDLOVRIFODVVGHFODUDWLRQVLQ&KDS
WHUDQGWKHSDUWLFXODUVRIRYHUULGLQJPHPEHUGHFODUDWLRQVLQ£2YHUULGLQJ0HPEHUV
RI&ODVVHVDQG7UDLWV¤RQSDJHLQ&KDSWHU
)RUQRZQRWHWKDWWKHtypeILHOGZRUNVYHU\PXFKOLNHDW\SHSDUDPHWHULQDSDUDPH
WHUL]HGW\SH,QIDFWZHFRXOGUHZULWHWKLVH[DPSOHDVIROORZVZKHUHZHVKRZRQO\
ZKDWZRXOGEHGLIIHUHQW
abstract class BulkReader[In] {
val source: In
...

48 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
}

class StringBulkReader(val source: String) extends BulkReader[String] {...}

class FileBulkReader(val source: File) extends BulkReader[File] {...}

-XVWDVIRUSDUDPHWHUL]HGW\SHVLIZHGHILQHWKHInW\SHWREHStringWKHQWKHsource
ILHOGPXVWDOVREHGHILQHGDVDString1RWHWKDWWKHStringBulkReader¦VreadPHWKRG
VLPSO\UHWXUQVWKHsourceILHOGZKLOHWKHFileBulkReader¦VreadPHWKRGUHDGVWKHFRQ
WHQWVRIWKHILOH
$VGHPRQVWUDWHGE\>%UXFH@SDUDPHWHUL]HGW\SHVWHQGWREHEHVWIRUFROOHFWLRQV
ZKLFKLVKRZWKH\DUHPRVWRIWHQXVHGLQ-DYDFRGHZKHUHDVDEVWUDFWW\SHVDUHPRVW
XVHIXOIRUW\SH£IDPLOLHV¤DQGRWKHUW\SHVFHQDULRV
:H¦OOH[SORUHWKHGHWDLOVRI6FDOD¦VDEVWUDFWW\SHVLQ&KDSWHU)RUH[DPSOHZH¦OOVHH
KRZWRFRQVWUDLQWKHSRVVLEOHFRQFUHWHW\SHVWKDWFDQEHXVHG

Reserved Words
7DEOHOLVWVWKHUHVHUYHGZRUGVLQ6FDODZKLFKZHVRPHWLPHVFDOO£NH\ZRUGV¤DQG
EULHIO\GHVFULEHVKRZWKH\DUHXVHG VHH>6FDOD6SHF@ 
7DEOH5HVHUYHGZRUGV
Word Description See …
abstract Makes a declaration abstract. Unlike Java, the keyword is usually “Class and Object Basics” on page 89
not required for abstract members.
case Start a case clause in a match expression. “Pattern Matching” on page 63
catch Start a clause for catching thrown exceptions. “Using try, catch, and finally Clau-
ses” on page 70
class Start a class declaration. “Class and Object Basics” on page 89
def Start a method declaration. “Method Declarations” on page 25
do Start a do...while loop. “Other Looping Constructs”
on page 61
else Start an else clause for an if clause. “Scala if Statements” on page 58
extends Indicates that the class or trait that follows is the parent type of the “Parent Classes” on page 91
class or trait being declared.
false Boolean false. “The Scala Type Hierarchy”
on page 155
final Applied to a class or trait to prohibit deriving child types from it. “Attempting to Override final Declara-
Applied to a member to prohibit overriding it in a derived class or tions” on page 112
trait.
finally Start a clause that is executed after the corresponding try clause, “Using try, catch, and finally Clau-
whether or not an exception is thrown by the try clause. ses” on page 70

Reserved Words | 49

Download at WoweBook.Com
Word Description See …
for Start a for comprehension (loop). “Scala for Comprehen-
sions” on page 59
forSome Used in existential type declarations to constrain the allowed “Existential Types” on page 284
concrete types that can be used.
if Start an if clause. “Scala if Statements” on page 58
implicit Marks a method as eligible to be used as an implicit type converter. “Implicit Conversions” on page 186
Marks a method parameter as optional, as long as a type-
compatible substitute object is in the scope where the method is
called.
import Import one or more types or members of types into the current “Importing Types and Their Mem-
scope. bers” on page 45
lazy Defer evaluation of a val. “Lazy Vals” on page 190
match Start a pattern matching clause. “Pattern Matching” on page 63
new Create a new instance of a class. “Class and Object Basics” on page 89
null Value of a reference variable that has not been assigned a value. “The Scala Type Hierarchy”
on page 155
object Start a singleton declaration: a class with only one instance. “Classes and Objects: Where Are the
Statics?” on page 148
override Override a concrete member of a class or trait, as long as the original “Overriding Members of Classes and
is not marked final. Traits” on page 111
package Start a package scope declaration. “Organizing Code in Files and Namespa-
ces” on page 44
private Restrict visibility of a declaration. “Visibility Rules” on page 96
protected Restrict visibility of a declaration. “Visibility Rules” on page 96
requires Deprecated. Was used for self typing. “The Scala Type Hierarchy”
on page 155
return Return from a function. “A Taste of Scala” on page 10
sealed Applied to a parent class to require all directly derived “Case Classes” on page 136
classes to be declared in the same source file.
super Analogous to this, but binds to the parent type. “Overriding Abstract and Concrete
Methods” on page 112
this How an object refers to itself. The method name for auxiliary “Class and Object Basics” on page 89
constructors.
throw Throw an exception. “Using try, catch, and finally Clau-
ses” on page 70
trait A mixin module that adds additional state and behavior to an Chapter 4
instance of a class.
try Start a block that may throw an exception. “Using try, catch, and finally Clau-
ses” on page 70

50 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
Word Description See …
true Boolean true. “The Scala Type Hierarchy”
on page 155
type Start a type declaration. “Abstract Types And Parameterized
Types” on page 47
val Start a read-only “variable” declaration. “Variable Declarations” on page 24
var Start a read-write variable declaration. “Variable Declarations” on page 24
while Start a while loop. “Other Looping Constructs”
on page 61
with Include the trait that follows in the class being declared or the object Chapter 4
being instantiated.
yield Return an element in a for comprehension that becomes part of “Yielding” on page 60
a sequence.
_ A placeholder, used in imports, function literals, etc. Many
: Separator between identifiers and type annotations. “A Taste of Scala” on page 10
= Assignment. “A Taste of Scala” on page 10
=> Used in function literals to separate the argument list from the “Function Literals and Clo-
function body. sures” on page 169
<- Used in for comprehensions in generator expressions. “Scala for Comprehen-
sions” on page 59
<: Used in parameterized and abstract type declarations to constrain “Type Bounds” on page 259
the allowed types.
<% Used in parameterized and abstract type “view bounds” “Type Bounds” on page 259
declarations.
>: Used in parameterized and abstract type declarations to constrain “Type Bounds” on page 259
the allowed types.
# Used in type projections. “Path-Dependent Types” on page 272
@ Marks an annotation. “Annotations” on page 289
º (Unicode \u21D2) Same as =>. “Function Literals and Clo-
sures” on page 169
← (Unicode \u2190) Same as <-. “Scala for Comprehen-
sions” on page 59

1RWLFHWKDW breakDQG continueDUHQRWOLVWHG7KHVHFRQWURONH\ZRUGVGRQ¦WH[LVWLQ


6FDOD,QVWHDG6FDODHQFRXUDJHV\RXWRXVHIXQFWLRQDOSURJUDPPLQJLGLRPVWKDWDUH
XVXDOO\PRUHVXFFLQFWDQGOHVVHUURUSURQH:H¦OOGLVFXVVDOWHUQDWLYHDSSURDFKHVZKHQ
ZHGLVFXVVforORRSV VHH£*HQHUDWRU([SUHVVLRQV¤RQSDJH 
6RPH -DYD PHWKRGV XVH QDPHV WKDW DUH UHVHUYHG E\ 6FDOD IRU H[DPSOH
java.util.Scanner.match7RDYRLGDFRPSLODWLRQHUURUVXUURXQGWKHQDPHZLWKVLQJOH
EDFNTXRWHVHJjava.util.Scanner.ÂmatchÂ

Reserved Words | 51

Download at WoweBook.Com
Recap and What’s Next
:HFRYHUHGVHYHUDOZD\VWKDW6FDOD¦VV\QWD[LVFRQFLVHIOH[LEOHDQGSURGXFWLYH:H
DOVRGHVFULEHGPDQ\6FDODIHDWXUHV,QWKHQH[WFKDSWHUZHZLOOURXQGRXWVRPH6FDOD
HVVHQWLDOV EHIRUH ZH GLYH LQWR 6FDOD¦V VXSSRUW IRU REMHFWRULHQWHG SURJUDPPLQJ DQG
IXQFWLRQDOSURJUDPPLQJ

52 | Chapter 2:—Type Less, Do More

Download at WoweBook.Com
CHAPTER 3
Rounding Out the Essentials

%HIRUHZHGLYHLQWR6FDOD¦VVXSSRUWIRUREMHFWRULHQWHGDQGIXQFWLRQDOSURJUDPPLQJ
OHW¦VILQLVKRXUGLVFXVVLRQRIWKHHVVHQWLDOIHDWXUHV\RX¦OOXVHLQPRVWRI\RXUSURJUDPV

Operator? Operator?
$QLPSRUWDQWIXQGDPHQWDOFRQFHSWLQ6FDODLVWKDWDOORSHUDWRUVDUHDFWXDOO\PHWKRGV
&RQVLGHUWKLVPRVWEDVLFRIH[DPSOHV
// code-examples/Rounding/one-plus-two-script.scala

1 + 2

7KDW SOXV VLJQ EHWZHHQ WKH QXPEHUV" ,W¦V D PHWKRG )LUVW 6FDOD DOORZV QRQ
DOSKDQXPHULFPHWKRGQDPHV<RXFDQFDOOPHWKRGV + - $RUZKDWHYHU\RXGHVLUH
6HFRQGWKLVH[SUHVVLRQLVLGHQWLFDOWR1 .+(2) :HSXWDVSDFHDIWHUWKH1EHFDXVH1.
ZRXOGEHLQWHUSUHWHGDVDDouble :KHQDPHWKRGWDNHVRQHDUJXPHQW6FDODOHWV\RX
GURS ERWK WKH SHULRG DQG WKH SDUHQWKHVHV VR WKH PHWKRG LQYRFDWLRQ ORRNV OLNH DQ
RSHUDWRULQYRFDWLRQ7KLVLVFDOOHG£LQIL[¤QRWDWLRQZKHUHWKHRSHUDWRULVEHWZHHQWKH
LQVWDQFHDQGWKHDUJXPHQW:H¦OOILQGRXWPRUHDERXWWKLVVKRUWO\
6LPLODUO\DPHWKRGZLWKQRDUJXPHQWVFDQEHLQYRNHGZLWKRXWWKHSHULRG7KLVLVFDOOHG
£SRVWIL[¤QRWDWLRQ
5XE\DQG6PDOOWDONSURJUDPPHUVVKRXOGQRZIHHOULJKWDWKRPH$VXVHUVRIWKRVH
ODQJXDJHVNQRZWKHVHVLPSOHUXOHVKDYHIDUUHDFKLQJEHQHILWVZKHQLWFRPHVWRFUHDWLQJ
SURJUDPVWKDWIORZQDWXUDOO\DQGHOHJDQWO\
6RZKDWFKDUDFWHUVFDQ\RXXVHLQLGHQWLILHUV"+HUHLVDVXPPDU\RIWKHUXOHVIRULGHQ
WLILHUV XVHG IRU PHWKRG DQG W\SH QDPHV YDULDEOHV HWF )RU WKH SUHFLVH GHWDLOV VHH
>6FDOD6SHF@6FDODDOORZVDOOWKHSULQWDEOH$6&,,FKDUDFWHUVVXFKDVOHWWHUVGLJLWV
WKHXQGHUVFRUH _ DQGWKHGROODUVLJQ $ ZLWKWKHH[FHSWLRQVRIWKH£SDUHQWKHWLFDO¤
FKDUDFWHUV¢()[]{DQG}¢DQGWKH£GHOLPLWHU¤FKDUDFWHUV¢`’'".;DQG,
6FDODDOORZVWKHRWKHUFKDUDFWHUVEHWZHHQ?X¡?X)WKDWDUHQRWLQWKHVHWVMXVW

53

Download at WoweBook.Com
VKRZQVXFKDVPDWKHPDWLFDOV\PEROVDQG£RWKHU¤V\PEROV7KHVHUHPDLQLQJFKDUDF
WHUVDUHFDOOHGRSHUDWRUFKDUDFWHUVDQGWKH\LQFOXGHFKDUDFWHUVVXFKDV/<HWF
5HVHUYHGZRUGVFDQ¦WEHXVHG
$VLQPRVWODQJXDJHV\RXFDQ¦WUHXVHUHVHUYHGZRUGVIRULGHQWLILHUV:HOLVWHGWKH
UHVHUYHGZRUGVLQ£5HVHUYHG:RUGV¤RQSDJH5HFDOOWKDWVRPHRIWKHPDUH
FRPELQDWLRQVRIRSHUDWRUDQGSXQFWXDWLRQFKDUDFWHUV)RUH[DPSOHDVLQJOHXQ
GHUVFRUH _ LVDUHVHUYHGZRUG
3ODLQLGHQWLILHUV¢FRPELQDWLRQVRIOHWWHUVGLJLWV$_DQGRSHUDWRUV
/LNH-DYDDQGPDQ\ODQJXDJHVDSODLQLGHQWLILHUFDQEHJLQZLWKDOHWWHURUXQGHU
VFRUH IROORZHG E\ PRUH OHWWHUV GLJLWV XQGHUVFRUHV DQG GROODU VLJQV 8QLFRGH
HTXLYDOHQWFKDUDFWHUVDUHDOVRDOORZHG+RZHYHUOLNH-DYD6FDODUHVHUYHVWKHGROODU
VLJQ IRU LQWHUQDO XVH VR \RX VKRXOGQ¦W XVH LW LQ \RXU RZQ LGHQWLILHUV $IWHU DQ
XQGHUVFRUH\RXFDQKDYHHLWKHUOHWWHUVDQGGLJLWVRUDVHTXHQFHRIRSHUDWRUFKDU
DFWHUV7KHXQGHUVFRUHLVLPSRUWDQW,WWHOOVWKHFRPSLOHUWRWUHDWDOOWKHFKDUDFWHUV
XSWRWKHQH[WZKLWHVSDFHDVSDUWRIWKHLGHQWLILHU)RUH[DPSOHval xyz_++= = 1
DVVLJQVWKHYDULDEOHxyz_++=WKHYDOXH1ZKLOHWKHH[SUHVVLRQval xyz++= = 1ZRQ¦W
FRPSLOHEHFDXVHWKH£LGHQWLILHU¤FRXOGDOVREHLQWHUSUHWHGDVxyz ++=ZKLFKORRNV
OLNHDQDWWHPSWWRDSSHQGVRPHWKLQJWRxyz6LPLODUO\LI\RXKDYHRSHUDWRUFKDU
DFWHUVDIWHUWKHXQGHUVFRUH\RXFDQ¦WPL[WKHPZLWKOHWWHUVDQGGLJLWV7KLVUH
VWULFWLRQSUHYHQWVDPELJXRXVH[SUHVVLRQVOLNHWKLV abc_=123,VWKDWDQLGHQWLILHU
abc_=123RUDQDVVLJQPHQWRIWKHYDOXH123WRabc_"
3ODLQLGHQWLILHUV¢RSHUDWRUV
,IDQLGHQWLILHUEHJLQVZLWKDQRSHUDWRUFKDUDFWHUWKHUHVWRIWKHFKDUDFWHUVPXVW
EHRSHUDWRUFKDUDFWHUV
£%DFNTXRWH¤OLWHUDOV
$QLGHQWLILHUFDQDOVREHDQDUELWUDU\VWULQJ VXEMHFWWRSODWIRUPOLPLWDWLRQV EH
WZHHQWZREDFNTXRWHFKDUDFWHUVHJval `this is a valid identifier` = "Hello
World!"5HFDOOWKDWWKLVV\QWD[LVDOVRWKHZD\WRLQYRNHDPHWKRGRQD-DYDRU1(7
FODVV ZKHQ WKH PHWKRG¦V QDPH LV LGHQWLFDO WR D 6FDOD UHVHUYHG ZRUG HJ
java.net.Proxy.ÂtypeÂ()
3DWWHUQPDWFKLQJLGHQWLILHUV
,Q SDWWHUQ PDWFKLQJ H[SUHVVLRQV WRNHQV WKDW EHJLQ ZLWK D ORZHUFDVH OHWWHU DUH
SDUVHGDVYDULDEOHLGHQWLILHUVZKLOHWRNHQVWKDWEHJLQZLWKDQXSSHUFDVHOHWWHUDUH
SDUVHGDVFRQVWDQWLGHQWLILHUV7KLVUHVWULFWLRQSUHYHQWVVRPHDPELJXLWLHVEHFDXVH
RIWKHYHU\VXFFLQFWYDULDEOHV\QWD[WKDWLVXVHGHJQRvalNH\ZRUGLVSUHVHQW

Syntactic Sugar
2QFH\RXNQRZWKDWDOORSHUDWRUVDUHPHWKRGVLW¦VHDVLHUWRUHDVRQDERXWXQIDPLOLDU
6FDODFRGH<RXGRQ¦WKDYHWRZRUU\DERXWVSHFLDOFDVHVZKHQ\RXVHHQHZRSHUDWRUV
:KHQZRUNLQJZLWK$FWRUVLQ£$7DVWHRI&RQFXUUHQF\¤RQSDJH\RXPD\KDYH
QRWLFHGWKDWZHXVHGDQH[FODPDWLRQSRLQW ! WRVHQGDPHVVDJHWRDQ$FWRU1RZ\RX

54 | Chapter 3:—Rounding Out the Essentials

Download at WoweBook.Com
NQRZWKDWWKH!LVMXVWDQRWKHUPHWKRGDVDUHWKHRWKHUKDQG\VKRUWFXWRSHUDWRUV\RX
FDQXVHWRWDONWR$FWRUV6LPLODUO\6FDOD¦V;0/OLEUDU\SURYLGHVWKH\DQG\\RSHUDWRUV
WRGLYHLQWRGRFXPHQWVWUXFWXUHV7KHVHDUHMXVWPHWKRGVRQWKH scala.xml.NodeSeq
FODVV
7KLVIOH[LEOHPHWKRGQDPLQJJLYHV\RXWKHSRZHUWRZULWHOLEUDULHVWKDWIHHOOLNHDQDWXUDO
H[WHQVLRQRI6FDODLWVHOI<RXFRXOGZULWHDQHZPDWKOLEUDU\ZLWKQXPHULFW\SHVWKDW
DFFHSWDOOWKHXVXDOPDWKHPDWLFDORSHUDWRUVOLNHDGGLWLRQDQGVXEWUDFWLRQ<RXFRXOG
ZULWHDQHZFRQFXUUHQWPHVVDJLQJOD\HUWKDWEHKDYHVMXVWOLNH$FWRUV7KHSRVVLELOLWLHV
DUHFRQVWUDLQHGRQO\E\6FDOD¦VPHWKRGQDPLQJOLPLWDWLRQV

-XVWEHFDXVH\RXFDQGRHVQ¦WPHDQ\RXVKRXOG:KHQGHVLJQLQJ\RXU
RZQOLEUDULHVDQG$3,VLQ6FDODNHHSLQPLQGWKDWREVFXUHSXQFWXDWLRQDO
RSHUDWRUVDUHKDUGIRUSURJUDPPHUVWRUHPHPEHU2YHUXVHRIWKHVHFDQ
FRQWULEXWHD£OLQHQRLVH¤TXDOLW\RIXQUHDGDELOLW\WR\RXUFRGH6WLFNWR
FRQYHQWLRQVDQGHUURQWKHVLGHRIVSHOOLQJPHWKRGQDPHVRXWZKHQD
VKRUWFXWGRHVQ¦WFRPHUHDGLO\WRPLQG

Methods Without Parentheses and Dots


7RIDFLOLWDWHDYDULHW\RIUHDGDEOHSURJUDPPLQJVW\OHV6FDODLVIOH[LEOHDERXWWKHXVHRI
SDUHQWKHVHVLQPHWKRGV,IDPHWKRGWDNHVQRSDUDPHWHUV\RXFDQGHILQHLWZLWKRXW
SDUHQWKHVHV&DOOHUVPXVWLQYRNHWKHPHWKRGZLWKRXWSDUHQWKHVHV,I\RXDGGHPSW\
SDUHQWKHVHV WKHQ FDOOHUV PD\ RSWLRQDOO\ DGG SDUHQWKHVHV )RU H[DPSOH WKH size
PHWKRGIRUListKDVQRSDUHQWKHVHVVR\RXZULWHList(1, 2, 3).size,I\RXWU\List(1,
2, 3).size()\RX¦OOJHWDQHUURU+RZHYHUWKH lengthPHWKRGIRU java.lang.String
GRHV KDYH SDUHQWKHVHV LQ LWV GHILQLWLRQ EXW 6FDOD OHWV \RX ZULWH ERWK
"hello".length()DQG"hello".length
7KHFRQYHQWLRQLQWKH6FDODFRPPXQLW\LVWRRPLWSDUHQWKHVHVZKHQFDOOLQJDPHWKRG
WKDWKDVQRVLGHHIIHFWV6RDVNLQJIRUWKHVL]HRIDVHTXHQFHLVILQHZLWKRXWSDUHQWKHVHV
EXWGHILQLQJDPHWKRGWKDWWUDQVIRUPVWKHHOHPHQWVLQWKHVHTXHQFHVKRXOGEHZULWWHQ
ZLWKSDUHQWKHVHV7KLVFRQYHQWLRQVLJQDOVDSRWHQWLDOO\WULFN\PHWKRGIRUXVHUVRI\RXU
FRGH
,W¦VDOVRSRVVLEOHWRRPLWWKHGRW SHULRG ZKHQFDOOLQJDSDUDPHWHUOHVVPHWKRGRURQH
WKDWWDNHVRQO\RQHDUJXPHQW:LWKWKLVLQPLQGRXU List(1, 2, 3).sizeH[DPSOH
FRXOGEHZULWWHQDV
// code-examples/Rounding/no-dot-script.scala

List(1, 2, 3) size

1HDW EXW FRQIXVLQJ :KHQ GRHV WKLV V\QWDFWLFDO IOH[LELOLW\ EHFRPH XVHIXO" :KHQ
FKDLQLQJPHWKRGFDOOVWRJHWKHULQWRH[SUHVVLYHVHOIH[SODQDWRU\£VHQWHQFHV¤RIFRGH

Methods Without Parentheses and Dots | 55

Download at WoweBook.Com
// code-examples/Rounding/no-dot-better-script.scala

def isEven(n: Int) = (n % 2) == 0

List(1, 2, 3, 4) filter isEven foreach println

$V\RXPLJKWJXHVVUXQQLQJWKLVSURGXFHVWKHIROORZLQJRXWSXW
2
4

6FDOD¦VOLEHUDODSSURDFKWRSDUHQWKHVHVDQGGRWVRQPHWKRGVSURYLGHVRQHEXLOGLQJ
EORFNIRUZULWLQJ'RPDLQ6SHFLILF/DQJXDJHV:H¦OOOHDUQPRUHDERXWWKHPDIWHUDEULHI
GLVFXVVLRQRIRSHUDWRUSUHFHGHQFH

Precedence Rules
6RLIDQH[SUHVVLRQOLNH2.0 * 4.0 / 3.0 * 5.0LVDFWXDOO\DVHULHVRIPHWKRGFDOOVRQ
DoubleVZKDWDUHWKHRSHUDWRUSUHFHGHQFHUXOHV"+HUHWKH\DUHLQRUGHUIURPORZHVWWR
KLJKHVWSUHFHGHQFH VHH>6FDOD6SHF@ 
 $OOOHWWHUV
 |
 ^
 &
 < >
 = !
 :
 + -
 * / %
 $OORWKHUVSHFLDOFKDUDFWHUV
&KDUDFWHUVRQWKHVDPHOLQHKDYHWKHVDPHSUHFHGHQFH$QH[FHSWLRQLV =ZKHQXVHG
IRUDVVLJQPHQWZKHQLWKDVWKHORZHVWSUHFHGHQFH
6LQFH DQGKDYHWKHVDPHSUHFHGHQFHWKHWZROLQHVLQWKHIROORZLQJ scalaVHVVLRQ
EHKDYHWKHVDPH
scala> 2.0 * 4.0 / 3.0 * 5.0
res2: Double = 13.333333333333332

scala> (((2.0 * 4.0) / 3.0) * 5.0)


res3: Double = 13.333333333333332

,QDVHTXHQFHRIOHIWDVVRFLDWLYHPHWKRGLQYRFDWLRQVWKH\VLPSO\ELQGLQOHIWWRULJKW
RUGHU£/HIWDVVRFLDWLYH¤\RXVD\",Q6FDODDQ\PHWKRGZLWKDQDPHWKDWHQGVZLWKD
FRORQ:DFWXDOO\ELQGVWRWKHULJKWZKLOHDOORWKHUPHWKRGVELQGWRWKHOHIW)RUH[DPSOH

56 | Chapter 3:—Rounding Out the Essentials

Download at WoweBook.Com
\RXFDQSUHSHQGDQHOHPHQWWRD ListXVLQJWKH ::PHWKRG FDOOHG£FRQV¤VKRUWIRU
£FRQVWUXFWRU¤ 
scala> val list = List('b', 'c', 'd')
list: List[Char] = List(b, c, d)

scala> 'a' :: list


res4: List[Char] = List(a, b, c, d)

7KHVHFRQGH[SUHVVLRQLVHTXLYDOHQWWR list.::(a),QDVHTXHQFHRIULJKWDVVRFLDWLYH
PHWKRGLQYRFDWLRQVWKH\ELQGIURPULJKWWROHIW:KDWDERXWDPL[WXUHRIOHIWELQGLQJ
DQGULJKWELQGLQJH[SUHVVLRQV"
scala> 'a' :: list ++ List('e', 'f')
res5: List[Char] = List(a, b, c, d, e, f)

7KH++PHWKRGDSSHQGVWZROLVWV ,QWKLVFDVHlistLVDGGHGWRWKHList(e, f)WKHQ


aLVSUHSHQGHGWRFUHDWHWKHILQDOOLVW,W¦VXVXDOO\EHWWHUWRDGGSDUHQWKHVHVWRUHPRYH
DQ\SRWHQWLDOXQFHUWDLQW\

$Q\PHWKRGZKRVHQDPHHQGVZLWKD:ELQGVWRWKHULJKWQRWWKHOHIW

)LQDOO\QRWHWKDWZKHQ\RXXVHWKHscalaFRPPDQGHLWKHULQWHUDFWLYHO\RUZLWKVFULSWV
LWPD\DSSHDUWKDW\RXFDQGHILQH£JOREDO¤YDULDEOHVDQGPHWKRGVRXWVLGHRIW\SHV7KLV
LVDFWXDOO\DQLOOXVLRQWKHLQWHUSUHWHUZUDSVDOOGHILQLWLRQVLQDQDQRQ\PRXVW\SHEHIRUH
JHQHUDWLQJ-90RU1(7&/5E\WHFRGH

Domain-Specific Languages
'RPDLQ6SHFLILF/DQJXDJHVRU'6/VSURYLGHDFRQYHQLHQWV\QWDFWLFDOPHDQVIRUH[
SUHVVLQJJRDOVLQDJLYHQSUREOHPGRPDLQ)RUH[DPSOH64/SURYLGHVMXVWHQRXJKRI
DSURJUDPPLQJODQJXDJHWRKDQGOHWKHSUREOHPVRIZRUNLQJZLWKGDWDEDVHVPDNLQJ
LWD'RPDLQ6SHFLILF/DQJXDJH
:KLOHVRPH'6/VOLNH64/DUHVHOIFRQWDLQHGLW¦VEHFRPHSRSXODUWRLPSOHPHQW'6/V
DVVXEVHWVRIIXOOIOHGJHGSURJUDPPLQJODQJXDJHV7KLVDOORZVSURJUDPPHUVWROHYHUDJH
WKHHQWLUHW\RIWKHKRVWODQJXDJHIRUHGJHFDVHVWKDWWKH'6/GRHVQRWFRYHUDQGVDYHV
WKHZRUNRIZULWLQJOH[HUVSDUVHUVDQGWKHRWKHUEXLOGLQJEORFNVRIDODQJXDJH
6FDOD¦VULFKIOH[LEOHV\QWD[PDNHVZULWLQJ'6/VDEUHH]H&RQVLGHUWKLVH[DPSOHRID
VW\OHRIWHVWZULWLQJFDOOHG%HKDYLRU'ULYHQ'HYHORSPHQW VHH>%''@ XVLQJWKH6SHFV
OLEUDU\ VHH£6SHFV¤RQSDJH 
// code-examples/Rounding/specs-script.scala

"nerd finder" should {

Domain-Specific Languages | 57

Download at WoweBook.Com
"identify nerds from a List" in {
val actors = List("Rick Moranis", "James Dean", "Woody Allen")
val finder = new NerdFinder(actors)
finder.findNerds mustEqual List("Rick Moranis", "Woody Allen")
}
}

1RWLFHKRZPXFKWKLVFRGHUHDGVOLNH(QJOLVK£7KLVVKRXOGWHVWWKDWLQWKHIROORZLQJ
VFHQDULR¤ £7KLV YDOXH PXVW HTXDO WKDW YDOXH¤ DQG VR IRUWK 7KLV H[DPSOH XVHV WKH
VXSHUE6SHFVOLEUDU\ZKLFKHIIHFWLYHO\SURYLGHVD'6/IRUWKH%HKDYLRU'ULYHQ'HYHO
RSPHQWWHVWLQJDQGHQJLQHHULQJPHWKRGRORJ\%\PDNLQJPD[LPXPXVHRI6FDOD¦VOLE
HUDOV\QWD[DQGULFKPHWKRGV6SHFVWHVWVXLWHVDUHUHDGDEOHHYHQE\QRQGHYHORSHUV
7KLVLVMXVWDWDVWHRIWKHSRZHURI'6/VLQ6FDOD:H¦OOVHHRWKHUH[DPSOHVODWHUDQG
OHDUQKRZWRZULWHRXURZQDVZHJHWPRUHDGYDQFHG VHH&KDSWHU 

Scala if Statements
(YHQWKHPRVWIDPLOLDUODQJXDJHIHDWXUHVDUHVXSHUFKDUJHGLQ6FDOD/HW¦VKDYHDORRN
DWWKHORZO\ifVWDWHPHQW$VLQPRVWHYHU\ODQJXDJH6FDOD¦VifHYDOXDWHVDFRQGLWLRQDO
H[SUHVVLRQWKHQSURFHHGVWRDEORFNLIWKHUHVXOWLV trueRUEUDQFKHVWRDQDOWHUQDWH
EORFNLIWKHUHVXOWLVfalse$VLPSOHH[DPSOH
// code-examples/Rounding/if-script.scala

if (2 + 2 == 5) {
println("Hello from 1984.")
} else if (2 + 2 == 3) {
println("Hello from Remedial Math class?")
} else {
println("Hello from a non-Orwellian future.")
}

:KDW¦VGLIIHUHQWLQ6FDODLVWKDWifDQGDOPRVWDOORWKHUVWDWHPHQWVDUHDFWXDOO\H[SUHV
VLRQVWKHPVHOYHV6RZHFDQDVVLJQWKHUHVXOWRIDQifH[SUHVVLRQDVVKRZQKHUH
// code-examples/Rounding/assigned-if-script.scala

val configFile = new java.io.File("~/.myapprc")

val configFilePath = if (configFile.exists()) {


configFile.getAbsolutePath()
} else {
configFile.createNewFile()
configFile.getAbsolutePath()
}

1RWHWKDW ifVWDWHPHQWVDUHH[SUHVVLRQVPHDQLQJWKH\KDYHYDOXHV,QWKLVH[DPSOH
WKHYDOXH configFilePathLVWKHUHVXOWRIDQ ifH[SUHVVLRQWKDWKDQGOHVWKHFDVHRID
FRQILJXUDWLRQILOHQRWH[LVWLQJLQWHUQDOO\WKHQUHWXUQVWKHDEVROXWHSDWKWRWKDWILOH7KLV
YDOXHFDQQRZEHUHXVHGWKURXJKRXWDQDSSOLFDWLRQDQGWKH ifH[SUHVVLRQZRQ¦WEH
UHHYDOXDWHGZKHQWKHYDOXHLVXVHG

58 | Chapter 3:—Rounding Out the Essentials

Download at WoweBook.Com
%HFDXVH ifVWDWHPHQWVDUHH[SUHVVLRQVLQ6FDODWKHUHLVQRQHHGIRUWKHVSHFLDOFDVH
WHUQDU\FRQGLWLRQDOH[SUHVVLRQVWKDWH[LVWLQ&GHULYHGODQJXDJHV<RXZRQ¦WVHH x ?
doThis() : doThat()LQ6FDOD6FDODSURYLGHVDPHFKDQLVPWKDW¦VMXVWDVSRZHUIXODQG
PRUHUHDGDEOH
:KDW LI ZH RPLW WKH else FODXVH LQ WKH SUHYLRXV H[DPSOH" 7\SLQJ WKH FRGH LQ WKH
scalaLQWHUSUHWHUZLOOWHOOXVZKDWKDSSHQV
scala> val configFile = new java.io.File("~/.myapprc")
configFile: java.io.File = ~/.myapprc

scala> val configFilePath = if (configFile.exists()) {


| configFile.getAbsolutePath()
| }
configFilePath: Unit = ()

scala>

1RWHWKDWconfigFilePathLVQRZUnit ,WZDVStringEHIRUH 7KHW\SHLQIHUHQFHSLFNV


DW\SHWKDWZRUNVIRUDOORXWFRPHVRIWKHifH[SUHVVLRQUnitLVWKHRQO\SRVVLELOLW\VLQFH
QRYDOXHLVRQHSRVVLEOHRXWFRPH

Scala for Comprehensions


$QRWKHU IDPLOLDU FRQWURO VWUXFWXUH WKDW¦V SDUWLFXODUO\ IHDWXUHULFK LQ 6FDOD LV WKH for
ORRSUHIHUUHGWRLQWKH6FDODFRPPXQLW\DVDforFRPSUHKHQVLRQRUforH[SUHVVLRQ7KLV
FRUQHURIWKHODQJXDJHGHVHUYHVDWOHDVWRQHIDQF\QDPHEHFDXVHLWFDQGRVRPHJUHDW
SDUW\WULFNV
$FWXDOO\WKHWHUPcomprehensionFRPHVIURPIXQFWLRQDOSURJUDPPLQJ,WH[SUHVVHVWKH
LGHDWKDWZHDUHWUDYHUVLQJDVHWRIVRPHNLQG£FRPSUHKHQGLQJ¤ZKDWZHILQGDQG
FRPSXWLQJVRPHWKLQJQHZIURPLW

A Dog-Simple Example
/HW¦VVWDUWZLWKDEDVLFforH[SUHVVLRQ
// code-examples/Rounding/basic-for-script.scala

val dogBreeds = List("Doberman", "Yorkshire Terrier", "Dachshund",


"Scottish Terrier", "Great Dane", "Portuguese Water Dog")

for (breed <- dogBreeds)


println(breed)

$V\RXPLJKWJXHVVWKLVFRGHVD\V£)RUHYHU\HOHPHQWLQWKHOLVW dogBreedsFUHDWHD
WHPSRUDU\YDULDEOHFDOOHGbreedZLWKWKHYDOXHRIWKDWHOHPHQWWKHQSULQWLW¤7KLQNRI
WKH<-RSHUDWRUDVDQDUURZGLUHFWLQJHOHPHQWVRIDFROOHFWLRQRQHE\RQHWRWKHVFRSHG
YDULDEOHE\ZKLFKZH¦OOUHIHUWRWKHPLQVLGHWKHforH[SUHVVLRQ7KHOHIWDUURZRSHUDWRU

Scala for Comprehensions | 59

Download at WoweBook.Com
LVFDOOHGDJHQHUDWRUVRQDPHGEHFDXVHLW¦VJHQHUDWLQJLQGLYLGXDOYDOXHVIURPDFROOHF
WLRQIRUXVHLQDQH[SUHVVLRQ

Filtering
:KDWLIZHZDQWWRJHWPRUHJUDQXODU"6FDOD¦VforH[SUHVVLRQVDOORZIRUILOWHUVWKDWOHW
XVVSHFLI\ZKLFKHOHPHQWVRIDFROOHFWLRQZHZDQWWRZRUNZLWK6RWRILQGDOOWHUULHUV
LQRXUOLVWRIGRJEUHHGVZHFRXOGPRGLI\WKHSUHYLRXVH[DPSOHWRWKHIROORZLQJ
// code-examples/Rounding/filtered-for-script.scala

for (breed <- dogBreeds


if breed.contains("Terrier")
) println(breed)

7RDGGPRUHWKDQRQHILOWHUWRDforH[SUHVVLRQVHSDUDWHWKHILOWHUVZLWKVHPLFRORQV
// code-examples/Rounding/double-filtered-for-script.scala

for (breed <- dogBreeds


if breed.contains("Terrier");
if !breed.startsWith("Yorkshire")
) println(breed)

<RX¦YHQRZIRXQGDOOWKHWHUULHUVWKDWGRQ¦WKDLOIURP<RUNVKLUHDQGKRSHIXOO\OHDUQHG
MXVWKRZXVHIXOILOWHUVFDQEHLQWKHSURFHVV

Yielding
:KDW LI UDWKHU WKDQ SULQWLQJ \RXU ILOWHUHG FROOHFWLRQ \RX QHHGHG WR KDQG LW RII WR
DQRWKHUSDUWRI\RXUSURJUDP"7KH yieldNH\ZRUGLV\RXUWLFNHWWRJHQHUDWLQJQHZ
FROOHFWLRQVZLWK forH[SUHVVLRQV,QWKHIROORZLQJH[DPSOHQRWHWKDWZH¦UHZUDSSLQJ
XSWKHforH[SUHVVLRQLQFXUO\EUDFHVDVZHZRXOGZKHQGHILQLQJDQ\EORFN
// code-examples/Rounding/yielding-for-script.scala

val filteredBreeds = for {


breed <- dogBreeds
if breed.contains("Terrier")
if !breed.startsWith("Yorkshire")
} yield breed

forH[SUHVVLRQVPD\EHGHILQHGZLWKSDUHQWKHVHVRUFXUO\EUDFHVEXW
XVLQJFXUO\EUDFHVPHDQV\RXGRQ¦WKDYHWRVHSDUDWH\RXUILOWHUVZLWK
VHPLFRORQV0RVWRIWKHWLPH\RX¦OOSUHIHUXVLQJFXUO\EUDFHVZKHQ\RX
KDYHPRUHWKDQRQHILOWHUDVVLJQPHQWHWF

(YHU\WLPHWKURXJKWKH forH[SUHVVLRQWKHILOWHUHGUHVXOWLV\LHOGHGDVDYDOXHQDPHG
breed7KHVHUHVXOWVDFFXPXODWHZLWKHYHU\UXQDQGWKHUHVXOWLQJFROOHFWLRQLVDVVLJQHG
WR WKH YDOXH filteredBreeds DV ZH GLG ZLWK if VWDWHPHQWV HDUOLHU  7KH W\SH RI WKH

60 | Chapter 3:—Rounding Out the Essentials

Download at WoweBook.Com
FROOHFWLRQUHVXOWLQJIURPDfor-yieldH[SUHVVLRQLVLQIHUUHGIURPWKHW\SHRIWKHFROOHF
WLRQEHLQJLWHUDWHGRYHU,QWKLVFDVHfilteredBreedsLVRIW\SHList[String]VLQFHLWLV
DVXEVHWRIWKHdogBreedsOLVWZKLFKLVDOVRRIW\SHList[String]

Expanded Scope
2QHILQDOXVHIXOIHDWXUHRI6FDOD¦VforFRPSUHKHQVLRQVLVWKHDELOLW\WRGHILQHYDULDEOHV
LQVLGHWKHILUVWSDUWRI\RXUforH[SUHVVLRQVWKDWFDQEHXVHGLQWKHODWWHUSDUW7KLVLV
EHVWLOOXVWUDWHGZLWKDQH[DPSOH
// code-examples/Rounding/scoped-for-script.scala

for {
breed <- dogBreeds
upcasedBreed = breed.toUpperCase()
} println(upcasedBreed)

1RWHWKDWZLWKRXWGHFODULQJupcasedBreedDVDval\RXFDQUHXVHLWZLWKLQWKHERG\RI
\RXU forH[SUHVVLRQ7KLVDSSURDFKLVLGHDOIRUWUDQVIRUPLQJHOHPHQWVLQDFROOHFWLRQ
DV\RXORRSWKURXJKWKHP
)LQDOO\ LQ £2SWLRQV DQG IRU &RPSUHKHQVLRQV¤ RQ SDJH  ZH¦OO VHH KRZ XVLQJ
OptionsZLWK forFRPSUHKHQVLRQVFDQJUHDWO\UHGXFHFRGHVL]HE\HOLPLQDWLQJXQQHF
HVVDU\£QXOO¤DQG£PLVVLQJ¤FKHFNV

Other Looping Constructs


6FDODSURYLGHVVHYHUDORWKHUORRSLQJFRQVWUXFWV

Scala while Loops


)DPLOLDULQPDQ\ODQJXDJHVWKHwhileORRSH[HFXWHVDEORFNRIFRGHDVORQJDVDFRQ
GLWLRQLVWUXH)RUH[DPSOHWKHIROORZLQJFRGHSULQWVRXWDFRPSODLQWRQFHDGD\XQWLO
WKHQH[W)ULGD\WKHWKKDVDUULYHG
// code-examples/Rounding/while-script.scala
// WARNING: This script runs for a LOOOONG time!

import java.util.Calendar

def isFridayThirteen(cal: Calendar): Boolean = {


val dayOfWeek = cal.get(Calendar.DAY_OF_WEEK)
val dayOfMonth = cal.get(Calendar.DAY_OF_MONTH)

// Scala returns the result of the last expression in a method


(dayOfWeek == Calendar.FRIDAY) && (dayOfMonth == 13)
}

while (!isFridayThirteen(Calendar.getInstance())) {
println("Today isn't Friday the 13th. Lame.")

Other Looping Constructs | 61

Download at WoweBook.Com
// sleep for a day
Thread.sleep(86400000)
}

7DEOHODWHULQWKLVFKDSWHUVKRZVWKHFRQGLWLRQDORSHUDWRUVWKDWZRUNLQwhileORRSV

Scala do-while Loops


/LNHWKHwhileORRSDdo-whileORRSH[HFXWHVVRPHFRGHZKLOHDFRQGLWLRQDOH[SUHVVLRQ
LVWUXH7KHRQO\GLIIHUHQFHWKDWD do-whileFKHFNVWRVHHLIWKHFRQGLWLRQLVWUXHDIWHU
UXQQLQJWKHEORFN7RFRXQWXSWRZHFRXOGZULWHWKLV
// code-examples/Rounding/do-while-script.scala

var count = 0

do {
count += 1
println(count)
} while (count < 10)

$VLWWXUQVRXWWKHUH¦VDPRUHHOHJDQWZD\WRORRSWKURXJKFROOHFWLRQVLQ6FDODDVZH¦OO
VHHLQWKHQH[WVHFWLRQ

Generator Expressions
5HPHPEHUWKHDUURZRSHUDWRU <- IURPWKHGLVFXVVLRQDERXW forORRSV":HFDQSXW
LWWRZRUNKHUHWRR/HW¦VFOHDQXSWKHdo-whileH[DPSOHMXVWVKRZQ
// code-examples/Rounding/generator-script.scala

for (i <- 1 to 10) println(i)

<XS WKDW¦V DOO WKDW¦V QHFHVVDU\ 7KLV FOHDQ RQHOLQHU LV SRVVLEOH EHFDXVH RI 6FDOD¦V
RichIntFODVV$QLPSOLFLWFRQYHUVLRQLVLQYRNHGE\WKHFRPSLOHUWRFRQYHUWWKH 1DQ
Int LQWR D RichInt :H¦OO GLVFXVV WKHVH FRQYHUVLRQV LQ £7KH 6FDOD 7\SH +LHUDU
FK\¤RQSDJHDQGLQ£,PSOLFLW&RQYHUVLRQV¤RQSDJH  RichIntGHILQHVD to
PHWKRGWKDWWDNHVDQRWKHULQWHJHUDQGUHWXUQVDQLQVWDQFHRIRange.Inclusive7KDWLV
Inclusive LV D QHVWHG FODVV LQ WKH Range FRPSDQLRQ REMHFW D FRQFHSW ZH LQWURGXFHG
EULHIO\LQ&KDSWHUVHH&KDSWHUIRUGHWDLOV 7KLVVXEFODVVRIWKHFODVVRangeLQKHULWV
DQXPEHURIPHWKRGVIRUZRUNLQJZLWKVHTXHQFHVDQGLWHUDEOHGDWDVWUXFWXUHVLQFOXGLQJ
WKRVHQHFHVVDU\WRXVHLWLQDforORRS
%\WKHZD\LI\RXZDQWHGWRFRXQWIURPXSWREXWQRWLQFOXGLQJ\RXFRXOGXVH
untilLQVWHDGRIto)RUH[DPSOHfor (i <- 0 until 10)
7KLVVKRXOGSDLQWDFOHDUHUSLFWXUHRIKRZ6FDOD¦VLQWHUQDOOLEUDULHVFRPSRVHWRIRUP
HDV\WRXVHODQJXDJHFRQVWUXFWV

62 | Chapter 3:—Rounding Out the Essentials

Download at WoweBook.Com
:KHQZRUNLQJZLWKORRSVLQPRVWODQJXDJHV\RXFDQ breakRXWRID
ORRSRUcontinueWKHLWHUDWLRQV6FDODGRHVQ¦WKDYHHLWKHURIWKHVHVWDWH
PHQWVEXWZKHQZULWLQJLGLRPDWLF6FDODFRGHWKH\¦UHQRWQHFHVVDU\
8VHFRQGLWLRQDOH[SUHVVLRQVWRWHVWLIDORRSVKRXOGFRQWLQXHRUPDNH
XVHRIUHFXUVLRQ%HWWHU\HWILOWHU\RXUFROOHFWLRQVDKHDGRIWLPHWRHOLP
LQDWHFRPSOH[FRQGLWLRQVZLWKLQ\RXUORRSV+RZHYHUEHFDXVHRIGH
PDQGIRULW6FDODYHUVLRQLQFOXGHVVXSSRUWIRUbreakLPSOHPHQWHG
DVDOLEUDU\PHWKRGUDWKHUWKDQDEXLOWLQbreakNH\ZRUG

Conditional Operators
6FDODERUURZVPRVWRIWKHFRQGLWLRQDORSHUDWRUVIURP-DYDDQGLWVSUHGHFHVVRUV<RX¦OO
ILQGWKHRQHVOLVWHGLQ7DEOHLQ ifVWDWHPHQWV whileORRSVDQGHYHU\ZKHUHHOVH
FRQGLWLRQVDSSO\
7DEOH&RQGLWLRQDORSHUDWRUV
Operator Operation Description
&& and The values on the left and right of the operator are true. The righthand side is only evaluated
if the lefthand side is true.
|| or At least one of the values on the left or right is true. The righthand side is only evaluated if the
lefthand side is false.
> greater than The value on the left is greater than the value on the right.
>= greater than or The value on the left is greater than or equal to the value on the right.
equals
< less than The value on the left is less than the value on the right.
<= less than or The value on the left is less than or equal to the value on the right.
equals
== equals The value on the left is the same as the value on the right.
!= not equal The value on the left is not the same as the value on the right.

1RWHWKDW&&DQG||DUH£VKRUWFLUFXLWLQJ¤RSHUDWRUV7KH\VWRSHYDOXDWLQJH[SUHVVLRQV
DVVRRQDVWKHDQVZHULVNQRZQ
:H¦OOGLVFXVVREMHFWHTXDOLW\LQPRUHGHWDLOLQ£(TXDOLW\RI2EMHFWV¤RQSDJH)RU
H[DPSOHZH¦OOVHHWKDW==KDVDGLIIHUHQWPHDQLQJLQ6FDODYHUVXV-DYD2WKHUZLVHWKHVH
RSHUDWRUVVKRXOGDOOEHIDPLOLDUVROHW¦VPRYHRQWRVRPHWKLQJQHZDQGH[FLWLQJ

Pattern Matching
$QLGHDERUURZHGIURPIXQFWLRQDOODQJXDJHVSDWWHUQPDWFKLQJLVDSRZHUIXO\HWFRQFLVH
ZD\WRPDNHDSURJUDPPDWLFFKRLFHEHWZHHQPXOWLSOHFRQGLWLRQV3DWWHUQPDWFKLQJLV
WKHIDPLOLDUcaseVWDWHPHQWIURP\RXUIDYRULWH&OLNHODQJXDJHEXWRQVWHURLGV,QWKH

Pattern Matching | 63

Download at WoweBook.Com
W\SLFDOcaseVWDWHPHQW\RX¦UHOLPLWHGWRPDWFKLQJDJDLQVWYDOXHVRIRUGLQDOW\SHV\LHOG
LQJWULYLDOH[SUHVVLRQVOLNHWKLV£,QWKHFDVHWKDWiLVSULQWDPHVVDJHLQWKHFDVHWKDW
iLVH[LWWKHSURJUDP¤:LWK6FDOD¦VSDWWHUQPDWFKLQJ\RXUFDVHVFDQLQFOXGHW\SHV
ZLOGFDUGVVHTXHQFHVUHJXODUH[SUHVVLRQVDQGHYHQGHHSLQVSHFWLRQVRIDQREMHFW¦V
YDULDEOHV

A Simple Match
7REHJLQZLWKOHW¦VVLPXODWHIOLSSLQJDFRLQE\PDWFKLQJWKHYDOXHRIDERROHDQ
// code-examples/Rounding/match-boolean-script.scala

val bools = List(true, false)

for (bool <- bools) {


bool match {
case true => println("heads")
case false => println("tails")
case _ => println("something other than heads or tails (yikes!)")
}
}

,WORRNVMXVWOLNHD&VW\OHcaseVWDWHPHQWULJKW"7KHRQO\GLIIHUHQFHLVWKHODVWcaseZLWK
WKHXQGHUVFRUH _ ZLOGFDUG,WPDWFKHVDQ\WKLQJQRWGHILQHGLQWKHFDVHVDERYHLWVR
LWVHUYHVWKHVDPHSXUSRVHDVWKHdefaultNH\ZRUGLQ-DYDDQG&switchVWDWHPHQWV
3DWWHUQPDWFKLQJLVHDJHUWKHILUVWPDWFKZLQV6RLI\RXWU\WRSXWD case _FODXVH
EHIRUHDQ\RWKHUcaseFODXVHVWKHFRPSLOHUZLOOWKURZDQ£XQUHDFKDEOHFRGH¤HUURURQ
WKHQH[WFODXVHEHFDXVHQRWKLQJZLOOJHWSDVWWKHGHIDXOWFODXVH

8VHcase _IRUWKHGHIDXOW£FDWFKDOO¤PDWFK

:KDWLIZHZDQWWRZRUNZLWKPDWFKHVDVYDULDEOHV"

Variables in Matches
,Q WKH IROORZLQJ H[DPSOH ZH DVVLJQ WKH ZLOGFDUG FDVH WR D YDULDEOH FDOOHG other
NumberWKHQSULQWLWLQWKHVXEVHTXHQWH[SUHVVLRQ,IZHJHQHUDWHDZH¦OOH[WROWKDW
QXPEHU¦VYLUWXHV2WKHUZLVHZH¦OOFXUVHIDWHIRUPDNLQJXVVXIIHUDQXQOXFN\QXPEHU
// code-examples/Rounding/match-variable-script.scala

import scala.util.Random

val randomInt = new Random().nextInt(10)

randomInt match {

64 | Chapter 3:—Rounding Out the Essentials

Download at WoweBook.Com
case 7 => println("lucky seven!")
case otherNumber => println("boo, got boring ol' " + otherNumber)
}

Matching on Type
7KHVHVLPSOHH[DPSOHVGRQ¦WHYHQEHJLQWRVFUDWFKWKHVXUIDFHRI6FDOD¦VSDWWHUQPDWFK
LQJIHDWXUHV/HW¦VWU\PDWFKLQJEDVHGRQW\SH
// code-examples/Rounding/match-type-script.scala

val sundries = List(23, "Hello", 8.5, 'q')

for (sundry <- sundries) {


sundry match {
case i: Int => println("got an Integer: " + i)
case s: String => println("got a String: " + s)
case f: Double => println("got a Double: " + f)
case other => println("got something else: " + other)
}
}

+HUHZHSXOOHDFKHOHPHQWRXWRIDListRIAnyW\SHRIHOHPHQWLQWKLVFDVHFRQWDLQLQJ
DStringDDoubleDQIntDQGDChar)RUWKHILUVWWKUHHRIWKRVHW\SHVZHOHWWKHXVHU
NQRZVSHFLILFDOO\ZKLFKW\SHZHJRWDQGZKDWWKHYDOXHZDV:KHQZHJHWVRPHWKLQJ
HOVH WKHChar ZHMXVWOHWWKHXVHUNQRZWKHYDOXH:HFRXOGDGGIXUWKHUHOHPHQWVWR
WKHOLVWRIRWKHUW\SHVDQGWKH\¦GEHFDXJKWE\WKHotherZLOGFDUGFDVH

Matching on Sequences
6LQFHZRUNLQJLQ6FDODRIWHQPHDQVZRUNLQJZLWKVHTXHQFHVZRXOGQ¦WLWEHKDQG\WR
EHDEOHWRPDWFKDJDLQVWWKHOHQJWKDQGFRQWHQWVRIOLVWVDQGDUUD\V"7KHIROORZLQJ
H[DPSOHGRHVMXVWWKDWWHVWLQJWZROLVWVWRVHHLIWKH\FRQWDLQIRXUHOHPHQWVWKHVHFRQG
RIZKLFKLVWKHLQWHJHU3
// code-examples/Rounding/match-seq-script.scala

val willWork = List(1, 3, 23, 90)


val willNotWork = List(4, 18, 52)
val empty = List()

for (l <- List(willWork, willNotWork, empty)) {


l match {
case List(_, 3, _, _) => println("Four elements, with the 2nd being '3'.")
case List(_*) => println("Any other list with 0 or more elements.")
}
}

,QWKHVHFRQG caseZH¦YHXVHGDVSHFLDOZLOGFDUGSDWWHUQWRPDWFKD ListRIDQ\VL]H


HYHQ]HURHOHPHQWVDQGDQ\HOHPHQWYDOXHV<RXFDQXVHWKLVSDWWHUQDWWKHHQGRIDQ\
VHTXHQFHPDWFKWRUHPRYHOHQJWKDVDFRQGLWLRQ

Pattern Matching | 65

Download at WoweBook.Com
5HFDOOWKDWZHPHQWLRQHGWKH£FRQV¤PHWKRGIRU List ::7KHH[SUHVVLRQ a :: list
SUHSHQGVaWRDOLVW<RXFDQDOVRXVHWKLVRSHUDWRUWRH[WUDFWWKHKHDGDQGWDLORIDOLVW
// code-examples/Rounding/match-list-script.scala

val willWork = List(1, 3, 23, 90)


val willNotWork = List(4, 18, 52)
val empty = List()

def processList(l: List[Any]): Unit = l match {


case head :: tail =>
format("%s ", head)
processList(tail)
case Nil => println("")
}

for (l <- List(willWork, willNotWork, empty)) {


print("List: ")
processList(l)
}

7KHprocessListPHWKRGPDWFKHVRQWKHListDUJXPHQWO,WPD\ORRNVWUDQJHWRVWDUW
WKHPHWKRGGHILQLWLRQOLNHWKHIROORZLQJ
def processList(l: List[Any]): Unit = l match {
...
}

+RSHIXOO\KLGLQJWKHGHWDLOVZLWKWKHHOOLSVLVPDNHVWKHPHDQLQJDOLWWOHFOHDUHU7KH
processListPHWKRGLVDFWXDOO\RQHVWDWHPHQWWKDWFURVVHVVHYHUDOOLQHV
,WILUVWPDWFKHVRQ head :: tailZKHUH headZLOOEHDVVLJQHGWKHILUVWHOHPHQWLQWKH
OLVWDQGtailZLOOEHDVVLJQHGWKHUHVWRIWKHOLVW7KDWLVZH¦UHH[WUDFWLQJWKHKHDGDQG
WDLOIURPWKHOLVWXVLQJ:::KHQWKLVFDVHPDWFKHVLWSULQWVWKHheadDQGFDOOVprocess
ListUHFXUVLYHO\WRSURFHVVWKHWDLO
7KHVHFRQGFDVHPDWFKHVWKHHPSW\OLVWNil,WSULQWVDQHQGRIOLQHDQGWHUPLQDWHVWKH
UHFXUVLRQ

Matching on Tuples (and Guards)


$OWHUQDWHO\LIZHMXVWZDQWHGWRWHVWWKDWZHKDYHDWXSOHRIWZRLWHPVZHFRXOGGRD
WXSOHPDWFK
// code-examples/Rounding/match-tuple-script.scala

val tupA = ("Good", "Morning!")


val tupB = ("Guten", "Tag!")

for (tup <- List(tupA, tupB)) {


tup match {
case (thingOne, thingTwo) if thingOne == "Good" =>
println("A two-tuple starting with 'Good'.")
case (thingOne, thingTwo) =>

66 | Chapter 3:—Rounding Out the Essentials

Download at WoweBook.Com
println("This has two things: " + thingOne + " and " + thingTwo)
}
}

,QWKHVHFRQGcaseLQWKLVH[DPSOHZH¦YHH[WUDFWHGWKHYDOXHVLQVLGHWKHWXSOHWRVFRSHG
YDULDEOHVWKHQUHXVHGWKHVHYDULDEOHVLQWKHUHVXOWLQJH[SUHVVLRQ
,QWKHILUVWFDVHZH¦YHDGGHGDQHZFRQFHSWJXDUGV7KHifFRQGLWLRQDIWHUWKHWXSOHLV
DJXDUG7KHJXDUGLVHYDOXDWHGZKHQPDWFKLQJEXWRQO\H[WUDFWLQJDQ\YDULDEOHVLQ
WKHSUHFHGLQJSDUWRIWKHFDVH*XDUGVSURYLGHDGGLWLRQDOJUDQXODULW\ZKHQFRQVWUXFWLQJ
FDVHV,QWKLVH[DPSOHWKHRQO\GLIIHUHQFHEHWZHHQWKHWZRSDWWHUQVLVWKHJXDUGH[
SUHVVLRQEXWWKDW¦VHQRXJKIRUWKHFRPSLOHUWRGLIIHUHQWLDWHWKHP

5HFDOOWKDWWKHFDVHVLQDSDWWHUQPDWFKDUHHYDOXDWHGLQRUGHU)RUH[
DPSOHLI\RXUILUVWFDVHLVEURDGHUWKDQ\RXUVHFRQGFDVHWKHVHFRQG
FDVH ZLOO QHYHU EH UHDFKHG 8QUHDFKDEOH FDVHV ZLOO FDXVH D FRPSLOHU
HUURU <RXPD\LQFOXGHD£GHIDXOW¤FDVHDWWKHHQGRIDSDWWHUQPDWFK
HLWKHUXVLQJWKHXQGHUVFRUHZLOGFDUGFKDUDFWHURUDPHDQLQJIXOO\QDPHG
YDULDEOH:KHQXVLQJDYDULDEOHLWVKRXOGKDYHQRH[SOLFLWW\SHRULW
VKRXOGEHGHFODUHGDVAnyVRLWFDQPDWFKDQ\WKLQJ2QWKHRWKHUKDQG
WU\WRGHVLJQ\RXUFRGHWRDYRLGDFDWFKDOOFODXVHE\HQVXULQJLWRQO\
UHFHLYHVVSHFLILFLWHPVWKDWDUHH[SHFWHG

Matching on Case Classes


/HW¦VWU\DGHHSPDWFKH[DPLQLQJWKHFRQWHQWVRIREMHFWVLQRXUSDWWHUQPDWFK
// code-examples/Rounding/match-deep-script.scala

case class Person(name: String, age: Int)

val alice = new Person("Alice", 25)


val bob = new Person("Bob", 32)
val charlie = new Person("Charlie", 32)

for (person <- List(alice, bob, charlie)) {


person match {
case Person("Alice", 25) => println("Hi Alice!")
case Person("Bob", 32) => println("Hi Bob!")
case Person(name, age) =>
println("Who are you, " + age + " year-old person named " + name + "?")
}
}

3RRU&KDUOLHJHWVWKHFROGVKRXOGHUDVZHFDQVHHLQWKHRXWSXW
Hi Alice!
Hi Bob!
Who are you, 32 year-old person named Charlie?

Pattern Matching | 67

Download at WoweBook.Com
:HILUVWGHILQHDFDVHFODVVDVSHFLDOW\SHRIFODVVWKDWZH¦OOOHDUQPRUHDERXWLQ£&DVH
&ODVVHV¤RQSDJH)RUQRZLWZLOOVXIILFHWRVD\WKDWDFDVHFODVVDOORZVIRUYHU\
WHUVHFRQVWUXFWLRQRIVLPSOHREMHFWVZLWKVRPHSUHGHILQHGPHWKRGV2XUSDWWHUQPDWFK
WKHQORRNVIRU$OLFHDQG%REE\LQVSHFWLQJWKHYDOXHVSDVVHGWRWKHFRQVWUXFWRURIWKH
PersonFDVHFODVV&KDUOLHIDOOVWKURXJKWRWKHFDWFKDOOFDVHHYHQWKRXJKKHKDVWKH
VDPHageYDOXHDV%REZH¦UHPDWFKLQJRQWKHnameSURSHUW\DVZHOO
7KLVW\SHRISDWWHUQPDWFKEHFRPHVH[WUHPHO\XVHIXOZKHQZRUNLQJZLWK$FWRUVDV
ZH¦OO VHH ODWHU RQ &DVH FODVVHV DUH IUHTXHQWO\ VHQW WR $FWRUV DV PHVVDJHV DQG GHHS
SDWWHUQPDWFKLQJRQDQREMHFW¦VFRQWHQWVLVDFRQYHQLHQWZD\WR£SDUVH¤WKRVHPHVVDJHV

Matching on Regular Expressions


5HJXODUH[SUHVVLRQVDUHFRQYHQLHQWIRUH[WUDFWLQJGDWDIURPVWULQJVWKDWKDYHDQLQIRU
PDOVWUXFWXUHEXWDUHQRW£VWUXFWXUHGGDWD¤ WKDWLVLQDIRUPDWOLNH;0/RU-621IRU
H[DPSOH &RPPRQO\UHIHUUHGWRDVUHJH[HVUHJXODUH[SUHVVLRQVDUHDIHDWXUHRIQHDUO\
DOOPRGHUQSURJUDPPLQJODQJXDJHV7KH\SURYLGHDWHUVHV\QWD[IRUVSHFLI\LQJFRPSOH[
PDWFKHV RQH WKDW LV W\SLFDOO\ WUDQVODWHG LQWR D VWDWH PDFKLQH EHKLQG WKH VFHQHV IRU
RSWLPXPSHUIRUPDQFH
5HJH[HVLQ6FDODVKRXOGFRQWDLQQRVXUSULVHVLI\RX¦YHXVHGWKHPLQRWKHUSURJUDPPLQJ
ODQJXDJHV/HW¦VVHHDQH[DPSOH
// code-examples/Rounding/match-regex-script.scala

val BookExtractorRE = """Book: title=([^,]+),\s+authors=(.+)""".r


val MagazineExtractorRE = """Magazine: title=([^,]+),\s+issue=(.+)""".r

val catalog = List(


"Book: title=Programming Scala, authors=Dean Wampler, Alex Payne",
"Magazine: title=The New Yorker, issue=January 2009",
"Book: title=War and Peace, authors=Leo Tolstoy",
"Magazine: title=The Atlantic, issue=February 2009",
"BadData: text=Who put this here??"
)

for (item <- catalog) {


item match {
case BookExtractorRE(title, authors) =>
println("Book \"" + title + "\", written by " + authors)
case MagazineExtractorRE(title, issue) =>
println("Magazine \"" + title + "\", issue " + issue)
case entry => println("Unrecognized entry: " + entry)
}
}

:HVWDUWZLWKWZRUHJXODUH[SUHVVLRQVRQHIRUUHFRUGVRIERRNVDQGDQRWKHUIRUUHFRUGV
RIPDJD]LQHV&DOOLQJ.rRQDVWULQJWXUQVLWLQWRDUHJXODUH[SUHVVLRQZHXVHUDZ WULSOH
TXRWHG VWULQJVKHUHWRDYRLGKDYLQJWRGRXEOHHVFDSHEDFNVODVKHV6KRXOG\RXILQG

68 | Chapter 3:—Rounding Out the Essentials

Download at WoweBook.Com
WKH.rWUDQVIRUPDWLRQPHWKRGRQVWULQJVXQFOHDU\RXFDQDOVRGHILQHUHJH[HVE\FUHDWLQJ
QHZLQVWDQFHVRIWKHRegexFODVVDVLQnew Regex("""\W""")
1RWLFHWKDWHDFKRIRXUUHJH[HVGHILQHVWZRFDSWXUHJURXSVFRQQRWHGE\SDUHQWKHVHV
(DFKJURXSFDSWXUHVWKHYDOXHRIDVLQJOHILHOGLQWKHUHFRUGVXFKDVDERRN¦VWLWOHRU
DXWKRU5HJH[HVLQ6FDODWUDQVODWHWKRVHFDSWXUHJURXSVWRH[WUDFWRUV(YHU\PDWFKVHWV
DILHOGWRWKHFDSWXUHGUHVXOWHYHU\PLVVLVVHWWRnull
:KDWGRHVWKLVPHDQLQSUDFWLFH",IWKHWH[WIHGWRWKHUHJXODUH[SUHVVLRQPDWFKHV
case BookExtractorRE(title, authors)ZLOODVVLJQWKHILUVWFDSWXUHJURXSWRtitleDQG
WKH VHFRQG WR authors :H FDQ WKHQ XVH WKRVH YDOXHV RQ WKH ULJKWKDQG VLGH RI WKH
case FODXVH DV ZH KDYH LQ WKH SUHYLRXV H[DPSOH 7KH YDULDEOH QDPHV title DQG
author ZLWKLQ WKH H[WUDFWRU DUH DUELWUDU\ PDWFKHV IURP FDSWXUH JURXSV DUH VLPSO\
DVVLJQHGIURPOHIWWRULJKWDQG\RXFDQFDOOWKHPZKDWHYHU\RX¦GOLNH
7KDW¦VUHJH[HVLQ6FDODLQQXWVKHOO7KHscala.util.matching.RegexFODVVVXSSOLHVVHY
HUDOKDQG\PHWKRGVIRUILQGLQJDQGUHSODFLQJPDWFKHVLQVWULQJVERWKDOORFFXUUHQFHV
RIDPDWFKDQGMXVWWKHILUVWRFFXUUHQFHVREHVXUHWRPDNHXVHRIWKHP
:KDWZHZRQ¦WFRYHULQWKLVVHFWLRQLVWKHGHWDLOVRIZULWLQJUHJXODUH[SUHVVLRQV6FDOD¦V
Regex FODVV XVHV WKH XQGHUO\LQJ SODWIRUP¦V UHJXODU H[SUHVVLRQ $3,V WKDW LV -DYD¦V
RU1(7¦V &RQVXOWUHIHUHQFHVRQWKRVH$3,VIRUWKHKDLU\GHWDLOVDVWKH\PD\EHVXEWO\
GLIIHUHQWIURPWKHUHJH[VXSSRUWLQ\RXUODQJXDJHRIFKRLFH

Binding Nested Variables in Case Clauses


6RPHWLPHV\RXZDQWWRELQGDYDULDEOHWRDQREMHFWHQFORVHGLQDPDWFKZKHUH\RXDUH
DOVRVSHFLI\LQJPDWFKFULWHULDRQWKHQHVWHGREMHFW6XSSRVHZHPRGLI\DSUHYLRXVH[
DPSOH VR ZH¦UH PDWFKLQJ RQ WKH NH\YDOXH SDLUV IURP D PDS :H¦OO VWRUH RXU VDPH
PersonREMHFWVDVWKHYDOXHVDQGXVHDQHPSOR\HH,'DVWKHNH\:H¦OODOVRDGGDQRWKHU
DWWULEXWHWRPersonDroleILHOGWKDWSRLQWVWRDQLQVWDQFHIURPDW\SHKLHUDUFK\
// code-examples/Rounding/match-deep-pair-script.scala

class Role
case object Manager extends Role
case object Developer extends Role

case class Person(name: String, age: Int, role: Role)

val alice = new Person("Alice", 25, Developer)


val bob = new Person("Bob", 32, Manager)
val charlie = new Person("Charlie", 32, Developer)

for (item <- Map(1 -> alice, 2 -> bob, 3 -> charlie)) {
item match {
case (id, p @ Person(_, _, Manager)) => format("%s is overpaid.\n", p)
case (id, p @ Person(_, _, _)) => format("%s is underpaid.\n", p)
}
}

Pattern Matching | 69

Download at WoweBook.Com
7KHcase objectsDUHMXVWVLQJOHWRQREMHFWVOLNHZH¦YHVHHQEHIRUHEXWZLWKWKHVSHFLDO
caseEHKDYLRU:H¦UHPRVWLQWHUHVWHGLQWKHHPEHGGHGp @ Person(...)LQVLGHWKHFDVH
FODXVH:H¦UHPDWFKLQJRQSDUWLFXODUNLQGVRIPersonREMHFWVLQVLGHWKHHQFORVLQJWXSOH
:HDOVRZDQWWRDVVLJQWKHPersonWRDYDULDEOHpVRZHFDQXVHLWIRUSULQWLQJ
Person(Alice,25,Developer) is underpaid.
Person(Bob,32,Manager) is overpaid.
Person(Charlie,32,Developer) is underpaid.

,IZHZHUHQ¦WXVLQJPDWFKLQJFULWHULDLQPersonLWVHOIZHFRXOGMXVWZULWHp: Person)RU
H[DPSOHWKHSUHYLRXVmatchFODXVHFRXOGEHZULWWHQWKLVZD\
item match {
case (id, p: Person) => p.role match {
case Manager => format("%s is overpaid.\n", p)
case _ => format("%s is underpaid.\n", p)
}
}

1RWHWKDWWKH p @ Person(...)V\QWD[JLYHVXVDZD\WRIODWWHQWKLVQHVWLQJRIPDWFK
VWDWHPHQWVLQWRRQHVWDWHPHQW,WLVDQDORJRXVWRXVLQJ£FDSWXUHJURXSV¤LQDUHJXODU
H[SUHVVLRQ WR SXOO RXW VXEVWULQJV ZH ZDQW LQVWHDG RI VSOLWWLQJ WKH VWULQJ LQ VHYHUDO
VXFFHVVLYHVWHSVWRH[WUDFWWKHVXEVWULQJVZHZDQW8VHZKLFKHYHUWHFKQLTXH\RXSUHIHU

Using try, catch, and finally Clauses


7KURXJKLWVXVHRIIXQFWLRQDOFRQVWUXFWVDQGVWURQJW\SLQJ6FDODHQFRXUDJHVDFRGLQJ
VW\OH WKDW OHVVHQV WKH QHHG IRU H[FHSWLRQV DQG H[FHSWLRQ KDQGOLQJ %XW ZKHUH 6FDOD
LQWHUDFWVZLWK-DYDH[FHSWLRQVDUHVWLOOSUHYDOHQW

6FDODGRHVQRWKDYHFKHFNHGH[FHSWLRQVOLNH-DYD(YHQ-DYD¦VFKHFNHG
H[FHSWLRQVDUHWUHDWHGDVXQFKHFNHGE\6FDOD7KHUHLVDOVRQR throws
FODXVHRQPHWKRGGHFODUDWLRQV+RZHYHUWKHUHLVD@throwsDQQRWDWLRQ
WKDW LV XVHIXO IRU -DYD LQWHURSHUDELOLW\ 6HH WKH VHFWLRQ £$QQRWD
WLRQV¤RQSDJH

7KDQNIXOO\6FDODWUHDWVH[FHSWLRQKDQGOLQJDVMXVWDQRWKHUSDWWHUQPDWFKDOORZLQJXV
WRPDNHVPDUWFKRLFHVZKHQSUHVHQWHGZLWKDPXOWLSOLFLW\RISRWHQWLDOH[FHSWLRQV/HW¦V
VHHWKLVLQDFWLRQ
// code-examples/Rounding/try-catch-script.scala

import java.util.Calendar

val then = null


val now = Calendar.getInstance()

try {
now.compareTo(then)
} catch {

70 | Chapter 3:—Rounding Out the Essentials

Download at WoweBook.Com
case e: NullPointerException => println("One was null!"); System.exit(-1)
case unknown => println("Unknown exception " + unknown); System.exit(-1)
} finally {
println("It all worked out.")
System.exit(0)
}

,QWKLVH[DPSOHZHH[SOLFLWO\FDWFKWKH NullPointerExceptionWKURZQZKHQWU\LQJWR
FRPSDUHDCalendarLQVWDQFHZLWKnull:HDOVRGHILQHunknownDVDFDWFKDOOFDVHMXVW
WREHVDIH,IZHZHUHQ¦WKDUGFRGLQJWKLVSURJUDPWRIDLOWKH finallyEORFNZRXOGEH
UHDFKHGDQGWKHXVHUZRXOGEHLQIRUPHGWKDWHYHU\WKLQJZRUNHGRXWMXVWILQH

<RXFDQXVHDQXQGHUVFRUH 6FDOD¦VVWDQGDUGZLOGFDUGFKDUDFWHU DVD


SODFHKROGHUWRFDWFKDQ\W\SHRIH[FHSWLRQ UHDOO\WRPDWFKDQ\FDVHLQ
DSDWWHUQPDWFKLQJH[SUHVVLRQ +RZHYHU\RXZRQ¦WEHDEOHWRUHIHUWR
WKHH[FHSWLRQLQWKHVXEVHTXHQWH[SUHVVLRQ1DPHWKHH[FHSWLRQYDUL
DEOHLI\RXQHHGLWIRUH[DPSOHLI\RXQHHGWRSULQWWKHH[FHSWLRQDVZH
GRLQWKHFDWFKDOOFDVHRIWKHSUHYLRXVH[DPSOH

3DWWHUQPDWFKLQJDVLGH6FDOD¦VWUHDWPHQWRIH[FHSWLRQKDQGOLQJVKRXOGEHIDPLOLDUWR
WKRVHIOXHQWLQ-DYD5XE\3\WKRQDQGPRVWRWKHUPDLQVWUHDPODQJXDJHV$QG\HV
\RXWKURZDQH[FHSWLRQE\ZULWLQJthrow new MyBadException(...)7KDW¦VDOOWKHUHLV
WRLW

Concluding Remarks on Pattern Matching


3DWWHUQPDWFKLQJLVDSRZHUIXODQGHOHJDQWZD\RIH[WUDFWLQJLQIRUPDWLRQIURPREMHFWV
ZKHQXVHGDSSURSULDWHO\5HFDOOIURP&KDSWHUWKDWZHKLJKOLJKWHGWKHV\QHUJ\EH
WZHHQSDWWHUQPDWFKLQJDQGSRO\PRUSKLVP0RVWRIWKHWLPH\RXZDQWWRDYRLGWKH
SUREOHPVRI£VZLWFK¤VWDWHPHQWVWKDWNQRZDFODVVKLHUDUFK\EHFDXVHWKH\KDYHWREH
PRGLILHGHYHU\WLPHWKHKLHUDUFK\LVFKDQJHG
,QRXUGUDZLQJ$FWRUH[DPSOHZHXVHGSDWWHUQPDWFKLQJWRVHSDUDWHGLIIHUHQW£FDWH
JRULHV¤RIPHVVDJHVEXWZHXVHGSRO\PRUSKLVPWRGUDZWKHVKDSHVVHQWWRLW:HFRXOG
FKDQJHWKHShapeKLHUDUFK\DQGWKH$FWRUFRGHZRXOGQRWUHTXLUHFKDQJHV
3DWWHUQPDWFKLQJLVDOVRXVHIXOIRUWKHGHVLJQSUREOHPZKHUH\RXQHHGWRJHWDWGDWD
LQVLGHDQREMHFWEXWRQO\LQVSHFLDOFLUFXPVWDQFHV2QHRIWKHXQLQWHQGHGFRQVHTXHQ
FHVRIWKH-DYD%HDQV VHH>-DYD%HDQV6SHF@ VSHFLILFDWLRQZDVWKDWLWHQFRXUDJHGSHRSOH
WR H[SRVH ILHOGV LQ WKHLU REMHFWV WKURXJKJHWWHUV DQG VHWWHUV7KLV VKRXOG QHYHU EH D
GHIDXOWGHFLVLRQ$FFHVVWR£VWDWHLQIRUPDWLRQ¤VKRXOGEHHQFDSVXODWHGDQGH[SRVHG
RQO\LQZD\VWKDWPDNHORJLFDOVHQVHIRUWKHW\SHDVYLHZHGIURPWKHDEVWUDFWLRQLW
H[SRVHV
,QVWHDGFRQVLGHUXVLQJSDWWHUQPDWFKLQJIRUWKRVH£UDUH¤WLPHVZKHQ\RXQHHGWRH[
WUDFWLQIRUPDWLRQLQDFRQWUROOHGZD\$VZHZLOOVHHLQ£8QDSSO\¤RQSDJHWKH
SDWWHUQPDWFKLQJH[DPSOHVZHKDYHVKRZQXVH unapplyPHWKRGVGHILQHGWRH[WUDFW

Pattern Matching | 71

Download at WoweBook.Com
LQIRUPDWLRQIURPLQVWDQFHV7KHVHPHWKRGVOHW\RXH[WUDFWWKDWLQIRUPDWLRQZKLOHKLG
LQJWKHLPSOHPHQWDWLRQGHWDLOV,QIDFWWKHLQIRUPDWLRQUHWXUQHGE\unapplyPLJKWEH
DWUDQVIRUPDWLRQRIWKHDFWXDOLQIRUPDWLRQLQWKHW\SH
)LQDOO\ZKHQGHVLJQLQJSDWWHUQPDWFKLQJVWDWHPHQWVEHZDU\RIUHO\LQJRQDGHIDXOW
FDVHFODXVH8QGHUZKDWFLUFXPVWDQFHVZRXOG£QRQHRIWKHDERYH¤EHWKHFRUUHFWDQ
VZHU",WPD\LQGLFDWHWKDWWKHGHVLJQVKRXOGEHUHILQHGVR\RXNQRZPRUHSUHFLVHO\DOO
WKHSRVVLEOHPDWFKHVWKDWPLJKWRFFXU:H¦OOOHDUQRQHWHFKQLTXHWKDWKHOSVZKHQZH
GLVFXVVVHDOHGFODVVKLHUDUFKLHVLQ£6HDOHG&ODVV+LHUDUFKLHV¤RQSDJH

Enumerations
5HPHPEHURXUH[DPSOHVLQYROYLQJYDULRXVEUHHGVRIGRJ",QWKLQNLQJDERXWWKHW\SHV
LQWKHVHSURJUDPVZHPLJKWZDQWDWRSOHYHOBreedW\SHWKDWNHHSVWUDFNRIDQXPEHU
RIEUHHGV6XFKDW\SHLVFDOOHGDQHQXPHUDWHGW\SHDQGWKHYDOXHVLWFRQWDLQVDUHFDOOHG
HQXPHUDWLRQV
:KLOHHQXPHUDWLRQVDUHDEXLOWLQSDUWRIPDQ\SURJUDPPLQJODQJXDJHV6FDODWDNHVD
GLIIHUHQWURXWHDQGLPSOHPHQWVWKHPDVDFODVVLQLWVVWDQGDUGOLEUDU\7KLVPHDQVWKHUH
LVQRVSHFLDOV\QWD[IRUHQXPHUDWLRQVLQ6FDODDVLQ-DYDDQG&,QVWHDG\RXMXVW
GHILQHDQREMHFWWKDWH[WHQGVWKHEnumerationFODVV+HQFHDWWKHE\WHFRGHOHYHOWKHUH
LVQRFRQQHFWLRQEHWZHHQ6FDODHQXPHUDWLRQVDQGWKHenumFRQVWUXFWVLQ-DYDDQG&
+HUHLVDQH[DPSOH
// code-examples/Rounding/enumeration-script.scala

object Breed extends Enumeration {


val doberman = Value("Doberman Pinscher")
val yorkie = Value("Yorkshire Terrier")
val scottie = Value("Scottish Terrier")
val dane = Value("Great Dane")
val portie = Value("Portuguese Water Dog")
}

// print a list of breeds and their IDs


println("ID\tBreed")
for (breed <- Breed) println(breed.id + "\t" + breed)

// print a list of Terrier breeds


println("\nJust Terriers:")
Breed.filter(_.toString.endsWith("Terrier")).foreach(println)

:KHQUXQ\RX¦OOJHWWKHIROORZLQJRXWSXW
ID Breed
0 Doberman Pinscher
1 Yorkshire Terrier
2 Scottish Terrier
3 Great Dane
4 Portuguese Water Dog

72 | Chapter 3:—Rounding Out the Essentials

Download at WoweBook.Com
Just Terriers:
Yorkshire Terrier
Scottish Terrier

:HFDQVHHWKDWRXUBreedHQXPHUDWHGW\SHFRQWDLQVVHYHUDOYDULDEOHVRIW\SHValueDV
LQWKHIROORZLQJH[DPSOH
val doberman = Value("Doberman Pinscher")

(DFKGHFODUDWLRQLVDFWXDOO\FDOOLQJDPHWKRGQDPHGValueWKDWWDNHVDVWULQJDUJXPHQW
:HXVHWKLVPHWKRGWRDVVLJQDORQJIRUPEUHHGQDPHWRHDFKHQXPHUDWLRQYDOXHZKLFK
LVZKDWWKHValue.toStringPHWKRGUHWXUQHGLQWKHRXWSXW
1RWHWKDWWKHUHLVQRQDPHVSDFHFROOLVLRQEHWZHHQWKHW\SHDQGPHWKRGWKDWERWKKDYH
WKHQDPHValue7KHUHDUHRWKHURYHUORDGHGYHUVLRQVRIWKHValuePHWKRG2QHRIWKHP
WDNHVQRDUJXPHQWVDQRWKHUWDNHVDQInt,'YDOXHDQGDQRWKHUWDNHVERWKDQIntDQG
String7KHVHValuePHWKRGVUHWXUQDValueREMHFWDQGWKH\DGGWKHYDOXHWRWKHHQX
PHUDWLRQ¦VFROOHFWLRQRIYDOXHV
,QIDFW6FDOD¦VEnumerationFODVVVXSSRUWVWKHXVXDOPHWKRGVIRUZRUNLQJZLWKFROOHF
WLRQVVRZHFDQHDVLO\LWHUDWHWKURXJKWKHEUHHGVZLWKDforORRSDQGfilterWKHPE\
QDPH7KHRXWSXWDERYHDOVRGHPRQVWUDWHGWKDWHYHU\ValueLQDQHQXPHUDWLRQLVDX
WRPDWLFDOO\ DVVLJQHG D QXPHULF LGHQWLILHU XQOHVV \RX FDOO RQH RI WKH Value PHWKRGV
ZKHUH\RXVSHFLI\\RXURZQ,'YDOXHH[SOLFLWO\
<RX¦OORIWHQZDQWWRJLYH\RXUHQXPHUDWLRQYDOXHVKXPDQUHDGDEOHQDPHVDVZHGLG
KHUH+RZHYHUVRPHWLPHV\RXPD\QRWQHHGWKHP+HUH¦VDQRWKHUHQXPHUDWLRQH[
DPSOHDGDSWHGIURPWKH6FDODGRFHQWU\IRUEnumeration
// code-examples/Rounding/days-enumeration-script.scala

object WeekDay extends Enumeration {


type WeekDay = Value
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}
import WeekDay._

def isWorkingDay(d: WeekDay) = ! (d == Sat || d == Sun)

WeekDay filter isWorkingDay foreach println

5XQQLQJWKLVVFULSWZLWKscala\LHOGVWKHIROORZLQJRXWSXW
Main$$anon$1$WeekDay(0)
Main$$anon$1$WeekDay(1)
Main$$anon$1$WeekDay(2)
Main$$anon$1$WeekDay(3)
Main$$anon$1$WeekDay(4)

:KHQDQDPHLVQ¦WDVVLJQHGXVLQJRQHRIWKHValuePHWKRGVWKDWWDNHVDStringDUJX
PHQWValue.toStringSULQWVWKHQDPHRIWKHW\SHWKDWLVV\QWKHVL]HGE\WKHFRPSLOHU
DORQJZLWKWKH,'YDOXHWKDWZDVJHQHUDWHGDXWRPDWLFDOO\

Enumerations | 73

Download at WoweBook.Com
1RWHWKDWZHLPSRUWHGWeekDay._7KLVPDGHHDFKHQXPHUDWLRQYDOXH MonTuesHWF
LQVFRSH2WKHUZLVH\RXZRXOGKDYHWRZULWHWeekDay.MonWeekDay.TuesHWF
$OVRWKHLPSRUWPDGHWKHW\SHDOLDVtype Weekday = ValueLQVFRSHZKLFKZHXVHG
DVWKHW\SHIRUWKHDUJXPHQWIRUWKH isWorkingDayPHWKRG,I\RXGRQ¦WGHILQHDW\SH
DOLDV OLNH WKLV WKHQ \RX ZRXOG GHFODUH WKH PHWKRG DV def isWorkingDay(d: Week
Day.Value)
6LQFH6FDODHQXPHUDWLRQVDUHMXVWUHJXODUREMHFWV\RXFRXOGXVHDQ\REMHFWZLWK vals
WRLQGLFDWHGLIIHUHQW£HQXPHUDWLRQYDOXHV¤+RZHYHUH[WHQGLQJ EnumerationKDVVHY
HUDODGYDQWDJHV,WDXWRPDWLFDOO\PDQDJHVWKHYDOXHVDVDFROOHFWLRQWKDW\RXFDQLWHUDWH
RYHUHWFDVLQRXUH[DPSOHV,WDOVRDXWRPDWLFDOO\DVVLJQVXQLTXHLQWHJHU,'VWRHDFK
YDOXH
&DVHFODVVHV VHH£&DVH&ODVVHV¤RQSDJH DUHRIWHQXVHGLQVWHDGRIHQXPHUDWLRQV
LQ6FDODEHFDXVHWKH£XVHFDVH¤IRUWKHPRIWHQLQYROYHVSDWWHUQPDWFKLQJ:H¦OOUHYLVLW
WKLVWRSLFLQ£(QXPHUDWLRQV9HUVXV3DWWHUQ0DWFKLQJ¤RQSDJH

Recap and What’s Next


:H¦YHFRYHUHGDORWRIJURXQGLQWKLVFKDSWHU:HOHDUQHGKRZIOH[LEOH6FDOD¦VV\QWD[
FDQ EH DQG KRZ LW IDFLOLWDWHV WKH FUHDWLRQ RI 'RPDLQ6SHFLILF /DQJXDJHV 7KHQ ZH
H[SORUHG6FDOD¦VHQKDQFHPHQWVWRORRSLQJFRQVWUXFWVDQGFRQGLWLRQDOH[SUHVVLRQV:H
H[SHULPHQWHGZLWKGLIIHUHQWXVHVIRUSDWWHUQPDWFKLQJDSRZHUIXOLPSURYHPHQWRQWKH
IDPLOLDU case-switch VWDWHPHQW )LQDOO\ ZH OHDUQHG KRZ WR HQFDSVXODWH YDOXHV LQ
HQXPHUDWLRQV
<RXVKRXOGQRZEHSUHSDUHGWRUHDGDIDLUELWRI6FDODFRGHEXWWKHUH¦VSOHQW\PRUH
DERXWWKHODQJXDJHWRSXWLQ\RXUWRROEHOW,QWKHQH[WIRXUFKDSWHUVZH¦OOH[SORUH
6FDOD¦VDSSURDFKWRREMHFWRULHQWHGSURJUDPPLQJVWDUWLQJZLWKWUDLWV

74 | Chapter 3:—Rounding Out the Essentials

Download at WoweBook.Com
CHAPTER 4
Traits

Introducing Traits
%HIRUHZHGLYHLQWRREMHFWRULHQWHGSURJUDPPLQJWKHUH¦VRQHPRUHHVVHQWLDOIHDWXUHRI
6FDODWKDW\RXVKRXOGJHWDFTXDLQWHGZLWKWUDLWV8QGHUVWDQGLQJWKHYDOXHRIWKLVIHDWXUH
UHTXLUHVDOLWWOHEDFNVWRU\
,Q-DYDDFODVVFDQLPSOHPHQWDQDUELWUDU\QXPEHURILQWHUIDFHV7KLVPRGHOLVYHU\
XVHIXOIRUGHFODULQJWKDWDFODVVH[SRVHVPXOWLSOHDEVWUDFWLRQV8QIRUWXQDWHO\LWKDVRQH
PDMRUGUDZEDFN
)RUPDQ\LQWHUIDFHVPXFKRIWKHIXQFWLRQDOLW\FDQEHLPSOHPHQWHGZLWKERLOHUSODWH
FRGHWKDWZLOOEHYDOLGIRUDOOFODVVHVWKDWXVHWKHLQWHUIDFH-DYDSURYLGHVQREXLOWLQ
PHFKDQLVPIRUGHILQLQJDQGXVLQJVXFKUHXVDEOHFRGH,QVWHDG-DYDSURJUDPPHUVPXVW
XVHDGKRFFRQYHQWLRQVWRUHXVHLPSOHPHQWDWLRQFRGHIRUDJLYHQLQWHUIDFH,QWKHZRUVW
FDVHWKHGHYHORSHUMXVWFRSLHVDQGSDVWHVWKHVDPHFRGHLQWRHYHU\FODVVWKDWQHHGVLW
2IWHQWKHLPSOHPHQWDWLRQRIDQLQWHUIDFHKDVPHPEHUVWKDWDUHXQUHODWHG £RUWKRJR
QDO¤ WRWKHUHVWRIWKHLQVWDQFH¦VPHPEHUV7KHWHUPPL[LQLVRIWHQXVHGIRUVXFKIRFXVHG
DQGSRWHQWLDOO\UHXVDEOHSDUWVRIDQLQVWDQFHWKDWFRXOGEHLQGHSHQGHQWO\PDLQWDLQHG
+DYHDORRNDWWKHIROORZLQJFRGHIRUDEXWWRQLQDJUDSKLFDOXVHULQWHUIDFHZKLFKXVHV
FDOOEDFNVIRU£FOLFNV¤
// code-examples/Traits/ui/button-callbacks.scala

package ui

class ButtonWithCallbacks(val label: String,


val clickedCallbacks: List[() => Unit]) extends Widget {

require(clickedCallbacks != null, "Callback list can't be null!")

def this(label: String, clickedCallback: () => Unit) =


this(label, List(clickedCallback))

def this(label: String) = {

75

Download at WoweBook.Com
this(label, Nil)
println("Warning: button has no click callbacks!")
}

def click() = {
// ... logic to give the appearance of clicking a physical button ...
clickedCallbacks.foreach(f => f())
}
}

7KHUH¦VDORWJRLQJRQKHUH7KHSULPDU\FRQVWUXFWRUWDNHVDlabelDUJXPHQWDQGDOLVW
RIcallbacksWKDWDUHLQYRNHGZKHQWKHEXWWRQ¦VclickPHWKRGLVLQYRNHG:H¦OOH[SORUH
WKLVFODVVLQJUHDWHUGHWDLOLQ&KDSWHU)RUQRZZHZDQWWRIRFXVRQRQHSDUWLFXODU
SUREOHP 1RW RQO\ GRHV ButtonWithCallbacks KDQGOH EHKDYLRUV HVVHQWLDO WR EXWWRQV
OLNHFOLFNLQJ LWDOVRKDQGOHVQRWLILFDWLRQRIFOLFNHYHQWVE\LQYRNLQJWKHFDOOEDFNIXQF
WLRQV7KLVJRHVDJDLQVWWKH6LQJOH5HVSRQVLELOLW\3ULQFLSOH VHH>0DUWLQ@ DPHDQV
WRWKHGHVLJQJRDORI VHSDUDWLRQRIFRQFHUQV:HZRXOGOLNHWRVHSDUDWHWKHEXWWRQ
VSHFLILFORJLFIURPWKHFDOOEDFNORJLFVXFKWKDWHDFKORJLFDOFRPSRQHQWEHFRPHVVLP
SOHUPRUHPRGXODUDQGPRUHUHXVDEOH7KHFDOOEDFNORJLFLVDJRRGH[DPSOHRIDPL[LQ
7KLVVHSDUDWLRQLVGLIILFXOWWRGRLQ-DYDHYHQLIZHGHILQHDQLQWHUIDFHIRUWKHFDOOEDFN
EHKDYLRU :H VWLOO KDYH WR HPEHG WKH LPSOHPHQWDWLRQ FRGH LQ WKH FODVV VRPHKRZ
FRPSURPLVLQJPRGXODULW\7KHRQO\RWKHUDOWHUQDWLYHLVWRXVHDVSHFLDOL]HGWRROOLNH
DVSHFWRULHQWHG SURJUDPPLQJ $23 VHH >$26'@  DV LPSOHPHQWHG E\ $VSHFW- VHH
>$VSHFW-@ DQH[WHQVLRQRI-DYD$23LVSULPDULO\GHVLJQHGWRVHSDUDWHWKHLPSOHPHQ
WDWLRQVRI£SHUYDVLYH¤FRQFHUQVWKDWDUHUHSHDWHGWKURXJKRXWDQDSSOLFDWLRQ,WVHHNV
WRPRGXODUL]HWKHVHFRQFHUQV\HWHQDEOHWKHILQHJUDLQHG£PL[LQJ¤RIWKHLUEHKDYLRUV
ZLWKRWKHUFRQFHUQVLQFOXGLQJWKHFRUHGRPDLQORJLFRIWKHDSSOLFDWLRQHLWKHUDWEXLOG
RUUXQWLPH

Traits As Mixins
6FDODSURYLGHVDFRPSOHWHPL[LQVROXWLRQFDOOHGWUDLWV,QRXUH[DPSOHZHFDQGHILQH
WKHFDOOEDFNDEVWUDFWLRQLQDWUDLWDVLQD-DYDLQWHUIDFHEXWZHFDQDOVRLPSOHPHQWWKH
DEVWUDFWLRQLQWKHWUDLW RUDGHULYHGWUDLW :HFDQGHFODUHFODVVHVWKDW£PL[LQ¤WKH
WUDLWPXFKWKHZD\\RXFDQGHFODUHFODVVHVWKDWLPSOHPHQWDQLQWHUIDFHLQ-DYD+RZ
HYHULQ6FDODZHFDQHYHQPL[LQWUDLWVDWWKHVDPHWLPHZHFUHDWHLQVWDQFHV7KDWLV
ZHGRQ¦WKDYHWRGHFODUHDFODVVILUVWWKDWPL[HVLQDOOWKHWUDLWVZHZDQW6R6FDODWUDLWV
SUHVHUYH VHSDUDWLRQ RI FRQFHUQV ZKLOH JLYLQJ XV WKH DELOLW\ WR FRPSRVH EHKDYLRU RQ
GHPDQG
,I\RXFRPHIURPD-DYDEDFNJURXQG\RXFDQWKLQNRIWUDLWVDVLQWHUIDFHVZLWKRSWLRQDO
LPSOHPHQWDWLRQV2ULI\RXSUHIHU\RXFDQWKLQNRIWUDLWVDVD£FRQVWUDLQHG¤IRUPRI
PXOWLSOHLQKHULWDQFH2WKHUODQJXDJHVSURYLGHFRQVWUXFWVWKDWDUHVLPLODUWRWUDLWVVXFK
DVPRGXOHVLQ5XE\IRUH[DPSOH
/HW¦VXVHDWUDLWWRVHSDUDWHWKHFDOOEDFNKDQGOLQJIURPWKHEXWWRQORJLF:H¦OOJHQHUDOL]H
RXUDSSURDFKDOLWWOHELW&DOOEDFNVDUHUHDOO\DVSHFLDOFDVHRIWKH2EVHUYHU3DWWHUQ VHH

76 | Chapter 4:—Traits

Download at WoweBook.Com
>*2)@ 6ROHW¦VFUHDWHDWUDLWWKDWLPSOHPHQWVWKLVSDWWHUQDQGWKHQXVHLWWR
KDQGOH FDOOEDFN EHKDYLRU 7R VLPSOLI\ WKLQJV ZH¦OO VWDUW ZLWK D VLQJOH FDOOEDFN WKDW
FRXQWVWKHQXPEHURIEXWWRQFOLFNV
)LUVWOHW¦VGHILQHDVLPSOHButtonFODVV
// code-examples/Traits/ui/button.scala

package ui

class Button(val label: String) extends Widget {


def click() = {
// Logic to give the appearance of clicking a button...
}
}

+HUHLVWKHSDUHQWFODVVWidget
// code-examples/Traits/ui/widget.scala

package ui

abstract class Widget

7KHORJLFIRUPDQDJLQJFDOOEDFNV LHWKHclickedCallbacksOLVW LVRPLWWHGDVDUHWKH


WZRDX[LOLDU\FRQVWUXFWRUV2QO\WKHEXWWRQ¦V labelILHOGDQG clickPHWKRGUHPDLQ
7KHclickPHWKRGQRZRQO\FDUHVDERXWWKHYLVXDODSSHDUDQFHRID£SK\VLFDO¤EXWWRQ
EHLQJFOLFNHGButtonKDVRQO\RQHFRQFHUQKDQGOLQJWKH£HVVHQFH¤RIEHLQJDEXWWRQ
+HUHLVDWUDLWWKDWLPSOHPHQWVWKHORJLFRIWKH2EVHUYHU3DWWHUQ
// code-examples/Traits/observer/observer.scala

package observer

trait Subject {
type Observer = { def receiveUpdate(subject: Any) }

private var observers = List[Observer]()


def addObserver(observer:Observer) = observers ::= observer
def notifyObservers = observers foreach (_.receiveUpdate(this))
}

([FHSWIRUWKHtraitNH\ZRUGSubjectORRNVOLNHDQRUPDOFODVVSubjectGHILQHVDOOWKH
PHPEHUVLWGHFODUHV7UDLWVFDQGHFODUHDEVWUDFWPHPEHUVFRQFUHWHPHPEHUVRUERWK
MXVWDVFODVVHVFDQ VHH£2YHUULGLQJ0HPEHUVRI&ODVVHVDQG7UDLWV¤RQSDJHIRU
PRUHGHWDLOV $OVROLNHFODVVHVWUDLWVFDQFRQWDLQQHVWHGWUDLWDQGFODVVGHILQLWLRQVDQG
FODVVHVFDQFRQWDLQQHVWHGWUDLWGHILQLWLRQV
7KH ILUVW OLQH GHILQHV D type IRU DQ Observer 7KLV LV D VWUXFWXUDO W\SH RI WKH IRUP
{ def receiveUpdate(subject:Any) }6WUXFWXUDOW\SHVVSHFLI\RQO\WKHVWUXFWXUHDW\SH
PXVWVXSSRUW\RXFRXOGWKLQNRIWKHPDV£DQRQ\PRXV¤W\SHV

Introducing Traits | 77

Download at WoweBook.Com
,QWKLVFDVHWKHVWUXFWXUDOW\SHLVGHILQHGE\DPHWKRGZLWKDSDUWLFXODUVLJQDWXUH$Q\
W\SHWKDWKDVDPHWKRGZLWKWKLVVLJQDWXUHFDQEHXVHGDVDQREVHUYHU:H¦OOOHDUQPRUH
DERXWVWUXFWXUDOW\SHVLQ&KDSWHU,I\RX¦UHZRQGHULQJZK\ZHGLGQ¦WXVHSubject
DVWKHW\SHRIWKHDUJXPHQWLQVWHDGRIAnyZH¦OOUHYLVLWWKDWLVVXHLQ£6HOI7\SH$QQR
WDWLRQVDQG$EVWUDFW7\SH0HPEHUV¤RQSDJH
7KHPDLQWKLQJWRQRWLFHIRUQRZLVKRZWKLVVWUXFWXUDOW\SHPLQLPL]HVWKHFRXSOLQJ
EHWZHHQWKHSubjectWUDLWDQGDQ\SRWHQWLDOXVHUVRIWKHWUDLW

SubjectLVVWLOOFRXSOHGE\WKHQDPHRIWKHPHWKRGLQObserverWKURXJK
WKHVWUXFWXUDOW\SHLHWRDPHWKRGQDPHG receiveUpdate7KHUHDUH
VHYHUDOZD\VZHFDQUHGXFHWKLVUHPDLQLQJFRXSOLQJ:H¦OOVHHKRZLQ
£2YHUULGLQJ$EVWUDFW7\SHV¤RQSDJH

1H[WZHGHFODUHDOLVWRIREVHUYHUV:HPDNHLWDvarUDWKHUWKDQDvalEHFDXVHList
LV LPPXWDEOH VR ZH PXVW FUHDWH D QHZ OLVW ZKHQ DQ REVHUYHU LV DGGHG XVLQJ WKH
addObserverPHWKRG
:H¦OOGLVFXVV6FDOD ListVPRUHLQ£7KH6FDOD7\SH+LHUDUFK\¤RQSDJHDQGDOVR
LQ&KDSWHU)RUQRZQRWLFHWKDW addObserverXVHVWKHOLVWFRQV£RSHUDWRU¤PHWKRG
:: WRSUHSHQGDQobserverWRWKHOLVWRIobservers7KHscalaFRPSLOHULVVPDUWHQRXJK
WRWXUQWKHIROORZLQJVWDWHPHQW
observers ::= observer

LQWRWKLVVWDWHPHQW
observers = observer :: observers

1RWH WKDW ZH ZURWH observer :: observers ZLWK WKH H[LVWLQJ observers OLVW RQ WKH
ULJKWKDQG VLGH 5HFDOO WKDW DQ\ PHWKRG WKDW HQGV ZLWK : ELQGV WR WKH ULJKW 6R WKH
SUHYLRXVVWDWHPHQWLVHTXLYDOHQWWRWKHIROORZLQJVWDWHPHQW
observers = observers.::(observer)

7KHnotifyObserversPHWKRGLWHUDWHVWKURXJKWKHobserversXVLQJWKHforeachPHWKRG
DQGFDOOVreceiveUpdateRQHDFKRQH 1RWHWKDWZHDUHXVLQJWKH£LQIL[¤RSHUDWRUQR
WDWLRQLQVWHDGRIobservers.foreach :HXVHWKHSODFHKROGHU_WRVKRUWHQWKHIROORZLQJ
H[SUHVVLRQ
(obs) => obs.receiveUpdate(this)

LQWRWKLVH[SUHVVLRQ
_.receiveUpdate(this)

7KLV H[SUHVVLRQ LV DFWXDOO\ WKH ERG\ RI DQ £DQRQ\PRXV IXQFWLRQ¤ FDOOHG DIXQFWLRQ
OLWHUDO LQ 6FDOD 7KLV LV VLPLODU WR D ODPEGD DQG OLNH FRQVWUXFWV XVHG LQ PDQ\ RWKHU
ODQJXDJHV )XQFWLRQ OLWHUDOV DQG WKH UHODWHG FRQFHSW RI D FORVXUH DUH GLVFXVVHG LQ
£)XQFWLRQ/LWHUDOVDQG&ORVXUHV¤RQSDJH

78 | Chapter 4:—Traits

Download at WoweBook.Com
,Q-DYDWKHforeachPHWKRGZRXOGSUREDEO\WDNHDQLQWHUIDFHDQG\RXZRXOGSDVVDQ
LQVWDQFHRIDFODVVWKDWLPSOHPHQWVWKHLQWHUIDFH HJWKHZD\ComparableLVW\SLFDOO\
XVHG 
,Q6FDODWKHList[A].foreachPHWKRGH[SHFWVDQDUJXPHQWRIW\SH(A) => UnitZKLFK
LVDIXQFWLRQWDNLQJDQLQVWDQFHRIW\SHA¢ZKHUHAUHSUHVHQWVWKHW\SHRIWKHHOHPHQWV
RIWKHOLVW ObserverLQWKLVFDVH ¢DQGUHWXUQLQJUnit OLNHvoidLQ-DYD 

:HFKRVHWRXVHD varZLWKLPPXWDEOH ListsIRUWKHREVHUYHUVLQWKLV


H[DPSOH :H FRXOG KDYH XVHG D val ZLWK D PXWDEOH W\SH OLNH
ListBuffer 7KDW FKRLFH ZRXOG PDNH D OLWWOH PRUH VHQVH IRU D UHDO
DSSOLFDWLRQEXWZHZDQWHGWRDYRLGWKHGLVWUDFWLRQRIH[SODLQLQJQHZ
OLEUDU\FODVVHV

2QFH DJDLQ ZH OHDUQHG D ORW RI 6FDOD IURP D VPDOO H[DPSOH 1RZ OHW¦V SXW RXU
SubjectWUDLWWRXVH+HUHLV ObservableButtonZKLFKVXEFODVVHV ButtonDQGPL[HVLQ
Subject
// code-examples/Traits/ui/observable-button.scala

package ui
import observer._

class ObservableButton(name: String) extends Button(name) with Subject {


override def click() = {
super.click()
notifyObservers
}
}

:H VWDUW E\ LPSRUWLQJ HYHU\WKLQJ LQ WKH observer SDFNDJH XVLQJ WKH _ ZLOGFDUG
$FWXDOO\ZHKDYHRQO\GHILQHGWKHSubjectWUDLWLQWKHSDFNDJH
7KHQHZFODVVXVHVWKHwithNH\ZRUGWRDGGWKHSubjectWUDLWWRWKHFODVVObservable
ButtonRYHUULGHVWKHclickPHWKRG8VLQJWKHsuperNH\ZRUG VHH£2YHUULGLQJ$EVWUDFW
DQG &RQFUHWH 0HWKRGV¤ RQ SDJH   LW ILUVW LQYRNHV WKH £VXSHUFODVV¤ PHWKRG
Button.clickDQGWKHQLWQRWLILHVWKHREVHUYHUV6LQFHWKHQHZclickPHWKRGRYHUULGHV
Button¦VFRQFUHWHLPSOHPHQWDWLRQWKHoverrideNH\ZRUGLVUHTXLUHG
7KH withNH\ZRUGLVDQDORJRXVWR-DYD¦V implementsNH\ZRUGIRULQWHUIDFHV<RXFDQ
VSHFLI\DVPDQ\WUDLWVDV\RXZDQWHDFKZLWKLWVRZQwithNH\ZRUG
$FODVVFDQH[WHQGDWUDLWDQGDWUDLWFDQH[WHQGDFODVV,QIDFWRXUWidgetFODVVHDUOLHU
FRXOGKDYHEHHQGHFODUHGWREHDWUDLW

,I\RXGHFODUHDFODVVWKDWXVHVRQHRUPRUHWUDLWVDQGLWGRHVQ¦WH[WHQG
DQRWKHUFODVV\RXPXVWXVHWKHextendsNH\ZRUGIRUWKHILUVWWUDLWOLVWHG

Introducing Traits | 79

Download at WoweBook.Com
,I\RXGRQ¦WXVHextendsIRUWKHILUVWWUDLWHJ\RXZULWHWKHIROORZLQJ
// ERROR:
class ObservableButton(name: String) with Button(name) with Subject {...}

<RX¦OOJHWDQHUURUOLNHWKLV
... error: ';' expected but 'with' found.
class ObservableButton(name: String) with Button(name) with Subject {...}
^

7KHHUURUVKRXOGUHDOO\VD\£withIRXQGEXWextendsH[SHFWHG¤
7RGHPRQVWUDWHWKLVFRGHOHW¦VVWDUWZLWKDFODVVIRUREVHUYLQJEXWWRQFOLFNVWKDWVLPSO\
FRXQWVWKHQXPEHURIFOLFNV
// code-examples/Traits/ui/button-count-observer.scala

package ui
import observer._

class ButtonCountObserver {
var count = 0
def receiveUpdate(subject: Any) = count += 1
}

)LQDOO\OHW¦VZULWHDWHVWWKDWH[HUFLVHVDOOWKHVHFODVVHV:HZLOOXVHWKH6SHFVOLEUDU\
GLVFXVVHGLQ£6SHFV¤RQSDJH WRZULWHD%HKDYLRU'ULYHQ'HYHORSPHQW >%''@
£VSHFLILFDWLRQ¤WKDWH[HUFLVHVWKHFRPELQHGButtonDQGSubjectW\SHV
// code-examples/Traits/ui/button-observer-spec.scala

package ui
import org.specs._
import observer._

object ButtonObserverSpec extends Specification {


"A Button Observer" should {
"observe button clicks" in {
val observableButton = new ObservableButton("Okay")
val buttonObserver = new ButtonCountObserver
observableButton.addObserver(buttonObserver)

for (i <- 1 to 3) observableButton.click()


buttonObserver.count mustEqual 3
}
}
}

,I\RXGRZQORDGHGWKHFRGHH[DPSOHVIURPWKH2¦5HLOO\VLWH\RXFDQIROORZWKHGLUHF
WLRQVLQLWV5($'0(ILOHVIRUEXLOGLQJDQGUXQQLQJWKHH[DPSOHVLQWKLVFKDSWHU7KH
RXWSXWRIWKHspecs£WDUJHW¤RIWKHEXLOGVKRXOGLQFOXGHWKHIROORZLQJWH[W
Specification "ButtonCountObserverSpec"
A Button Observer should
+ observe button clicks

80 | Chapter 4:—Traits

Download at WoweBook.Com
Total for specification "ButtonCountObserverSpec":
Finished in 0 second, 10 ms
1 example, 1 expectation, 0 failure, 0 error

1RWLFHWKDWWKHVWULQJV A Button Observer shouldDQG observe button clicksFRUUH


VSRQGWRVWULQJVLQWKHH[DPSOH7KHRXWSXWRID6SHFVUXQSURYLGHVDQLFHVXPPDU\RI
WKHUHTXLUHPHQWVIRUWKHLWHPVEHLQJWHVWHGDVVXPLQJJRRGFKRLFHVZHUHPDGHIRUWKH
VWULQJV
7KHERG\RIWKHWHVWFUHDWHVDQ£2ND\¤ObservableButtonDQGDButtonCountObserver
ZKLFKJLYHVWKHREVHUYHUWRWKHEXWWRQ7KHEXWWRQLVFOLFNHGWKUHHWLPHVXVLQJWKH
forORRS7KHODVWOLQHUHTXLUHVWKHREVHUYHU¦VcountWRHTXDO,I\RXDUHDFFXVWRPHG
WRXVLQJDQ;8QLWVW\OH7''WRROOLNHJUnit VHH>-8QLW@ RUScalaTest VHH>6FDOD7HVW
7RRO@DQG£6FDOD7HVW¤RQSDJH WKHQWKHODVWOLQHLVHTXLYDOHQWWRWKHIROORZLQJ
JUnitDVVHUWLRQ
assertEquals(3, buttonObserver.count)

7KH6SHFVOLEUDU\ VHH£6SHFV¤RQSDJH DQGWKH6FDOD7HVWOLEUDU\


VHH£6FDOD7HVW¤RQSDJH ERWKVXSSRUW%HKDYLRU'ULYHQ'HYHORS
PHQW >%''@ DVW\OHRI7HVW'ULYHQ'HYHORSPHQW >7''@ WKDWHPSKD
VL]HVWKH£VSHFLILFDWLRQ¤UROHRIWHVWV

6XSSRVHZHQHHGRQO\RQH ObservableButtonLQVWDQFH":HDFWXDOO\GRQ¦WKDYHWRGH
FODUHDFODVVWKDWVXEFODVVHVButtonZLWKSubject:HFDQLQFRUSRUDWHWKHWUDLWZKHQZH
FUHDWHWKHLQVWDQFH
7KHQH[WH[DPSOHVKRZVDUHYLVHG6SHFVILOHWKDWLQVWDQWLDWHVD ButtonZLWK Subject
PL[HGLQDVSDUWRIWKHGHFODUDWLRQ
// code-examples/Traits/ui/button-observer-anon-spec.scala

package ui
import org.specs._
import observer._

object ButtonObserverAnonSpec extends Specification {


"A Button Observer" should {
"observe button clicks" in {
val observableButton = new Button("Okay") with Subject {
override def click() = {
super.click()
notifyObservers
}
}

val buttonObserver = new ButtonCountObserver


observableButton.addObserver(buttonObserver)

for (i <- 1 to 3) observableButton.click()


buttonObserver.count mustEqual 3

Introducing Traits | 81

Download at WoweBook.Com
}
}
}

7KHUHYLVHGGHFODUDWLRQRI observableButtonDFWXDOO\FUHDWHVDQDQRQ\PRXVFODVVLQ
ZKLFK ZH RYHUULGH WKH click PHWKRG DV EHIRUH 7KH PDLQ GLIIHUHQFH ZLWK FUHDWLQJ
DQRQ\PRXVFODVVHVLQ-DYDLVWKDWZHFDQLQFRUSRUDWHWUDLWVLQWKLVSURFHVV-DYDGRHV
QRWOHW\RXLPSOHPHQWDQHZLQWHUIDFHZKLOHLQVWDQWLDWLQJDFODVV
)LQDOO\QRWHWKDWWKHLQKHULWDQFHKLHUDUFK\IRUDQLQVWDQFHFDQEHFRPSOH[LILWPL[HV
LQ WUDLWV WKDW H[WHQG RWKHU WUDLWV HWF :H¦OO GLVFXVV WKH GHWDLOV RI WKH KLHUDUFK\ LQ
£/LQHDUL]DWLRQRIDQ2EMHFW¦V+LHUDUFK\¤RQSDJH

Stackable Traits
7KHUHDUHDFRXSOHRIUHILQHPHQWVZHFDQGRWRLPSURYHWKHUHXVDELOLW\RIRXUZRUNDQG
WRPDNHLWHDVLHUWRXVHPRUHWKDQRQHWUDLWDWDWLPHLHWR£VWDFN¤WKHP
)LUVWOHW¦VLQWURGXFHDQHZWUDLWClickableDQDEVWUDFWLRQIRUDQ\ZLGJHWWKDWUHVSRQGV
WRFOLFNV
// code-examples/Traits/ui2/clickable.scala

package ui2

trait Clickable {
def click()
}

:H¦UHVWDUWLQJZLWKDQHZSDFNDJHui2WRPDNHLWHDVLHUWRNHHSROGHU
DQGQHZHUYHUVLRQVRIWKHH[DPSOHVGLVWLQFWLQWKHGRZQORDGDEOHFRGH

7KHClickableWUDLWORRNVMXVWOLNHD-DYDLQWHUIDFHLWLVFRPSOHWHO\DEVWUDFW,WGHILQHV
DVLQJOHDEVWUDFWPHWKRG click7KHPHWKRGLVDEVWUDFWEHFDXVHLWKDVQRERG\,I
ClickableZHUHDFODVVZHZRXOGKDYHWRDGGWKH abstractNH\ZRUGLQIURQWRIWKH
classNH\ZRUG7KLVLVQRWQHFHVVDU\IRUWUDLWV
+HUHLVWKHUHIDFWRUHGEXWWRQZKLFKXVHVWKHWUDLW
// code-examples/Traits/ui2/button.scala

package ui2

import ui.Widget

class Button(val label: String) extends Widget with Clickable {


def click() = {
// Logic to give the appearance of clicking a button...

82 | Chapter 4:—Traits

Download at WoweBook.Com
}
}

7KLVFRGHLVOLNH-DYDFRGHWKDWLPSOHPHQWVDClickableLQWHUIDFH
:KHQZHSUHYLRXVO\GHILQHGObservableButton LQ£7UDLWV$V0L[LQV¤RQSDJH ZH
RYHUURGH Button.click WR QRWLI\ WKH REVHUYHUV :H KDG WR GXSOLFDWH WKDW ORJLF LQ
ButtonObserverAnonSpecZKHQZHGHFODUHGobservableButtonDVDButtonLQVWDQFHWKDW
PL[HGLQWKHSubjectWUDLWGLUHFWO\/HW¦VHOLPLQDWHWKLVGXSOLFDWLRQ
:KHQZHUHIDFWRUWKHFRGHWKLVZD\ZHUHDOL]HWKDWZHGRQ¦WUHDOO\FDUHDERXWREVHUYLQJ
EXWWRQVZHFDUHDERXWREVHUYLQJFOLFNV+HUHLVDWUDLWWKDWIRFXVHVVROHO\RQREVHUYLQJ
Clickable
// code-examples/Traits/ui2/observable-clicks.scala

package ui2
import observer._

trait ObservableClicks extends Clickable with Subject {


abstract override def click() = {
super.click()
notifyObservers
}
}

7KHObservableClicksWUDLWH[WHQGVClickableDQGPL[HVLQSubject,WWKHQRYHUULGHV
WKHclickPHWKRGZLWKDQLPSOHPHQWDWLRQWKDWORRNVDOPRVWWKHVDPHDVWKHRYHUULGGHQ
PHWKRG VKRZQ LQ £7UDLWV $V 0L[LQV¤ RQ SDJH  7KH LPSRUWDQW GLIIHUHQFH LV WKH
abstractNH\ZRUG
/RRNFORVHO\DWWKLVPHWKRG,WFDOOV super.click()EXWZKDWLV superLQWKLVFDVH"$W
WKLVSRLQWLWFRXOGRQO\DSSHDUWREHClickableZKLFKGHFODUHVEXWGRHVQRWGHILQHWKH
clickPHWKRGRULWFRXOGEH SubjectZKLFKGRHVQ¦WKDYHD clickPHWKRG6R super
FDQ¦WEHERXQGDWOHDVWQRW\HW
,QIDFW superZLOOEHERXQGZKHQWKLVWUDLWLVPL[HGLQWRDQLQVWDQFHWKDWGHILQHVD
FRQFUHWH clickPHWKRGVXFKDV Button7KHUHIRUHZHQHHGDQ abstractNH\ZRUGRQ
ObservableClicks.clickWRWHOOWKHFRPSLOHU DQGWKHUHDGHU WKDWclickLVQRW\HWIXOO\
LPSOHPHQWHGHYHQWKRXJKObservableClicks.clickKDVDERG\

([FHSWIRUGHFODULQJDEVWUDFWFODVVHVWKH abstractNH\ZRUGLVRQO\UH
TXLUHGRQDPHWKRGLQDWUDLWZKHQWKHPHWKRGKDVDERG\EXWLWFDOOV
WKH super PHWKRG WKDW GRHVQ¦W KDYH D FRQFUHWH LPSOHPHQWDWLRQ LQ
SDUHQWVRIWKHWUDLW

/HW¦VXVHWKLVWUDLWZLWKButtonDQGLWVFRQFUHWHclickPHWKRGLQD6SHFVWHVW
// code-examples/Traits/ui2/button-clickable-observer-spec.scala

package ui2

Stackable Traits | 83

Download at WoweBook.Com
import org.specs._
import observer._
import ui.ButtonCountObserver

object ButtonClickableObserverSpec extends Specification {


"A Button Observer" should {
"observe button clicks" in {
val observableButton = new Button("Okay") with ObservableClicks
val buttonClickCountObserver = new ButtonCountObserver
observableButton.addObserver(buttonClickCountObserver)

for (i <- 1 to 3) observableButton.click()


buttonClickCountObserver.count mustEqual 3
}
}
}

&RPSDUH WKLV FRGH WR ButtonObserverAnonSpec :H LQVWDQWLDWH D Button ZLWK WKH
ObservableClicksWUDLWPL[HGLQEXWQRZWKHUHLVQRRYHUULGHRIclickUHTXLUHG+HQFH
WKLVFOLHQWRIButtonGRHVQ¦WKDYHWRZRUU\DERXWSURSHUO\RYHUULGLQJclick7KHKDUG
ZRUNLVDOUHDG\GRQHE\ObservableClicks7KHGHVLUHGEHKDYLRULVFRPSRVHGGHFODUD
WLYHO\ZKHQQHHGHG
/HW¦V ILQLVK RXU H[DPSOH E\ DGGLQJ D VHFRQG WUDLW 7KH -DYD%HDQV VSHFLILFDWLRQ VHH
>-DYD%HDQV6SHF@ KDVWKHLGHDRI£YHWRDEOH¤HYHQWVZKHUHOLVWHQHUVIRUFKDQJHVWRD
-DYD%HDQ FDQ YHWR WKH FKDQJH /HW¦V LPSOHPHQW VRPHWKLQJ VLPLODU ZLWK D WUDLW WKDW
YHWRHVPRUHWKDQDVHWQXPEHURIFOLFNV
// code-examples/Traits/ui2/vetoable-clicks.scala

package ui2
import observer._

trait VetoableClicks extends Clickable {


val maxAllowed = 1 // default
private var count = 0

abstract override def click() = {


if (count < maxAllowed) {
count += 1
super.click()
}
}
}

2QFHDJDLQZHRYHUULGHWKH clickPHWKRG$VEHIRUHWKHRYHUULGHPXVWEHGHFODUHG
abstract7KHPD[LPXPDOORZHGQXPEHURIFOLFNVGHIDXOWVWR<RXPLJKWZRQGHU
ZKDW ZH PHDQ E\ £GHIDXOWV¤ KHUH ,VQ¦W WKH ILHOG GHFODUHG WR EH D val" 7KHUH LV QR
FRQVWUXFWRU GHILQHG WR LQLWLDOL]H LW WR DQRWKHU YDOXH :H¦OO UHYLVLW WKHVH TXHVWLRQV LQ
£2YHUULGLQJ0HPEHUVRI&ODVVHVDQG7UDLWV¤RQSDJH
7KLV WUDLW DOVR GHFODUHV D count YDULDEOH WR NHHS WUDFN RI WKH QXPEHU RI FOLFNV VHHQ
,W LV GHFODUHG private VR LW LV LQYLVLEOH RXWVLGH WKH WUDLW VHH £9LVLELOLW\

84 | Chapter 4:—Traits

Download at WoweBook.Com
5XOHV¤RQSDJH 7KHRYHUULGGHQ clickPHWKRGLQFUHPHQWV count,WRQO\FDOOVWKH
super.click()PHWKRGLIWKHFRXQWLVOHVVWKDQRUHTXDOWRWKHmaxAllowedFRXQW
+HUHLVD6SHFVREMHFWWKDWGHPRQVWUDWHVObservableClicksDQGVetoableClicksZRUNLQJ
WRJHWKHU1RWHWKDWDVHSDUDWH withNH\ZRUGLVUHTXLUHGIRUHDFKWUDLWDVRSSRVHGWR
XVLQJ RQH NH\ZRUG DQG VHSDUDWLQJ WKH QDPHV ZLWK FRPPDV DV -DYD GRHV IRU
implementsFODXVHV
// code-examples/Traits/ui2/button-clickable-observer-vetoable-spec.scala

package ui2
import org.specs._
import observer._
import ui.ButtonCountObserver

object ButtonClickableObserverVetoableSpec extends Specification {


"A Button Observer with Vetoable Clicks" should {
"observe only the first button click" in {
val observableButton =
new Button("Okay") with ObservableClicks with VetoableClicks
val buttonClickCountObserver = new ButtonCountObserver
observableButton.addObserver(buttonClickCountObserver)

for (i <- 1 to 3) observableButton.click()


buttonClickCountObserver.count mustEqual 1
}
}
}

7KHH[SHFWHGREVHUYHUFRXQWLV7KHobservableButtonLVGHFODUHGDVIROORZV
new Button("Okay") with ObservableClicks with VetoableClicks

:HFDQLQIHUWKDWWKHclickRYHUULGHLQVetoableClicksLVFDOOHGEHIRUHWKHclickRYHUULGH
LQ ObservableClicks /RRVHO\ VSHDNLQJ VLQFH RXU DQRQ\PRXV FODVV GRHVQ¦W GHILQH
clickLWVHOIWKHPHWKRGORRNXSSURFHHGVULJKWWROHIWDVGHFODUHG,W¦VDFWXDOO\PRUH
FRPSOLFDWHG WKDQ WKDW DV ZH¦OO VHH ODWHU LQ £/LQHDUL]DWLRQ RI DQ 2EMHFW¦V +LHUDU
FK\¤RQSDJH
,QWKHPHDQWLPHZKDWKDSSHQVLIZHXVHWKHWUDLWVLQWKHUHYHUVHRUGHU"
// code-examples/Traits/ui2/button-vetoable-clickable-observer-spec.scala

package ui2
import org.specs._
import observer._
import ui.ButtonCountObserver

object ButtonVetoableClickableObserverSpec extends Specification {


"A Vetoable Button with Click Observer" should {
"observe all the button clicks, even when some are vetoed" in {
val observableButton =
new Button("Okay") with VetoableClicks with ObservableClicks
val buttonClickCountObserver = new ButtonCountObserver
observableButton.addObserver(buttonClickCountObserver)

Stackable Traits | 85

Download at WoweBook.Com
for (i <- 1 to 3) observableButton.click()
buttonClickCountObserver.count mustEqual 3
}
}
}

1RZ WKH H[SHFWHG REVHUYHU FRXQW LV  ObservableClicks QRZ KDV SUHFHGHQFH RYHU
VetoableClicksVRWKHFRXQWRIFOLFNVLVLQFUHPHQWHGHYHQZKHQVRPHFOLFNVDUHVXE
VHTXHQWO\YHWRHG
6RWKHRUGHURIGHFODUDWLRQPDWWHUVZKLFKLVLPSRUWDQWWRUHPHPEHUIRUSUHYHQWLQJ
XQH[SHFWHGEHKDYLRUZKHQWUDLWVLPSDFWHDFKRWKHU3HUKDSVDQRWKHUOHVVRQWRQRWHLV
WKDWVSOLWWLQJREMHFWVLQWRWRRPDQ\ILQHJUDLQHGWUDLWVFDQREVFXUHWKHRUGHURIH[HFX
WLRQLQ\RXUFRGH
%UHDNLQJ XS \RXU DSSOLFDWLRQ LQWR VPDOO IRFXVHG WUDLWV LV D SRZHUIXO ZD\ WR FUHDWH
UHXVDEOHVFDODEOHDEVWUDFWLRQVDQG£FRPSRQHQWV¤&RPSOH[EHKDYLRUVFDQEHEXLOWXS
WKURXJKGHFODUDWLYHFRPSRVLWLRQRIWUDLWV:HZLOOH[SORUHWKLVLGHDLQJUHDWHUGHWDLOLQ
£6FDODEOH$EVWUDFWLRQV¤RQSDJH

Constructing Traits
7UDLWVGRQ¦WVXSSRUWDX[LOLDU\FRQVWUXFWRUVQRUGRWKH\DFFHSWDQDUJXPHQWOLVWIRUWKH
SULPDU\FRQVWUXFWRUWKHERG\RIDWUDLW7UDLWVFDQH[WHQGFODVVHVRURWKHUWUDLWV+RZ
HYHUWKH\FDQ¦WSDVVDUJXPHQWVWRWKHSDUHQWFODVVFRQVWUXFWRU HYHQOLWHUDOYDOXHV VR
WUDLWVFDQRQO\H[WHQGFODVVHVWKDWKDYHDQRDUJXPHQWSULPDU\RUDX[LOLDU\FRQVWUXFWRU
+RZHYHUOLNHFODVVHVWKHERG\RIDWUDLWLVH[HFXWHGHYHU\WLPHDQLQVWDQFHLVFUHDWHG
WKDWXVHVWKHWUDLWDVGHPRQVWUDWHGE\WKHIROORZLQJVFULSW
// code-examples/Traits/trait-construction-script.scala

trait T1 {
println( " in T1: x = " + x )
val x=1
println( " in T1: x = " + x )
}
trait T2 {
println( " in T2: y = " + y )
val y="T2"
println( " in T2: y = " + y )
}

class Base12 {
println( " in Base12: b = " + b )
val b="Base12"
println( " in Base12: b = " + b )
}
class C12 extends Base12 with T1 with T2 {
println( " in C12: c = " + c )
val c="C12"

86 | Chapter 4:—Traits

Download at WoweBook.Com
println( " in C12: c = " + c )
}
println( "Creating C12:" )
new C12
println( "After Creating C12" )

5XQQLQJWKLVVFULSWZLWKWKHscalaFRPPDQG\LHOGVWKHIROORZLQJRXWSXW
Creating C12:
in Base12: b = null
in Base12: b = Base12
in T1: x = 0
in T1: x = 1
in T2: y = null
in T2: y = T2
in C12: c = null
in C12: c = C12
After Creating C12

1RWLFHWKHRUGHURILQYRFDWLRQRIWKHFODVVDQGWUDLWFRQVWUXFWRUV6LQFHWKHGHFODUDWLRQ
RIC12LVextends Base12 with T1 with T2WKHRUGHURIFRQVWUXFWLRQIRUWKLVVLPSOHFODVV
KLHUDUFK\LVOHIWWRULJKWVWDUWLQJZLWKWKHEDVHFODVV Base12IROORZHGE\WKHWUDLWV T1
DQG T2 DQG HQGLQJ ZLWK WKH C12 FRQVWUXFWRU ERG\ )RU FRQVWUXFWLQJ DUELWUDULO\
FRPSOH[KLHUDUFKLHVVHH£/LQHDUL]DWLRQRIDQ2EMHFW¦V+LHUDUFK\¤RQSDJH
6RZKLOH\RXFDQ¦WSDVVFRQVWUXFWLRQSDUDPHWHUVWRWUDLWV\RXFDQLQLWLDOL]HILHOGVZLWK
GHIDXOWYDOXHVRUOHDYHWKHPDEVWUDFW:HDFWXDOO\VDZWKLVEHIRUHLQRXUSubjectWUDLW
ZKHUHWKHSubject.observersILHOGZDVLQLWLDOL]HGWRDQHPSW\OLVW
,IDFRQFUHWHILHOGLQDWUDLWGRHVQRWKDYHDVXLWDEOHGHIDXOWYDOXHWKHUHLVQR£IDLOVDIH¤
ZD\WRLQLWLDOL]HWKHYDOXH$OOWKHDOWHUQDWLYHDSSURDFKHVUHTXLUHVRPHDGKRFVWHSVE\
XVHUVRIWKHWUDLWZKLFKLVHUURUSURQHEHFDXVHWKH\PLJKWGRLWZURQJRUIRUJHWWRGR
LWDOO3HUKDSVWKHILHOGVKRXOGEHOHIWDEVWUDFWVRWKDWFODVVHVRURWKHUWUDLWVWKDWXVH
WKLVWUDLWDUHIRUFHGWRGHILQHWKHYDOXHDSSURSULDWHO\:H¦OOGLVFXVVRYHUULGLQJDEVWUDFW
DQGFRQFUHWHPHPEHUVLQGHWDLOLQ&KDSWHU
$QRWKHUVROXWLRQLVWRPRYHWKDWILHOGWRDVHSDUDWHFODVVZKHUHWKHFRQVWUXFWLRQSURFHVV
FDQJXDUDQWHHWKDWWKHFRUUHFWLQLWLDOL]DWLRQGDWDLVVXSSOLHGE\WKHXVHU,WPLJKWEH
WKDWWKHZKROHWUDLWVKRXOGDFWXDOO\EHDFODVVLQVWHDGVR\RXFDQGHILQHDFRQVWUXFWRU
IRULWWKDWLQLWLDOL]HVWKHILHOG

Class or Trait?
:KHQFRQVLGHULQJZKHWKHUD£FRQFHSW¤VKRXOGEHDWUDLWRUDFODVVNHHSLQPLQGWKDW
WUDLWVDVPL[LQVPDNHWKHPRVWVHQVHIRU£DGMXQFW¤EHKDYLRU,I\RXILQGWKDWDSDUWLFXODU
WUDLWLVXVHGPRVWRIWHQDVDSDUHQWRIRWKHUFODVVHVVRWKDWWKHFKLOGFODVVHVEHKDYHDV
WKHSDUHQWWUDLWWKHQFRQVLGHUGHILQLQJWKHWUDLWDVDFODVVLQVWHDGWRPDNHWKLVORJLFDO
UHODWLRQVKLSPRUHFOHDU :HVDLGEHKDYHVDVUDWKHUWKDQLVDEHFDXVHWKHIRUPHULVWKH
PRUHSUHFLVHGHILQLWLRQRILQKHULWDQFHEDVHGRQWKH/LVNRY6XEVWLWXWLRQ3ULQFLSOH¢VHH
>0DUWLQ@IRUH[DPSOH

Constructing Traits | 87

Download at WoweBook.Com
$YRLGFRQFUHWHILHOGVLQWUDLWVWKDWFDQ¦WEHLQLWLDOL]HGWRVXLWDEOHGHIDXOW
YDOXHV8VHDEVWUDFWILHOGVLQVWHDGRUFRQYHUWWKHWUDLWWRDFODVVZLWK
D FRQVWUXFWRU 2I FRXUVH VWDWHOHVV WUDLWV GRQ¦W KDYH DQ\ LVVXHV ZLWK
LQLWLDOL]DWLRQ

,W¦VDJHQHUDOSULQFLSOHRIJRRGREMHFWRULHQWHGGHVLJQWKDWDQLQVWDQFHVKRXOGDOZD\V
EHLQDNQRZQYDOLGVWDWHVWDUWLQJIURPWKHPRPHQWWKHFRQVWUXFWLRQSURFHVVILQLVKHV

Recap and What’s Next


,QWKLVFKDSWHUZHOHDUQHGKRZWRXVHWUDLWVWRHQFDSVXODWHDQGVKDUHFURVVFXWWLQJ
FRQFHUQVEHWZHHQFODVVHV:HFRYHUHGZKHQDQGKRZWRXVHWUDLWVKRZWR£VWDFN¤
PXOWLSOHWUDLWVDQGWKHUXOHVIRULQLWLDOL]LQJYDOXHVZLWKLQWUDLWV
,QWKHQH[WFKDSWHUZHH[SORUHKRZWKHIXQGDPHQWDOVRIREMHFWRULHQWHGSURJUDPPLQJ
ZRUNLQ6FDOD(YHQLI\RX¦UHDQROGKDQGDWREMHFWRULHQWHGSURJUDPPLQJ\RX¦OOZDQW
WRUHDGWKHQH[WVHYHUDOFKDSWHUVWRXQGHUVWDQGWKHSDUWLFXODUVRI6FDOD¦VDSSURDFKWR
223

88 | Chapter 4:—Traits

Download at WoweBook.Com
CHAPTER 5
Basic Object-Oriented Programming
in Scala

6FDODLVDQREMHFWRULHQWHGODQJXDJHOLNH-DYD3\WKRQ5XE\6PDOOWDONDQGRWKHUV,I
\RX¦UHFRPLQJIURPWKH-DYDZRUOG\RX¦OOQRWLFHVRPHQRWDEOHLPSURYHPHQWVRYHUWKH
OLPLWDWLRQVRI-DYD¦VREMHFWPRGHO
:HDVVXPH\RXKDYHVRPHSULRUH[SHULHQFHZLWKREMHFWRULHQWHGSURJUDPPLQJ 223 
VRZHZLOOQRWGLVFXVVWKHEDVLFSULQFLSOHVKHUHDOWKRXJKVRPHFRPPRQWHUPVDQG
FRQFHSWVDUHGLVFXVVHGLQWKH*ORVVDU\RQSDJH6HH>0H\HU@IRUDGHWDLOHG
LQWURGXFWLRQWR223VHH>0DUWLQ@IRUDUHFHQWWUHDWPHQWRI223SULQFLSOHVLQWKH
FRQWH[WRI£DJLOHVRIWZDUHGHYHORSPHQW¤VHH>*2)@WROHDUQDERXWGHVLJQSDW
WHUQVDQGVHH>:LUIV%URFN@IRUDGLVFXVVLRQRIREMHFWRULHQWHGGHVLJQFRQFHSWV

Class and Object Basics


/HW¦VUHYLHZWKHWHUPLQRORJ\RI223LQ6FDOD

:H VDZ SUHYLRXVO\ WKDW 6FDOD KDV WKH FRQFHSW RI D GHFODUHG object
ZKLFK ZH¦OO GLJ LQWR LQ £&ODVVHV DQG 2EMHFWV :KHUH $UH WKH 6WDW
LFV"¤RQSDJH:H¦OOXVHWKHWHUPLQVWDQFHWRUHIHUWRDFODVVLQVWDQFH
JHQHULFDOO\PHDQLQJHLWKHUDQobjectRUDQLQVWDQFHRIDclassWRDYRLG
WKHSRWHQWLDOIRUFRQIXVLRQEHWZHHQWKHVHWZRFRQFHSWV

&ODVVHVDUHGHFODUHGZLWKWKHNH\ZRUGclass:HZLOOVHHODWHUWKDWDGGLWLRQDONH\ZRUGV
FDQDOVREHXVHGOLNHfinalWRSUHYHQWFUHDWLRQRIGHULYHGFODVVHVDQGabstractWRLQGL
FDWHWKDWWKHFODVVFDQ¦WEHLQVWDQWLDWHGXVXDOO\EHFDXVHLWFRQWDLQVRULQKHULWVPHPEHU
GHFODUDWLRQVZLWKRXWSURYLGLQJFRQFUHWHGHILQLWLRQVIRUWKHP
$Q LQVWDQFH FDQ UHIHU WR LWVHOI XVLQJ WKH this NH\ZRUG MXVW DV LQ -DYD DQG VLPLODU
ODQJXDJHV

89

Download at WoweBook.Com
)ROORZLQJ6FDOD¦VFRQYHQWLRQZHXVHWKHWHUPPHWKRGIRUDIXQFWLRQWKDWLVWLHGWRDQ
LQVWDQFH 6RPH RWKHU REMHFWRULHQWHG ODQJXDJHV XVH WKH WHUP £PHPEHU IXQFWLRQ¤
0HWKRGGHILQLWLRQVVWDUWZLWKWKHdefNH\ZRUG
/LNH-DYDEXWXQOLNH5XE\DQG3\WKRQ6FDODDOORZVRYHUORDGHGPHWKRGV7ZRRUPRUH
PHWKRGVFDQKDYHWKHVDPHQDPHDVORQJDVWKHLUIXOOVLJQDWXUHVDUHXQLTXH7KHVLJ
QDWXUH LQFOXGHV WKH W\SH QDPH WKH OLVW RI SDUDPHWHUV ZLWK W\SHV DQG WKH PHWKRG¦V
UHWXUQYDOXH
7KHUHLVDQH[FHSWLRQWRWKLVUXOHGXHWRW\SHHUDVXUHZKLFKLVDIHDWXUHRIWKH-90
RQO\EXWLVXVHGE\6FDODRQERWKWKH-90DQG1(7SODWIRUPVWRPLQLPL]HLQFRP
SDWLELOLWLHV6XSSRVHWZRPHWKRGVDUHLGHQWLFDOH[FHSWWKDWRQHWDNHVDSDUDPHWHURI
W\SHList[String]ZKLOHWKHRWKHUWDNHVDSDUDPHWHURIW\SHList[Int]DVIROORZV
// code-examples/BasicOOP/type-erasure-wont-compile.scala
// WON'T COMPILE

object Foo {
def bar(list: List[String]) = list.toString
def bar(list: List[Int]) = list.size.toString
}

<RX¦OOJHWDFRPSLODWLRQHUURURQWKHVHFRQGPHWKRGEHFDXVHWKHWZRPHWKRGVZLOO
KDYHDQLGHQWLFDOVLJQDWXUHDIWHUW\SHHUDVXUH

7KHscalaLQWHUSUHWHUZLOOOHW\RXW\SHLQERWKPHWKRGV,WVLPSO\GURSV
WKHILUVWYHUVLRQ+RZHYHULI\RXWU\WRORDGWKHSUHYLRXVH[DPSOHXVLQJ
WKH:load fileFRPPDQG\RX¦OOJHWWKHVDPHHUURUscalacUDLVHV

:H¦OOGLVFXVVW\SHHUDVXUHLQPRUHGHWDLOLQ&KDSWHU
$OVRE\FRQYHQWLRQZHXVHWKHWHUPILHOGIRUDYDULDEOHWKDWLVWLHGWRDQLQVWDQFH7KH
WHUPDWWULEXWHLVRIWHQXVHGLQRWKHUODQJXDJHV OLNH5XE\ 1RWHWKDWWKHVWDWHRIDQ
LQVWDQFHLVWKHXQLRQRIDOOWKHYDOXHVFXUUHQWO\UHSUHVHQWHGE\WKHLQVWDQFH¦VILHOGV
$VZHGLVFXVVHGLQ£9DULDEOH'HFODUDWLRQV¤RQSDJHUHDGRQO\ £YDOXH¤ ILHOGVDUH
GHFODUHG XVLQJ WKH val NH\ZRUG DQG UHDGZULWH ILHOGV DUH GHFODUHG XVLQJ WKH var
NH\ZRUG
6FDODDOVRDOORZVW\SHVWREHGHFODUHGLQFODVVHVDVZHVDZLQ£$EVWUDFW7\SHV$QG
3DUDPHWHUL]HG7\SHV¤RQSDJH
:HXVHWKHWHUPPHPEHUWRUHIHUWRDILHOGPHWKRGRUW\SHLQDJHQHULFZD\1RWHWKDW
ILHOGDQGPHWKRGPHPEHUV EXWQRWW\SHPHPEHUV VKDUHWKHVDPHQDPHVSDFHXQOLNH
-DYD :H¦OO GLVFXVV WKLV PRUH LQ £:KHQ $FFHVVRU 0HWKRGV DQG )LHOGV $UH ,QGLVWLQ
JXLVKDEOH7KH8QLIRUP$FFHVV3ULQFLSOH¤RQSDJH
)LQDOO\QHZLQVWDQFHVRIUHIHUHQFHW\SHVDUHFUHDWHGIURPDFODVVXVLQJWKHnewNH\ZRUG
DVLQODQJXDJHVOLNH-DYDDQG&1RWHWKDW\RXFDQGURSWKHSDUHQWKHVHVZKHQXVLQJ
DGHIDXOWFRQVWUXFWRU LHRQHWKDWWDNHVQRDUJXPHQWV ,QVRPHFDVHVOLWHUDOYDOXHV

90 | Chapter 5:—Basic Object-Oriented Programming in Scala

Download at WoweBook.Com
FDQEHXVHGLQVWHDGHJval name = "Programming Scala"LVHTXLYDOHQWWRval name =
new String("Programming Scala")
,QVWDQFHVRIYDOXHW\SHV IntDoubleHWF ZKLFKFRUUHVSRQGWRWKHSULPLWLYHVLQODQ
JXDJHVOLNH-DYDDUHDOZD\VFUHDWHGXVLQJOLWHUDOYDOXHVHJ13.14,QIDFWWKHUHDUH
QRSXEOLFFRQVWUXFWRUVIRUWKHVHW\SHVVRDQH[SUHVVLRQOLNHval i = new Int(1)ZRQ¦W
FRPSLOH
:H¦OO GLVFXVV WKH GLIIHUHQFH EHWZHHQ UHIHUHQFH DQG YDOXH W\SHV LQ £7KH 6FDOD 7\SH
+LHUDUFK\¤RQSDJH

Parent Classes
6FDODVXSSRUWVVLQJOHLQKHULWDQFHQRWPXOWLSOHLQKHULWDQFH$FKLOG RUGHULYHG FODVV
FDQKDYHRQHDQGRQO\RQHSDUHQW RUEDVH FODVV7KHVROHH[FHSWLRQLVWKHURRWRIWKH
6FDODFODVVKLHUDUFK\AnyZKLFKKDVQRSDUHQW
:H¦YHVHHQVHYHUDOH[DPSOHVRISDUHQWDQGFKLOGFODVVHV+HUHDUHVQLSSHWVRIRQHRI
WKHILUVWZHVDZLQ£$EVWUDFW7\SHV$QG3DUDPHWHUL]HG7\SHV¤RQSDJH
// code-examples/TypeLessDoMore/abstract-types-script.scala

import java.io._

abstract class BulkReader {


// ...
}

class StringBulkReader(val source: String) extends BulkReader {


// ...
}

class FileBulkReader(val source: File) extends BulkReader {


// ...
}

$VLQ-DYDWKHNH\ZRUGextendsLQGLFDWHVWKHSDUHQWFODVVLQWKLVFDVHBulkReader,Q
6FDODextendsLVDOVRXVHGZKHQDFODVVLQKHULWVDWUDLWDVLWVSDUHQW HYHQZKHQLWPL[HV
LQRWKHUWUDLWVXVLQJWKHwithNH\ZRUG $OVRextendsLVXVHGZKHQRQHWUDLWLVWKHFKLOG
RIDQRWKHUWUDLWRUFODVV<HVWUDLWVFDQLQKHULWFODVVHV
,I\RXGRQ¦W extendDSDUHQWFODVVWKHGHIDXOWSDUHQWLV AnyRefDGLUHFWFKLOGFODVVRI
Any :HGLVFXVVWKHGLIIHUHQFHEHWZHHQAnyDQGAnyRefZKHQZHGLVFXVVWKH6FDODW\SH
KLHUDUFK\LQ£7KH6FDOD7\SH+LHUDUFK\¤RQSDJH

Constructors in Scala
6FDODGLVWLQJXLVKHVEHWZHHQDSULPDU\FRQVWUXFWRUDQG]HURRUPRUHDX[LOLDU\FRQVWUXF
WRUV,Q6FDODWKHSULPDU\FRQVWUXFWRULVWKHHQWLUHERG\RIWKHFODVV$Q\SDUDPHWHUV

Constructors in Scala | 91

Download at WoweBook.Com
WKDWWKHFRQVWUXFWRUUHTXLUHVDUHOLVWHGDIWHUWKHFODVVQDPH:H¦YHVHHQPDQ\H[DPSOHV
RIWKLVDOUHDG\DVLQWKHButtonWithCallbacksH[DPSOHZHXVHGLQ&KDSWHU
// code-examples/Traits/ui/button-callbacks.scala

package ui

class ButtonWithCallbacks(val label: String,


val clickedCallbacks: List[() => Unit]) extends Widget {

require(clickedCallbacks != null, "Callback list can't be null!")

def this(label: String, clickedCallback: () => Unit) =


this(label, List(clickedCallback))

def this(label: String) = {


this(label, Nil)
println("Warning: button has no click callbacks!")
}

def click() = {
// ... logic to give the appearance of clicking a physical button ...
clickedCallbacks.foreach(f => f())
}
}

7KHButtonWithCallbacksFODVVUHSUHVHQWVDEXWWRQRQDJUDSKLFDOXVHULQWHUIDFH,WKDV
DODEHODQGDOLVWRIFDOOEDFNIXQFWLRQVWKDWDUHLQYRNHGLIWKHEXWWRQLVFOLFNHG(DFK
FDOOEDFN IXQFWLRQ WDNHV QR DUJXPHQWV DQG UHWXUQV Unit 7KH click PHWKRG LWHUDWHV
WKURXJKWKHOLVWRIFDOOEDFNVDQGLQYRNHVHDFKRQH
ButtonWithCallbacksGHILQHVWKUHHFRQVWUXFWRUV7KHSULPDU\FRQVWUXFWRUZKLFKLVWKH
ERG\RIWKHHQWLUHFODVVKDVDSDUDPHWHUOLVWWKDWWDNHVDODEHOVWULQJDQGDOLVWRIFDOOEDFN
IXQFWLRQV%HFDXVHHDFKSDUDPHWHULVGHFODUHGDVDvalWKHFRPSLOHUJHQHUDWHVDSULYDWH
ILHOGFRUUHVSRQGLQJWRHDFKSDUDPHWHU DGLIIHUHQWLQWHUQDOQDPHLVXVHG DORQJZLWKD
SXEOLFUHDGHUPHWKRGWKDWKDVWKHVDPHQDPHDVWKHSDUDPHWHU£3ULYDWH¤DQG£SXEOLF¤
KDYHWKHVDPHPHDQLQJKHUHDVLQPRVWREMHFWRULHQWHGODQJXDJHV:H¦OOGLVFXVVWKH
YDULRXV YLVLELOLW\ UXOHV DQG WKH NH\ZRUGV WKDW FRQWURO WKHP LQ £9LVLELOLW\
5XOHV¤RQSDJH
,IDSDUDPHWHUKDVWKHvarNH\ZRUGDSXEOLFZULWHUPHWKRGLVDOVRJHQHUDWHGZLWKWKH
SDUDPHWHU¦VQDPHDVDSUHIL[IROORZHGE\_=)RUH[DPSOHLIlabelZHUHGHFODUHGDVD
varWKHZULWHUPHWKRGZRXOGEHQDPHGlabel_=DQGLWZRXOGWDNHDVLQJOHDUJXPHQW
RIW\SHString
7KHUHDUHWLPHVZKHQ\RXGRQ¦WZDQWWKHDFFHVVRUPHWKRGVWREHJHQHUDWHGDXWRPDW
LFDOO\,QRWKHUZRUGV\RXZDQWWKHILHOGWREHSULYDWH$GGWKHprivateNH\ZRUGEHIRUH
WKHvalRUvarNH\ZRUGDQGWKHDFFHVVRUPHWKRGVZRQ¦WEHJHQHUDWHG 6HH£9LVLELOLW\
5XOHV¤RQSDJHIRUPRUHGHWDLOV

92 | Chapter 5:—Basic Object-Oriented Programming in Scala

Download at WoweBook.Com
)RU\RX-DYDSURJUDPPHUV6FDODGRHVQ¦WIROORZWKH-DYD%HDQV>-DYD
%HDQV6SHF@FRQYHQWLRQWKDWILHOGUHDGHUDQGZULWHUPHWKRGVEHJLQZLWK
getDQGsetUHVSHFWLYHO\IROORZHGE\WKHILHOGQDPHZLWKWKHILUVWFKDU
DFWHUFDSLWDOL]HG:H¦OOVHHZK\ZKHQZHGLVFXVVWKH8QLIRUP$FFHVV
3ULQFLSOHLQ£:KHQ$FFHVVRU0HWKRGVDQG)LHOGV$UH,QGLVWLQJXLVKDEOH
7KH 8QLIRUP $FFHVV 3ULQFLSOH¤ RQ SDJH  +RZHYHU \RX FDQ JHW
-DYD%HDQVVW\OH JHWWHUV DQG VHWWHUV ZKHQ \RX QHHG WKHP XVLQJ WKH
scala.reflect.BeanPropertyDQQRWDWLRQDVZH¦OOGLVFXVVLQ£-DYD%HDQ
3URSHUWLHV¤RQSDJH

:KHQDQLQVWDQFHRIWKHFODVVLVFUHDWHGHDFKILHOGFRUUHVSRQGLQJWRDSDUDPHWHULQWKH
SDUDPHWHUOLVWZLOOEHLQLWLDOL]HGZLWKWKHSDUDPHWHUDXWRPDWLFDOO\1RFRQVWUXFWRUORJLF
LVUHTXLUHGWRLQLWLDOL]HWKHVHILHOGVLQFRQWUDVWWRPRVWRWKHUREMHFWRULHQWHGODQJXDJHV
7KHILUVWVWDWHPHQWLQWKHButtonWithCallbacksFODVV LHWKHFRQVWUXFWRU ERG\LVDWHVW
WRHQVXUHWKDWDQRQnullOLVWKDVEHHQSDVVHGWRWKHFRQVWUXFWRU ,WGRHVDOORZDQHPSW\
NilOLVWKRZHYHU ,WXVHVWKHFRQYHQLHQWrequireIXQFWLRQWKDWLVLPSRUWHGDXWRPDWL
FDOO\LQWRWKHFXUUHQWVFRSH DVZH¦OOGLVFXVVLQ£7KH3UHGHI2EMHFW¤RQSDJH ,I
WKHOLVWLVQXOOrequireZLOOWKURZDQH[FHSWLRQ7KHrequireIXQFWLRQDQGLWVFRPSDQLRQ
assumeDUHYHU\XVHIXOIRU 'HVLJQE\&RQWUDFWSURJUDPPLQJDVGLVFXVVHGLQ £%HWWHU
'HVLJQZLWK'HVLJQ%\&RQWUDFW¤RQSDJH
+HUH LV SDUW RI D IXOO VSHFLILFDWLRQ IRU ButtonWithCallbacks WKDW GHPRQVWUDWHV WKH
requireVWDWHPHQWLQXVH
// code-examples/Traits/ui/button-callbacks-spec.scala
package ui
import org.specs._

object ButtonWithCallbacksSpec extends Specification {


"A ButtonWithCallbacks" should {
// ...
"not be constructable with a null callback list" in {
val nullList:List[() => Unit] = null
val errorMessage =
"requirement failed: Callback list can't be null!"
(new ButtonWithCallbacks("button1", nullList)) must throwA(
new IllegalArgumentException(errorMessage))
}
}
}

6FDODHYHQPDNHVLWGLIILFXOWWRSDVVnullDVWKHVHFRQGSDUDPHWHUWRWKHFRQVWUXFWRULW
ZRQ¦WW\SHFKHFNZKHQ\RXFRPSLOHLW+RZHYHU\RXFDQDVVLJQ nullWRDYDOXHDV
VKRZQ ,I ZH GLGQ¦W KDYH WKH must throwA(...) FODXVH ZH ZRXOG VHH WKH IROORZLQJ
H[FHSWLRQWKURZQ
java.lang.IllegalArgumentException: requirement failed: Callback list can't be null!
at scala.Predef$.require(Predef.scala:112)
at ui.ButtonWithCallbacks.<init>(button-callbacks.scala:7)
...

Constructors in Scala | 93

Download at WoweBook.Com
ButtonWithCallbacksGHILQHVWZRDX[LOLDU\FRQVWUXFWRUVIRUWKHXVHU¦VFRQYHQLHQFH7KH
ILUVW DX[LOLDU\ FRQVWUXFWRU DFFHSWV D ODEHO DQG D VLQJOH FDOOEDFN ,W FDOOV WKH SULPDU\
FRQVWUXFWRUSDVVLQJWKHODEHODQGDQHZListWRZUDSWKHVLQJOHFDOOEDFN
7KHVHFRQGDX[LOLDU\FRQVWUXFWRUDFFHSWVMXVWDODEHO,WFDOOVWKHSULPDU\FRQVWUXFWRU
ZLWKNil ZKLFKUHSUHVHQWVDQHPSW\ListREMHFW 7KHFRQVWUXFWRUWKHQSULQWVDZDUQ
LQJPHVVDJHWKDWWKHUHDUHQRFDOOEDFNVVLQFHOLVWVDUHLPPXWDEOHDQGWKHUHLVQRZD\
WRUHSODFHWKHFDOOEDFNOLVWvalZLWKDQHZRQH
7RDYRLGLQILQLWHUHFXUVLRQ6FDODUHTXLUHVHDFKDX[LOLDU\FRQVWUXFWRUWRLQYRNHDQRWKHU
FRQVWUXFWRUGHILQHGEHIRUHLW VHH>6FDOD6SHF@ 7KHFRQVWUXFWRULQYRNHGPD\EH
HLWKHUDQRWKHUDX[LOLDU\FRQVWUXFWRURUWKHSULPDU\FRQVWUXFWRUDQGLWPXVWEHWKHILUVW
VWDWHPHQWLQWKHDX[LOLDU\FRQVWUXFWRU¦VERG\$GGLWLRQDOSURFHVVLQJFDQRFFXUDIWHU
WKLVFDOOVXFKDVWKHZDUQLQJPHVVDJHSULQWHGLQRXUH[DPSOH

%HFDXVHDOODX[LOLDU\FRQVWUXFWRUVHYHQWXDOO\LQYRNHWKHSULPDU\FRQ
VWUXFWRUORJLFFKHFNVDQGRWKHULQLWLDOL]DWLRQVGRQHLQWKHERG\ZLOOEH
SHUIRUPHGFRQVLVWHQWO\IRUDOOLQVWDQFHVFUHDWHG

7KHUHDUHDIHZDGYDQWDJHVRI6FDOD¦VFRQVWUDLQWVRQFRQVWUXFWRUV
(OLPLQDWLRQRIGXSOLFDWLRQ
%HFDXVHDX[LOLDU\FRQVWUXFWRUVLQYRNHWKHSULPDU\FRQVWUXFWRUSRWHQWLDOGXSOLFD
WLRQRIFRQVWUXFWLRQORJLFLVODUJHO\HOLPLQDWHG
&RGHVL]HUHGXFWLRQ
$VVKRZQLQWKHH[DPSOHVZKHQRQHRUPRUHRIWKHSULPDU\FRQVWUXFWRUSDUDP
HWHUVLVGHFODUHGDVDvalRUDvar6FDODDXWRPDWLFDOO\JHQHUDWHVDILHOGWKHDSSUR
SULDWHDFFHVVRUPHWKRGV XQOHVVWKH\DUHGHFODUHG private DQGWKHLQLWLDOL]DWLRQ
ORJLFIRUZKHQLQVWDQFHVDUHFUHDWHG
7KHUHLVDOVRDWOHDVWRQHGLVDGYDQWDJHRI6FDOD¦VFRQVWUDLQWVRQFRQVWUXFWRUV
/HVVIOH[LELOLW\
6RPHWLPHVLW¦VMXVWQRWFRQYHQLHQWWRKDYHRQHFRQVWUXFWRUERG\WKDWDOOFRQVWUXF
WRUVDUHIRUFHGWRXVH+RZHYHUZHILQGWKHVHFLUFXPVWDQFHVWREHUDUH,QVXFK
FDVHVLWPD\VLPSO\EHWKDWWKHFODVVKDVWRRPDQ\UHVSRQVLELOLWLHVDQGLWVKRXOG
EHUHIDFWRUHGLQWRVPDOOHUFODVVHV

Calling Parent Class Constructors


7KHSULPDU\FRQVWUXFWRULQDGHULYHGFODVVPXVWLQYRNHRQHRIWKHSDUHQWFODVVFRQ
VWUXFWRUVHLWKHUWKHSULPDU\FRQVWUXFWRURUDQDX[LOLDU\FRQVWUXFWRU,QWKHIROORZLQJ
H[DPSOHDFODVVGHULYHGIURPButtonWithCallbacksFDOOHGRadioButtonWithCallbacks
LQYRNHVWKHSULPDU\ ButtonWithCallbacksFRQVWUXFWRU£5DGLR¤EXWWRQVFDQEHHLWKHU
RQRURII

94 | Chapter 5:—Basic Object-Oriented Programming in Scala

Download at WoweBook.Com
// code-examples/BasicOOP/ui/radio-button-callbacks.scala

package ui

/**
* Button with two states, on or off, like an old-style,
* channel-selection button on a radio.
*/
class RadioButtonWithCallbacks(
var on: Boolean, label: String, clickedCallbacks: List[() => Unit])
extends ButtonWithCallbacks(label, clickedCallbacks) {

def this(on: Boolean, label: String, clickedCallback: () => Unit) =


this(on, label, List(clickedCallback))

def this(on: Boolean, label: String) = this(on, label, Nil)


}

7KHSULPDU\FRQVWUXFWRUIRU RadioButtonWithCallbacksWDNHVWKUHHSDUDPHWHUVDQ on
VWDWH trueRUfalse DODEHODQGDOLVWRIFDOOEDFNV,WSDVVHVWKHODEHODQGOLVWRIFDOOEDFNV
WRLWVSDUHQWFODVVButtonWithCallbacks7KHonSDUDPHWHULVGHFODUHGDVDvarVRLWLV
PXWDEOHonLVDOVRWKHRQHFRQVWUXFWRUSDUDPHWHUXQLTXHWRDUDGLREXWWRQVRLWLVNHSW
DVDQDWWULEXWHRIRadioButtonWithCallbacks
)RUFRQVLVWHQF\ZLWKLWVSDUHQWFODVVRadioButtonWithCallbacksDOVRGHFODUHVWZRDX[
LOLDU\FRQVWUXFWRUV1RWHWKDWWKH\PXVWLQYRNHDSUHFHGLQJFRQVWUXFWRULQRadioButton
WithCallbacksDVEHIRUH7KH\FDQ¦WLQYRNHDButtonWithCallbacksFRQVWUXFWRUGLUHFWO\
'HFODULQJDOOWKHVHFRQVWUXFWRUVLQHDFKFODVVFRXOGJHWWHGLRXVDIWHUDZKLOHEXWZH
H[SORUHGWHFKQLTXHVLQ&KDSWHUWKDWFDQHOLPLQDWHUHSHWLWLRQ

:KLOHsuperLVXVHGWRLQYRNHRYHUULGGHQPHWKRGVDVLQ-DYDLWFDQQRW
EHXVHGWRLQYRNHDVXSHUFODVVFRQVWUXFWRU

Nested Classes
6FDODOHWV\RXQHVWFODVVGHFODUDWLRQVOLNHPDQ\REMHFWRULHQWHGODQJXDJHV6XSSRVHZH
ZDQWDOO WidgetsWRKDYHDPDSRISURSHUWLHV7KHVHSURSHUWLHVFRXOGEHVL]HFRORU
ZKHWKHU RU QRW WKH ZLGJHW LV YLVLEOH HWF :H PLJKW XVH D VLPSOH map WR KROG WKH
SURSHUWLHVEXWOHW¦VDVVXPHWKDWZHDOVRZDQWWRFRQWURODFFHVVWRWKHSURSHUWLHVDQG
WRSHUIRUPRWKHURSHUDWLRQVZKHQWKH\FKDQJH
+HUHLVRQHZD\ZHPLJKWH[SDQGRXURULJLQDO WidgetH[DPSOHIURP£7UDLWV$V0L[
LQV¤RQSDJHWRDGGWKLVIHDWXUH
// code-examples/BasicOOP/ui/widget.scala

package ui

Nested Classes | 95

Download at WoweBook.Com
abstract class Widget {
class Properties {
import scala.collection.immutable.HashMap

private var values: Map[String, Any] = new HashMap

def size = values.size

def get(key: String) = values.get(key)

def update(key: String, value: Any) = {


// Do some preprocessing, e.g., filtering.
values = values.update(key, value)
// Do some postprocessing.
}
}

val properties = new Properties


}

:HDGGHGD PropertiesFODVVWKDWKDVDSULYDWHPXWDEOHUHIHUHQFHWRDQLPPXWDEOH
HashMap:HDOVRDGGHGWKUHHSXEOLFPHWKRGVWKDWUHWULHYHWKHVL]H LHWKHQXPEHURI
SURSHUWLHVGHILQHG UHWULHYHDVLQJOHHOHPHQWLQWKHPDSDQGXSGDWHWKHPDSZLWKD
QHZHOHPHQWUHVSHFWLYHO\:HPLJKWQHHGWRGRDGGLWLRQDOZRUNLQWKHupdatePHWKRG
DQGZH¦YHLQGLFDWHGDVPXFKZLWKFRPPHQWV

<RXFDQVHHIURPWKHSUHYLRXVH[DPSOHWKDW6FDODDOORZVFODVVHVWREH
GHFODUHG LQVLGH RQH DQRWKHU RU £QHVWHG¤ $ QHVWHG FODVV PDNH VHQVH
ZKHQ\RXKDYHHQRXJKUHODWHGIXQFWLRQDOLW\WROXPSWRJHWKHULQDFODVV
EXWWKHIXQFWLRQDOLW\LVRQO\HYHUJRLQJWREHXVHGE\LWV£RXWHU¤FODVV

6RIDUZH¦YHFRYHUHGKRZWRGHFODUHFODVVHVKRZWRLQVWDQWLDWHWKHPDQGVRPHRIWKH
EDVLFVRILQKHULWDQFH,QWKHQH[WVHFWLRQZH¦OOGLVFXVVYLVLELOLW\UXOHVZLWKLQFODVVHVDQG
REMHFWV

Visibility Rules
)RUFRQYHQLHQFHZH¦OOXVHWKHZRUG£W\SH¤LQWKLVVHFWLRQWRUHIHUWR
FODVVHVDQGWUDLWVJHQHULFDOO\DVRSSRVHGWRUHIHUULQJWRPHPEHU type
GHFODUDWLRQV :H¦OO LQFOXGH WKRVH ZKHQ ZH XVH WKH WHUP £PHPEHU¤
JHQHULFDOO\XQOHVVRWKHUZLVHLQGLFDWHG

0RVWREMHFWRULHQWHGODQJXDJHVKDYHFRQVWUXFWVWRFRQVWUDLQWKHYLVLELOLW\ RUVFRSH RI


W\SHDQGW\SHPHPEHUGHFODUDWLRQV7KHVHFRQVWUXFWVVXSSRUWWKHREMHFWRULHQWHGIRUP
RIHQFDSVXODWLRQZKHUHRQO\WKHHVVHQWLDOSXEOLFDEVWUDFWLRQRIDFODVVRUWUDLWLVH[SRVHG
DQGLPSOHPHQWDWLRQLQIRUPDWLRQLVKLGGHQIURPYLHZ

96 | Chapter 5:—Basic Object-Oriented Programming in Scala

Download at WoweBook.Com
<RX¦OOZDQWWRXVHSXEOLFYLVLELOLW\IRUDQ\WKLQJWKDWXVHUVRI\RXUFODVVHVDQGREMHFWV
VKRXOGVHHDQGXVH.HHSLQPLQGWKDWWKHVHWRISXEOLFO\YLVLEOHPHPEHUVIRUPWKH
DEVWUDFWLRQH[SRVHGE\WKHW\SHDORQJZLWKWKHW\SH¦VQDPHLWVHOI
7KHFRQYHQWLRQDOZLVGRPLQREMHFWRULHQWHGGHVLJQLVWKDWILHOGVVKRXOGEHSULYDWHRU
SURWHFWHG,IDFFHVVLVUHTXLUHGLWVKRXOGKDSSHQWKURXJKPHWKRGVEXWQRWHYHU\WKLQJ
VKRXOGEHDFFHVVLEOHE\GHIDXOW7KHYLUWXHRIWKH8QLIRUP$FFHVV3ULQFLSOH VHH£:KHQ
$FFHVVRU 0HWKRGV DQG )LHOGV $UH ,QGLVWLQJXLVKDEOH 7KH 8QLIRUP $FFHVV 3ULQFL
SOH¤RQSDJH LVWKDWZHFDQJLYHWKHXVHUWKHVHPDQWLFVRISXEOLFILHOGDFFHVVYLD
HLWKHUDPHWKRGRUGLUHFWDFFHVVWRDILHOGZKLFKHYHULVDSSURSULDWHIRUWKHWDVN

7KHDUWRIJRRGREMHFWRULHQWHGGHVLJQLQFOXGHVGHILQLQJPLQLPDOFOHDU
DQGFRKHVLYHSXEOLFDEVWUDFWLRQV

7KHUH DUH WZR NLQGV RI £XVHUV¤ RI D W\SH GHULYHG W\SHV DQG FRGH WKDW ZRUNV ZLWK
LQVWDQFHVRIWKHW\SH'HULYHGW\SHVXVXDOO\QHHGPRUHDFFHVVWRWKHPHPEHUVRIWKHLU
SDUHQWW\SHVWKDQXVHUVRILQVWDQFHVGR
6FDOD¦VYLVLELOLW\UXOHVDUHVLPLODUWR-DYD¦VEXWWHQGWREHERWKPRUHFRQVLVWHQWO\DSSOLHG
DQGPRUHIOH[LEOH)RUH[DPSOHLQ-DYDLIDQLQQHUFODVVKDVD privatePHPEHUWKH
HQFORVLQJFODVVFDQVHHLW,Q6FDODWKHHQFORVLQJFODVVFDQ¦WVHHDprivatePHPEHUEXW
6FDODSURYLGHVDQRWKHUZD\WRGHFODUHLWYLVLEOHWRWKHHQFORVLQJFODVV
$V LQ -DYD DQG & WKH NH\ZRUGV WKDW PRGLI\ YLVLELOLW\ VXFK DV private DQG
protectedDSSHDUDWWKHEHJLQQLQJRIGHFODUDWLRQV<RX¦OOILQGWKHPEHIRUHWKH class
RU traitNH\ZRUGVIRUW\SHVEHIRUHWKH valRU varIRUILHOGVDQGEHIRUHWKH defIRU
PHWKRGV

<RXFDQDOVRXVHDQDFFHVVPRGLILHUNH\ZRUGRQWKHSULPDU\FRQVWUXFWRU
RIDFODVV3XWLWDIWHUWKHW\SHQDPHDQGW\SHSDUDPHWHUVLIDQ\DQG
EHIRUH WKH DUJXPHQW OLVW DV LQ WKLV H[DPSOH class Restricted[+A]
private (name: String) {...}

7DEOHVXPPDUL]HVWKHYLVLELOLW\VFRSHV
7DEOH9LVLELOLW\VFRSHV
Name Keyword Description
public none Public members and types are visible everywhere, across all boundaries.
protected protected Protected members are visible to the defining type, to derived types, and to
nested types. Protected types are visible only within the same package and
subpackages.

Visibility Rules | 97

Download at WoweBook.Com
Name Keyword Description
private private Private members are visible only within the defining type and nested types.
Private types are visible only within the same package.
scoped protected protected[scope] Visibility is limited to scope, which can be a package, type, or this (meaning
the same instance, when applied to members, or the enclosing package, when
applied to types). See the text below for details.
scoped private private[scope] Synonymous with scoped protected visibility, except under inheritance (dis-
cussed below).

/HW¦VH[SORUHWKHVHYLVLELOLW\RSWLRQVLQPRUHGHWDLO7RNHHSWKLQJVVLPSOHZH¦OOXVH
ILHOGVIRUPHPEHUH[DPSOHV0HWKRGDQGW\SHGHFODUDWLRQVEHKDYHWKHVDPHZD\

8QIRUWXQDWHO\\RXFDQ¦WDSSO\DQ\RIWKHYLVLELOLW\PRGLILHUVWRSDFN
DJHV7KHUHIRUHDSDFNDJHLVDOZD\VSXEOLFHYHQZKHQLWFRQWDLQVQR
SXEOLFO\YLVLEOHW\SHV

Public Visibility
$Q\GHFODUDWLRQZLWKRXWDYLVLELOLW\NH\ZRUGLV£SXEOLF¤PHDQLQJLWLVYLVLEOHHYHU\
ZKHUH7KHUHLVQRpublicNH\ZRUGLQ6FDOD7KLVLVLQFRQWUDVWWR-DYDZKLFKGHIDXOWV
WRSXEOLFYLVLELOLW\RQO\ZLWKLQWKHHQFORVLQJSDFNDJH LH£SDFNDJHSULYDWH¤ 2WKHU
REMHFWRULHQWHGODQJXDJHVOLNH5XE\DOVRGHIDXOWWRSXEOLFYLVLELOLW\
// code-examples/BasicOOP/scoping/public.scala

package scopeA {
class PublicClass1 {
val publicField = 1

class Nested {
val nestedField = 1
}

val nested = new Nested


}

class PublicClass2 extends PublicClass1 {


val field2 = publicField + 1
val nField2 = new Nested().nestedField
}
}

package scopeB {
class PublicClass1B extends scopeA.PublicClass1

class UsingClass(val publicClass: scopeA.PublicClass1) {


def method = "UsingClass:" +
" field: " + publicClass.publicField +

98 | Chapter 5:—Basic Object-Oriented Programming in Scala

Download at WoweBook.Com
" nested field: " + publicClass.nested.nestedField
}
}

<RXFDQFRPSLOHWKLVILOHZLWKscalac,WVKRXOGFRPSLOHZLWKRXWHUURU
(YHU\WKLQJLVSXEOLFLQWKHVHSDFNDJHVDQGFODVVHV1RWHWKDW scopeB.UsingClassFDQ
DFFHVVscopeA.PublicClass1DQGLWVPHPEHUVLQFOXGLQJWKHLQVWDQFHRINestedDQGLWV
SXEOLFILHOG

Protected Visibility
3URWHFWHGYLVLELOLW\LVIRUWKHEHQHILWRILPSOHPHQWHUVRIGHULYHGW\SHVZKRQHHGDOLWWOH
PRUH DFFHVV WR WKH GHWDLOV RI WKHLU SDUHQW W\SHV $Q\ PHPEHU GHFODUHG ZLWK WKH
protectedNH\ZRUGLVYLVLEOHRQO\WRWKHGHILQLQJW\SHLQFOXGLQJRWKHULQVWDQFHVRIWKH
VDPHW\SHDQGDQ\GHULYHGW\SHV:KHQDSSOLHGWRDW\SHprotectedOLPLWVYLVLELOLW\WR
WKHHQFORVLQJSDFNDJH
-DYDLQFRQWUDVWPDNHVSURWHFWHGPHPEHUVYLVLEOHWKURXJKRXWWKHHQFORVLQJSDFNDJH
6FDODKDQGOHVWKLVFDVHZLWKVFRSHGSULYDWHDQGSURWHFWHGDFFHVV
// code-examples/BasicOOP/scoping/protected-wont-compile.scala
// WON'T COMPILE

package scopeA {
class ProtectedClass1(protected val protectedField1: Int) {
protected val protectedField2 = 1

def equalFields(other: ProtectedClass1) =


(protectedField1 == other.protectedField1) &&
(protectedField1 == other.protectedField1) &&
(nested == other.nested)

class Nested {
protected val nestedField = 1
}

protected val nested = new Nested


}

class ProtectedClass2 extends ProtectedClass1(1) {


val field1 = protectedField1
val field2 = protectedField2
val nField = new Nested().nestedField // ERROR
}

class ProtectedClass3 {
val protectedClass1 = new ProtectedClass1(1)
val protectedField1 = protectedClass1.protectedField1 // ERROR
val protectedField2 = protectedClass1.protectedField2 // ERROR
val protectedNField = protectedClass1.nested.nestedField // ERROR
}

Visibility Rules | 99

Download at WoweBook.Com
protected class ProtectedClass4

class ProtectedClass5 extends ProtectedClass4


protected class ProtectedClass6 extends ProtectedClass4
}

package scopeB {
class ProtectedClass4B extends scopeA.ProtectedClass4 // ERROR
}

:KHQ\RXFRPSLOHWKLVILOHZLWKscalac\RXJHWWKHIROORZLQJRXWSXW 7KHILOHQDPHV
EHIRUHWKHN:OLQHQXPEHUVKDYHEHHQUHPRYHGIURPWKHRXWSXWWREHWWHUILWWKHVSDFH
16: error: value nestedField cannot be accessed in ProtectedClass2.this.Nested
val nField = new Nested().nestedField
^
20: error: value protectedField1 cannot be accessed in scopeA.ProtectedClass1
val protectedField1 = protectedClass1.protectedField1
^
21: error: value protectedField2 cannot be accessed in scopeA.ProtectedClass1
val protectedField2 = protectedClass1.protectedField2
^
22: error: value nested cannot be accessed in scopeA.ProtectedClass1
val protectedNField = protectedClass1.nested.nestedField
^
32: error: class ProtectedClass4 cannot be accessed in package scopeA
class ProtectedClass4B extends scopeA.ProtectedClass4
^
5 errors found

7KH// ERRORFRPPHQWVLQWKHOLVWLQJPDUNWKHOLQHVWKDWIDLOWRSDUVH
ProtectedClass2 FDQ DFFHVV SURWHFWHG PHPEHUV RI ProtectedClass1 VLQFH LW GHULYHV
IURP LW +RZHYHU LW FDQ¦W DFFHVV WKH SURWHFWHG nestedField LQ protectedClass1.nes
ted $OVR ProtectedClass3 FDQ¦W DFFHVV SURWHFWHG PHPEHUV RI WKH ProtectedClass1
LQVWDQFHLWXVHV
)LQDOO\EHFDXVH ProtectedClass4LVGHFODUHG protectedLWLVQRWYLVLEOHLQWKH scopeB
SDFNDJH

Private Visibility
3ULYDWHYLVLELOLW\FRPSOHWHO\KLGHVLPSOHPHQWDWLRQGHWDLOVHYHQIURPWKHLPSOHPHQWHUV
RIGHULYHGFODVVHV$Q\PHPEHUGHFODUHGZLWKWKH privateNH\ZRUGLVYLVLEOHRQO\WR
WKHGHILQLQJW\SHLQFOXGLQJRWKHULQVWDQFHVRIWKHVDPHW\SH:KHQDSSOLHGWRDW\SH
privateOLPLWVYLVLELOLW\WRWKHHQFORVLQJSDFNDJH
// code-examples/BasicOOP/scoping/private-wont-compile.scala
// WON'T COMPILE

package scopeA {
class PrivateClass1(private val privateField1: Int) {
private val privateField2 = 1

100 | Chapter 5:—Basic Object-Oriented Programming in Scala

Download at WoweBook.Com
def equalFields(other: PrivateClass1) =
(privateField1 == other.privateField1) &&
(privateField2 == other.privateField2) &&
(nested == other.nested)

class Nested {
private val nestedField = 1
}

private val nested = new Nested


}

class PrivateClass2 extends PrivateClass1(1) {


val field1 = privateField1 // ERROR
val field2 = privateField2 // ERROR
val nField = new Nested().nestedField // ERROR
}

class PrivateClass3 {
val privateClass1 = new PrivateClass1(1)
val privateField1 = privateClass1.privateField1 // ERROR
val privateField2 = privateClass1.privateField2 // ERROR
val privateNField = privateClass1.nested.nestedField // ERROR
}

private class PrivateClass4

class PrivateClass5 extends PrivateClass4 // ERROR


protected class PrivateClass6 extends PrivateClass4 // ERROR
private class PrivateClass7 extends PrivateClass4
}

package scopeB {
class PrivateClass4B extends scopeA.PrivateClass4 // ERROR
}

&RPSLOLQJWKLVILOH\LHOGVWKHIROORZLQJRXWSXW
14: error: not found: value privateField1
val field1 = privateField1
^
15: error: not found: value privateField2
val field2 = privateField2
^
16: error: value nestedField cannot be accessed in PrivateClass2.this.Nested
val nField = new Nested().nestedField
^
20: error: value privateField1 cannot be accessed in scopeA.PrivateClass1
val privateField1 = privateClass1.privateField1
^
21: error: value privateField2 cannot be accessed in scopeA.PrivateClass1
val privateField2 = privateClass1.privateField2
^
22: error: value nested cannot be accessed in scopeA.PrivateClass1
val privateNField = privateClass1.nested.nestedField
^

Visibility Rules | 101

Download at WoweBook.Com
27: error: private class PrivateClass4 escapes its defining scope as part
of type scopeA.PrivateClass4
class PrivateClass5 extends PrivateClass4
^
28: error: private class PrivateClass4 escapes its defining scope as part
of type scopeA.PrivateClass4
protected class PrivateClass6 extends PrivateClass4
^
33: error: class PrivateClass4 cannot be accessed in package scopeA
class PrivateClass4B extends scopeA.PrivateClass4
^
9 errors found

1RZ PrivateClass2FDQ¦WDFFHVVSULYDWHPHPEHUVRILWVSDUHQWFODVV PrivateClass1


7KH\DUHFRPSOHWHO\LQYLVLEOHWRWKHVXEFODVVDVLQGLFDWHGE\WKHHUURUPHVVDJHV1RU
FDQLWDFFHVVDSULYDWHILHOGLQDNestedFODVV
-XVWDVIRUWKHFDVHRIprotectedDFFHVVPrivateClass3FDQ¦WDFFHVVSULYDWHPHPEHUVRI
WKHPrivateClass1LQVWDQFHLWLVXVLQJ1RWHKRZHYHUWKDWWKHequalFieldsPHWKRGFDQ
DFFHVVSULYDWHPHPEHUVRIWKHotherLQVWDQFH
7KH GHFODUDWLRQV RI PrivateClass5 DQG PrivateClass6 IDLO EHFDXVH LI DOORZHG WKH\
ZRXOGHQDEOHPrivateClass4WR£HVFDSHLWVGHILQLQJVFRSH¤+RZHYHUWKHGHFODUDWLRQ
RIPrivateClass7VXFFHHGVEHFDXVHLWLVDOVRGHFODUHGWREHSULYDWH&XULRXVO\RXUSUH
YLRXVH[DPSOHZDVDEOHWRGHFODUHDSXEOLFFODVVWKDWVXEFODVVHGDSURWHFWHGFODVVZLWK
RXWDVLPLODUHUURU
)LQDOO\MXVWDVIRU protectedW\SHGHFODUDWLRQVWKH privateW\SHVFDQ¦WEHVXEFODVVHG
RXWVLGHWKHVDPHSDFNDJH

Scoped Private and Protected Visibility


6FDOD DOORZV \RX WR ILQHWXQH WKH VFRSH RI YLVLELOLW\ ZLWK WKH VFRSHG private DQG
protectedYLVLELOLW\GHFODUDWLRQV1RWHWKDWXVLQJprivateRUprotectedLQDVFRSHGGHF
ODUDWLRQLVLQWHUFKDQJHDEOHDVWKH\EHKDYHLGHQWLFDOO\H[FHSWXQGHULQKHULWDQFHZKHQ
DSSOLHGWRPHPEHUV

:KLOHHLWKHUFKRLFHEHKDYHVWKHVDPHLQPRVWVFHQDULRVLWLVPRUHFRP
PRQWRVHH private[X]UDWKHUWKDQ protected[X]XVHGLQFRGH,QWKH
FRUHOLEUDULHVLQFOXGHGZLWK6FDODWKHUDWLRLVURXJKO\ILYHWRRQH

/HW¦VEHJLQE\FRQVLGHULQJWKHRQO\GLIIHUHQFHVLQEHKDYLRUEHWZHHQVFRSHGSULYDWHDQG
VFRSHG SURWHFWHG¢KRZ WKH\ EHKDYH XQGHU LQKHULWDQFH ZKHQ PHPEHUV KDYH WKHVH
VFRSHV
// code-examples/BasicOOP/scoping/scope-inheritance-wont-compile.scala
// WON'T COMPILE

package scopeA {

102 | Chapter 5:—Basic Object-Oriented Programming in Scala

Download at WoweBook.Com
class Class1 {
private[scopeA] val scopeA_privateField = 1
protected[scopeA] val scopeA_protectedField = 2
private[Class1] val class1_privateField = 3
protected[Class1] val class1_protectedField = 4
private[this] val this_privateField = 5
protected[this] val this_protectedField = 6
}

class Class2 extends Class1 {


val field1 = scopeA_privateField
val field2 = scopeA_protectedField
val field3 = class1_privateField // ERROR
val field4 = class1_protectedField
val field5 = this_privateField // ERROR
val field6 = this_protectedField
}
}

package scopeB {
class Class2B extends scopeA.Class1 {
val field1 = scopeA_privateField // ERROR
val field2 = scopeA_protectedField
val field3 = class1_privateField // ERROR
val field4 = class1_protectedField
val field5 = this_privateField // ERROR
val field6 = this_protectedField
}
}

&RPSLOLQJWKLVILOH\LHOGVWKHIROORZLQJRXWSXW
17: error: not found: value class1_privateField
val field3 = class1_privateField // ERROR
^
19: error: not found: value this_privateField
val field5 = this_privateField // ERROR
^
26: error: not found: value scopeA_privateField
val field1 = scopeA_privateField // ERROR
^
28: error: not found: value class1_privateField
val field3 = class1_privateField // ERROR
^
30: error: not found: value this_privateField
val field5 = this_privateField // ERROR
^
5 errors found

7KHILUVWWZRHUURUVLQVLGHClass2VKRZXVWKDWDGHULYHGFODVVLQVLGHWKHVDPHSDFNDJH
FDQ¦WUHIHUHQFHDPHPEHUWKDWLVVFRSHGSULYDWHWRWKHSDUHQWFODVVRU thisEXWLWFDQ
UHIHUHQFHDSULYDWHPHPEHUVFRSHGWRWKHSDFNDJH RUW\SH WKDWHQFORVHVERWKClass1
DQGClass2

Visibility Rules | 103

Download at WoweBook.Com
,QFRQWUDVWIRUDGHULYHGFODVVRXWVLGHWKHVDPHSDFNDJHLWKDVQRDFFHVVWRDQ\RIWKH
VFRSHGSULYDWHPHPEHUVRIClass1
+RZHYHUDOOWKHVFRSHGSURWHFWHGPHPEHUVDUHYLVLEOHLQERWKGHULYHGFODVVHV
:H¦OOXVHVFRSHGSULYDWHGHFODUDWLRQVIRUWKHUHVWRIRXUH[DPSOHVDQGGLVFXVVLRQVLQFH
XVHRIVFRSHGSULYDWHLVDOLWWOHPRUHFRPPRQLQWKH6FDODOLEUDU\WKDQVFRSHGSURWHFWHG
ZKHQWKHSUHYLRXVLQKHULWDQFHVFHQDULRVDUHQ¦WDIDFWRU
)LUVW OHW¦V VWDUW ZLWK WKH PRVW UHVWULFWLYH YLVLELOLW\ private[this] DV LW DIIHFWV W\SH
PHPEHUV
// code-examples/BasicOOP/scoping/private-this-wont-compile.scala
// WON'T COMPILE

package scopeA {
class PrivateClass1(private[this] val privateField1: Int) {
private[this] val privateField2 = 1

def equalFields(other: PrivateClass1) =


(privateField1 == other.privateField1) && // ERROR
(privateField2 == other.privateField2) &&
(nested == other.nested)

class Nested {
private[this] val nestedField = 1
}

private[this] val nested = new Nested


}

class PrivateClass2 extends PrivateClass1(1) {


val field1 = privateField1 // ERROR
val field2 = privateField2 // ERROR
val nField = new Nested().nestedField // ERROR
}

class PrivateClass3 {
val privateClass1 = new PrivateClass1(1)
val privateField1 = privateClass1.privateField1 // ERROR
val privateField2 = privateClass1.privateField2 // ERROR
val privateNField = privateClass1.nested.nestedField // ERROR
}
}

&RPSLOLQJWKLVILOH\LHOGVWKHIROORZLQJRXWSXW
5: error: value privateField1 is not a member of scopeA.PrivateClass1
(privateField1 == other.privateField1) &&
^
14: error: not found: value privateField1
val field1 = privateField1
^
15: error: not found: value privateField2
val field2 = privateField2
^

104 | Chapter 5:—Basic Object-Oriented Programming in Scala

Download at WoweBook.Com
16: error: value nestedField is not a member of PrivateClass2.this.Nested
val nField = new Nested().nestedField
^
20: error: value privateField1 is not a member of scopeA.PrivateClass1
val privateField1 = privateClass1.privateField1
^
21: error: value privateField2 is not a member of scopeA.PrivateClass1
val privateField2 = privateClass1.privateField2
^
22: error: value nested is not a member of scopeA.PrivateClass1
val privateNField = privateClass1.nested.nestedField
^
7 errors found

/LQHV¡DOVRZRQ¦WSDUVH6LQFHWKH\DUHSDUWRIWKHH[SUHVVLRQWKDW
VWDUWHGRQOLQHWKHFRPSLOHUVWRSSHGDIWHUWKHILUVWHUURU

7KHprivate[this]PHPEHUVDUHRQO\YLVLEOHWRWKHVDPHLQVWDQFH$QLQVWDQFHRIWKH
VDPHFODVVFDQ¦WVHH private[this]PHPEHUVRIDQRWKHULQVWDQFHVRWKH equalFields
PHWKRGZRQ¦WSDUVH
2WKHUZLVH WKH YLVLELOLW\ RI FODVV PHPEHUV LV WKH VDPH DV private ZLWKRXW D VFRSH
VSHFLILHU
:KHQGHFODULQJDW\SHZLWKprivate[this]XVHRIthisHIIHFWLYHO\ELQGVWRWKHHQFORVLQJ
SDFNDJHDVVKRZQKHUH
// code-examples/BasicOOP/scoping/private-this-pkg-wont-compile.scala
// WON'T COMPILE

package scopeA {
private[this] class PrivateClass1

package scopeA2 {
private[this] class PrivateClass2
}

class PrivateClass3 extends PrivateClass1 // ERROR


protected class PrivateClass4 extends PrivateClass1 // ERROR
private class PrivateClass5 extends PrivateClass1
private[this] class PrivateClass6 extends PrivateClass1

private[this] class PrivateClass7 extends scopeA2.PrivateClass2 // ERROR


}

package scopeB {
class PrivateClass1B extends scopeA.PrivateClass1 // ERROR
}

&RPSLOLQJWKLVILOH\LHOGVWKHIROORZLQJRXWSXW

Visibility Rules | 105

Download at WoweBook.Com
8: error: private class PrivateClass1 escapes its defining scope as part
of type scopeA.PrivateClass1
class PrivateClass3 extends PrivateClass1
^
9: error: private class PrivateClass1 escapes its defining scope as part
of type scopeA.PrivateClass1
protected class PrivateClass4 extends PrivateClass1
^
13: error: type PrivateClass2 is not a member of package scopeA.scopeA2
private[this] class PrivateClass7 extends scopeA2.PrivateClass2
^
17: error: type PrivateClass1 is not a member of package scopeA
class PrivateClass1B extends scopeA.PrivateClass1
^
four errors found

,QWKHVDPHSDFNDJHDWWHPSWLQJWRGHFODUHDpublicRUprotectedVXEFODVVIDLOV2QO\
privateDQG private[this]VXEFODVVHVDUHDOORZHG$OVR PrivateClass2LVVFRSHGWR
scopeA2VR\RXFDQ¦WGHFODUHLWRXWVLGHscopeA26LPLODUO\DQDWWHPSWWRGHFODUHDFODVV
LQXQUHODWHGscopeBXVLQJPrivateClass1DOVRIDLOV
+HQFHZKHQDSSOLHGWRW\SHV private[this]LVHTXLYDOHQWWR-DYD¦V package private
YLVLELOLW\
1H[WOHW¦VH[DPLQHW\SHOHYHOYLVLELOLW\private[T]ZKHUHTLVDW\SH
// code-examples/BasicOOP/scoping/private-type-wont-compile.scala
// WON'T COMPILE

package scopeA {
class PrivateClass1(private[PrivateClass1] val privateField1: Int) {
private[PrivateClass1] val privateField2 = 1

def equalFields(other: PrivateClass1) =


(privateField1 == other.privateField1) &&
(privateField2 == other.privateField2) &&
(nested == other.nested)

class Nested {
private[Nested] val nestedField = 1
}

private[PrivateClass1] val nested = new Nested


val nestedNested = nested.nestedField // ERROR
}

class PrivateClass2 extends PrivateClass1(1) {


val field1 = privateField1 // ERROR
val field2 = privateField2 // ERROR
val nField = new Nested().nestedField // ERROR
}

class PrivateClass3 {
val privateClass1 = new PrivateClass1(1)
val privateField1 = privateClass1.privateField1 // ERROR

106 | Chapter 5:—Basic Object-Oriented Programming in Scala

Download at WoweBook.Com
val privateField2 = privateClass1.privateField2 // ERROR
val privateNField = privateClass1.nested.nestedField // ERROR
}
}

&RPSLOLQJWKLVILOH\LHOGVWKHIROORZLQJRXWSXW
12: error: value nestedField cannot be accessed in PrivateClass1.this.Nested
val nestedNested = nested.nestedField
^
15: error: not found: value privateField1
val field1 = privateField1
^
16: error: not found: value privateField2
val field2 = privateField2
^
17: error: value nestedField cannot be accessed in PrivateClass2.this.Nested
val nField = new Nested().nestedField
^
21: error: value privateField1 cannot be accessed in scopeA.PrivateClass1
val privateField1 = privateClass1.privateField1
^
22: error: value privateField2 cannot be accessed in scopeA.PrivateClass1
val privateField2 = privateClass1.privateField2
^
23: error: value nested cannot be accessed in scopeA.PrivateClass1
val privateNField = privateClass1.nested.nestedField
^
7 errors found

$ private[PrivateClass1] PHPEHU LV YLVLEOH WR RWKHU LQVWDQFHV VR WKH equalFields
PHWKRG QRZ SDUVHV +HQFH private[T] LV QRW DV UHVWULFWLYH DV private[this] 1RWH
WKDW PrivateClass1 FDQ¦W VHH Nested.nestedField EHFDXVH WKDW ILHOG LV GHFODUHG
private[Nested]

:KHQPHPEHUVRITDUHGHFODUHGprivate[T]WKHEHKDYLRULVHTXLYDOHQW
WR private ,W LV QRW HTXLYDOHQW WR private[this] ZKLFK LV PRUH
UHVWULFWLYH

:KDWLIZHFKDQJHWKHVFRSHRINested.nestedFieldWREHprivate[PrivateClass1]"/HW¦V
VHHKRZprivate[T]DIIHFWVQHVWHGW\SHV
// code-examples/BasicOOP/scoping/private-type-nested-wont-compile.scala
// WON'T COMPILE

package scopeA {
class PrivateClass1 {
class Nested {
private[PrivateClass1] val nestedField = 1
}

private[PrivateClass1] val nested = new Nested


val nestedNested = nested.nestedField

Visibility Rules | 107

Download at WoweBook.Com
}

class PrivateClass2 extends PrivateClass1 {


val nField = new Nested().nestedField // ERROR
}

class PrivateClass3 {
val privateClass1 = new PrivateClass1
val privateNField = privateClass1.nested.nestedField // ERROR
}
}

&RPSLOLQJWKLVILOH\LHOGVWKHIROORZLQJRXWSXW
10: error: value nestedField cannot be accessed in PrivateClass2.this.Nested
def nField = new Nested().nestedField
^
14: error: value nested cannot be accessed in scopeA.PrivateClass1
val privateNField = privateClass1.nested.nestedField
^
two errors found

1RZnestedFieldLVYLVLEOHWRPrivateClass1EXWLWLVVWLOOLQYLVLEOHRXWVLGHRIPrivate
Class17KLVLVKRZprivateZRUNVLQ-DYD
/HW¦VH[DPLQHVFRSLQJXVLQJDSDFNDJHQDPH
// code-examples/BasicOOP/scoping/private-pkg-type-wont-compile.scala
// WON'T COMPILE

package scopeA {
private[scopeA] class PrivateClass1

package scopeA2 {
private [scopeA2] class PrivateClass2
private [scopeA] class PrivateClass3
}

class PrivateClass4 extends PrivateClass1


protected class PrivateClass5 extends PrivateClass1
private class PrivateClass6 extends PrivateClass1
private[this] class PrivateClass7 extends PrivateClass1

private[this] class PrivateClass8 extends scopeA2.PrivateClass2 // ERROR


private[this] class PrivateClass9 extends scopeA2.PrivateClass3
}

package scopeB {
class PrivateClass1B extends scopeA.PrivateClass1 // ERROR
}

&RPSLOLQJWKLVILOH\LHOGVWKHIROORZLQJRXWSXW
14: error: class PrivateClass2 cannot be accessed in package scopeA.scopeA2
private[this] class PrivateClass8 extends scopeA2.PrivateClass2
^
19: error: class PrivateClass1 cannot be accessed in package scopeA

108 | Chapter 5:—Basic Object-Oriented Programming in Scala

Download at WoweBook.Com
class PrivateClass1B extends scopeA.PrivateClass1
^
two errors found

1RWHWKDWPrivateClass2FDQ¦WEHVXEFODVVHGRXWVLGHRIscopeA2EXWPrivateClass3FDQ
EHVXEFODVVHGLQscopeAEHFDXVHLWLVGHFODUHGprivate[scopeA]
)LQDOO\OHW¦VORRNDWWKHHIIHFWRISDFNDJHOHYHOVFRSLQJRIW\SHPHPEHUV
// code-examples/BasicOOP/scoping/private-pkg-wont-compile.scala
// WON'T COMPILE

package scopeA {
class PrivateClass1 {
private[scopeA] val privateField = 1

class Nested {
private[scopeA] val nestedField = 1
}

private[scopeA] val nested = new Nested


}

class PrivateClass2 extends PrivateClass1 {


val field = privateField
val nField = new Nested().nestedField
}

class PrivateClass3 {
val privateClass1 = new PrivateClass1
val privateField = privateClass1.privateField
val privateNField = privateClass1.nested.nestedField
}

package scopeA2 {
class PrivateClass4 {
private[scopeA2] val field1 = 1
private[scopeA] val field2 = 2
}
}

class PrivateClass5 {
val privateClass4 = new scopeA2.PrivateClass4
val field1 = privateClass4.field1 // ERROR
val field2 = privateClass4.field2
}
}

package scopeB {
class PrivateClass1B extends scopeA.PrivateClass1 {
val field1 = privateField // ERROR
val privateClass1 = new scopeA.PrivateClass1
val field2 = privateClass1.privateField // ERROR
}
}

Visibility Rules | 109

Download at WoweBook.Com
&RPSLOLQJWKLVILOH\LHOGVWKHIROORZLQJRXWSXW
28: error: value field1 cannot be accessed in scopeA.scopeA2.PrivateClass4
val field1 = privateClass4.field1
^
35: error: not found: value privateField
val field1 = privateField
^
37: error: value privateField cannot be accessed in scopeA.PrivateClass1
val field2 = privateClass1.privateField
^
three errors found

7KHRQO\HUURUVDUHZKHQZHDWWHPSWWRDFFHVVPHPEHUVVFRSHGWR scopeAIURPWKH
XQUHODWHG SDFNDJH scopeB DQG ZKHQ ZH DWWHPSW WR DFFHVV D PHPEHU IURP D QHVWHG
SDFNDJHscopeA2WKDWLVVFRSHGWRWKDWSDFNDJH

:KHQDW\SHRUPHPEHULVGHFODUHGprivate[P]ZKHUHPLVWKHHQFORVLQJ
SDFNDJHWKHQLWLVHTXLYDOHQWWR-DYD¦Vpackage privateYLVLELOLW\

Final Thoughts on Visibility


6FDODYLVLELOLW\GHFODUDWLRQVDUHYHU\IOH[LEOHDQGWKH\EHKDYHFRQVLVWHQWO\7KH\SURYLGH
ILQHJUDLQHG FRQWURO RYHU YLVLELOLW\ DW DOO SRVVLEOH VFRSHV IURP WKH LQVWDQFH OHYHO
private[this] XSWRSDFNDJHOHYHOYLVLELOLW\ private[P]IRUDSDFNDJHP )RUH[DP
SOH WKH\ PDNH LW HDVLHU WR FUHDWH £FRPSRQHQWV¤ ZLWK W\SHV H[SRVHG RXWVLGH RI WKH
FRPSRQHQW¦VWRSOHYHOSDFNDJHZKLOHKLGLQJLPSOHPHQWDWLRQW\SHVDQGW\SHPHPEHUV
ZLWKLQWKH£FRPSRQHQW¦V¤SDFNDJHV
)LQDOO\ZHKDYHREVHUYHGDSRWHQWLDO£JRWFKD¤ZLWKKLGGHQPHPEHUVRIWUDLWV

%HFDUHIXOZKHQFKRRVLQJWKHQDPHVRIPHPEHUVRIWUDLWV,IWZRWUDLWV
KDYHDPHPEHURIWKHVDPHQDPHDQGWKHWUDLWVDUHXVHGLQWKHVDPH
LQVWDQFHDQDPHFROOLVLRQZLOORFFXUHYHQLIERWKPHPEHUVDUHSULYDWH

)RUWXQDWHO\WKHFRPSLOHUFDWFKHVWKLVSUREOHP

Recap and What’s Next


:HLQWURGXFHGWKHEDVLFVRI6FDOD¦VREMHFWPRGHOLQFOXGLQJFRQVWUXFWRUVLQKHULWDQFH
QHVWLQJRIFODVVHVDQGUXOHVIRUYLVLELOLW\
,QWKHQH[WFKDSWHUZH¦OOH[SORUH6FDOD¦VPRUHDGYDQFHG223IHDWXUHVLQFOXGLQJRYHU
ULGLQJFRPSDQLRQREMHFWVFDVHFODVVHVDQGUXOHVIRUHTXDOLW\EHWZHHQREMHFWV

110 | Chapter 5:—Basic Object-Oriented Programming in Scala

Download at WoweBook.Com
CHAPTER 6
Advanced Object-Oriented
Programming In Scala

:H¦YHJRWWKHEDVLFVRI223LQ6FDODXQGHURXUEHOWEXWWKHUH¦VSOHQW\PRUHWROHDUQ

Overriding Members of Classes and Traits


&ODVVHV DQG WUDLWV FDQ GHFODUH DEVWUDFW PHPEHUV ILHOGV PHWKRGV DQG W\SHV 7KHVH
PHPEHUVPXVWEHGHILQHGE\DGHULYHGFODVVRUWUDLWEHIRUHDQLQVWDQFHFDQEHFUHDWHG
0RVWREMHFWRULHQWHGODQJXDJHVVXSSRUWDEVWUDFWPHWKRGVDQGVRPHDOVRVXSSRUWDE
VWUDFWILHOGVDQGW\SHV

:KHQRYHUULGLQJDFRQFUHWHPHPEHU6FDODUHTXLUHVWKH overrideNH\
ZRUG,WLVRSWLRQDOZKHQDVXEW\SHGHILQHV £RYHUULGHV¤ DQDEVWUDFW
PHPEHU&RQYHUVHO\GRQ¦WXVH overrideXQOHVV\RXDUHDFWXDOO\RYHU
ULGLQJDPHPEHU

5HTXLULQJWKHoverrideNH\ZRUGKDVVHYHUDOEHQHILWV
‡ ,WFDWFKHVPLVVSHOOHGPHPEHUVWKDWZHUHLQWHQGHGWREHRYHUULGHV7KHFRPSLOHU
ZLOOWKURZDQHUURUWKDWWKHPHPEHUGRHVQ¦WRYHUULGHDQ\WKLQJ
‡ ,WFDWFKHVDSRWHQWLDOO\VXEWOHEXJWKDWFDQRFFXULIDQHZPHPEHULVDGGHGWRD
EDVHFODVVZKHUHWKHPHPEHU¦VQDPHFROOLGHVZLWKDQROGHUGHULYHGFODVVPHPEHU
WKDWLVXQNQRZQWRWKHEDVHFODVVGHYHORSHU7KDWLVWKHGHULYHGFODVVPHPEHUZDV
QHYHULQWHQGHGWRRYHUULGHDEDVHFODVVPHPEHU%HFDXVHWKHGHULYHGFODVVPHPEHU
ZRQ¦WKDYHWKHoverrideNH\ZRUGWKHFRPSLOHUZLOOWKURZDQHUURUZKHQWKHQHZ
EDVHFODVVPHPEHULVLQWURGXFHG
‡ +DYLQJ WR DGG WKH NH\ZRUG UHPLQGV \RX WR FRQVLGHU ZKDW PHPEHUV VKRXOG RU
VKRXOGQRWEHRYHUULGGHQ

111

Download at WoweBook.Com
-DYDKDVDQRSWLRQDO@OverrideDQQRWDWLRQIRUPHWKRGV,WKHOSVFDWFKHUURUVRIWKHILUVW
W\SH PLVVSHOOLQJV EXWLWFDQ¦WKHOSZLWKHUURUVRIWKHVHFRQGW\SHVLQFHXVLQJWKH
DQQRWDWLRQLVRSWLRQDO

Attempting to Override final Declarations


+RZHYHULIDGHFODUDWLRQLQFOXGHVWKHfinalNH\ZRUGWKHQRYHUULGLQJWKHGHFODUDWLRQ
LVSURKLELWHG,QWKHIROORZLQJH[DPSOHWKHfixedMethodLVGHFODUHGfinalLQWKHSDUHQW
FODVV$WWHPSWLQJWRFRPSLOHWKHH[DPSOHZLOOUHVXOWLQDFRPSLODWLRQHUURU
// code-examples/AdvOOP/overrides/final-member-wont-compile.scala
// WON'T COMPILE.

class NotFixed {
final def fixedMethod = "fixed"
}

class Changeable2 extends NotFixed {


override def fixedMethod = "not fixed" // ERROR
}

7KLVFRQVWUDLQWDSSOLHVWRFODVVHVDQGWUDLWVDVZHOODVPHPEHUV,QWKLVH[DPSOHWKH
FODVVFixedLVGHFODUHGfinalVRDQDWWHPSWWRGHULYHDQHZW\SHIURPLWZLOODOVRIDLOWR
FRPSLOH
// code-examples/AdvOOP/overrides/final-class-wont-compile.scala
// WON'T COMPILE.

final class Fixed {


def doSomething = "Fixed did something!"
}

class Changeable1 extends Fixed // ERROR

6RPHRIWKHW\SHVLQWKH6FDODOLEUDU\DUHILQDOLQFOXGLQJ-'.FODVVHV
OLNHStringDQGDOOWKH£YDOXH¤W\SHVGHULYHGIURPAnyVal VHH£7KH6FDOD
7\SH+LHUDUFK\¤RQSDJH 

)RUGHFODUDWLRQVWKDWDUHQ¦WILQDOOHW¦VH[DPLQHWKHUXOHVDQGEHKDYLRUVIRURYHUULGLQJ
VWDUWLQJZLWKPHWKRGV

Overriding Abstract and Concrete Methods


/HW¦VH[WHQGRXUIDPLOLDU WidgetEDVHFODVVZLWKDQDEVWUDFWPHWKRG drawWRVXSSRUW
£UHQGHULQJ¤ WKH ZLGJHW WR D GLVSOD\ ZHE SDJH HWF :H¦OO DOVR RYHUULGH D FRQFUHWH
PHWKRGIDPLOLDUWRDQ\-DYDSURJUDPPHUtoString()XVLQJDQDGKRFIRUPDW$VEH
IRUHZHZLOOXVHDQHZSDFNDJHui3

112 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
'UDZLQJLVDFWXDOO\DFURVVFXWWLQJFRQFHUQ7KHVWDWHRIDWidgetLVRQH
WKLQJKRZLWLVUHQGHUHGRQGLIIHUHQWSODWIRUPVWKLFNFOLHQWVZHESDJHV
PRELOHGHYLFHVHWFLVDVHSDUDWHLVVXH6RGUDZLQJLVDYHU\JRRGFDQ
GLGDWH IRU D WUDLW HVSHFLDOO\ LI \RX ZDQW \RXU *8, DEVWUDFWLRQV WR EH
SRUWDEOH+RZHYHUWRNHHSWKLQJVVLPSOHZHZLOOKDQGOHGUDZLQJLQWKH
WidgetKLHUDUFK\LWVHOI

+HUHLVWKHUHYLVHGWidgetFODVVZLWKdrawDQGtoStringPHWKRGV
// code-examples/AdvOOP/ui3/widget.scala

package ui3

abstract class Widget {


def draw(): Unit
override def toString() = "(widget)"
}

7KHdrawPHWKRGLVDEVWUDFWEHFDXVHLWKDVQRERG\WKDWLVWKHPHWKRGLVQ¦WIROORZHG
E\ DQ HTXDOV VLJQ =  QRU DQ\ WH[W DIWHU LW 7KHUHIRUH Widget KDV WR EH GHFODUHG
abstract LWZDVRSWLRQDOEHIRUH (DFKFRQFUHWHVXEFODVVRIWidgetZLOOKDYHWRLPSOH
PHQWdrawRUUHO\RQDSDUHQWFODVVWKDWLPSOHPHQWVLW:HGRQ¦WQHHGWRUHWXUQDQ\WKLQJ
IURPdrawVRLWVUHWXUQYDOXHLVUnit
7KH toString() PHWKRG LV VWUDLJKWIRUZDUG 6LQFH AnyRef GHILQHV toString WKH
overrideNH\ZRUGLVUHTXLUHGIRUWidget.toString
+HUHLVWKHUHYLVHGButtonFODVVZLWKdrawDQGtoStringPHWKRGV
// code-examples/AdvOOP/ui3/button.scala

package ui3

class Button(val label: String) extends Widget with Clickable {

def click() = {
// Logic to give the appearance of clicking a button...
}

def draw() = {
// Logic to draw the button on the display, web page, etc.
}

override def toString() =


"(button: label=" + label + ", " + super.toString() + ")"
}

Button LPSOHPHQWV WKH DEVWUDFW PHWKRG draw 1R override NH\ZRUG LV UHTXLUHG
Button DOVR RYHUULGHV toString VR WKH override NH\ZRUG LV UHTXLUHG 1RWH WKDW
super.toStringLVFDOOHG

Overriding Members of Classes and Traits | 113

Download at WoweBook.Com
7KHsuperNH\ZRUGLVDQDORJRXVWRthisEXWLWELQGVWRWKHSDUHQWW\SHZKLFKLVWKH
DJJUHJDWLRQ RI WKH SDUHQW FODVV DQG DQ\ PL[HGLQ WUDLWV 7KH VHDUFK IRU
super.toString ZLOO ILQG WKH £FORVHVW¤ SDUHQW W\SH toString DV GHWHUPLQHG E\ WKH
OLQHDUL]DWLRQSURFHVV VHH£/LQHDUL]DWLRQRIDQ2EMHFW¦V+LHUDUFK\¤RQSDJH ,Q
WKLVFDVHVLQFHClickableGRHVQ¦WGHILQHtoStringWidget.toStringZLOOEHFDOOHG

2YHUULGLQJDFRQFUHWHPHWKRGVKRXOGEHGRQHUDUHO\EHFDXVHLWLVHUURU
SURQH6KRXOG\RXLQYRNHWKHSDUHQWPHWKRG",IVRZKHQ"'R\RXFDOO
LWEHIRUHGRLQJDQ\WKLQJHOVHRUDIWHUZDUG":KLOHWKHZULWHURIWKHSD
UHQWPHWKRGPLJKWGRFXPHQWWKHRYHUULGLQJFRQVWUDLQWVIRUWKHPHWKRG
LW¦VGLIILFXOWWRHQVXUHWKDWWKHZULWHURIDGHULYHGFODVVZLOOKRQRUWKRVH
FRQVWUDLQWV$PXFKPRUHUREXVWDSSURDFKLVWKH7HPSODWH0HWKRG3DW
WHUQ VHH>*2)@ 

Overriding Abstract and Concrete Fields


0RVWREMHFWRULHQWHGODQJXDJHVDOORZ\RXWRRYHUULGHPXWDEOHILHOGV var )HZHU22
ODQJXDJHV DOORZ \RX WR GHILQH DEVWUDFW ILHOGV RU RYHUULGH FRQFUHWH LPPXWDEOH ILHOGV
val )RUH[DPSOHLW¦VFRPPRQIRUDEDVHFODVVFRQVWUXFWRUWRLQLWLDOL]HDPXWDEOHILHOG
DQGIRUDGHULYHGFODVVFRQVWUXFWRUWRFKDQJHLWVYDOXH
:H¦OOGLVFXVVRYHUULGLQJILHOGVLQWUDLWVDQGFODVVHVVHSDUDWHO\DVWUDLWVKDYHVRPHSDU
WLFXODULVVXHV

Overriding Abstract and Concrete Fields in Traits


5HFDOORXUVetoableClicksWUDLWLQ£6WDFNDEOH7UDLWV¤RQSDJH,WGHILQHVDvalQDPHG
maxAllowedDQGLQLWLDOL]HVLWWR 1:HZRXOGOLNHWKHDELOLW\WRRYHUULGHWKHYDOXHLQD
FODVVWKDWPL[HVLQWKLVWUDLW
8QIRUWXQDWHO\LQ6FDODYHUVLRQ;LWLVQRWSRVVLEOHWRRYHUULGHD valGHILQHGLQD
WUDLW+RZHYHULWLVSRVVLEOHWRRYHUULGHDvalGHILQHGLQDSDUHQWFODVV9HUVLRQRI
6FDODGRHVVXSSRUWRYHUULGLQJDvalLQDWUDLW

%HFDXVHWKHRYHUULGHEHKDYLRUIRUDvalLQDWUDLWLVFKDQJLQJ\RXVKRXOG
DYRLGUHO\LQJRQWKHDELOLW\WRRYHUULGHLWLI\RXDUHFXUUHQWO\XVLQJ6FDOD
YHUVLRQ;8VHDQRWKHUDSSURDFKLQVWHDG

8QIRUWXQDWHO\WKHYHUVLRQFRPSLOHUDFFHSWVFRGHWKDWDWWHPSWVWRRYHUULGHDWUDLW
GHILQHGvalEXWWKHRYHUULGHGRHVQRWDFWXDOO\KDSSHQDVLOOXVWUDWHGE\WKLVH[DPSOH
// code-examples/AdvOOP/overrides/trait-val-script.scala
// DANGER! Silent failure to override a trait's "name" (V2.7.5 only).
// Works as expected in V2.8.0.

114 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
trait T1 {
val name = "T1"
}

class Base

class ClassWithT1 extends Base with T1 {


override val name = "ClassWithT1"
}

val c = new ClassWithT1()


println(c.name)

class ClassExtendsT1 extends T1 {


override val name = "ClassExtendsT1"
}

val c2 = new ClassExtendsT1()


println(c2.name)

,I\RXUXQWKLVVFULSWZLWKscalaYHUVLRQWKHRXWSXWLVWKHIROORZLQJ
T1
T1

5HDGLQJWKHVFULSWZHZRXOGKDYHH[SHFWHGWKHWZRT1VWULQJVWREHClassWithT1DQG
ClassExtendsT1UHVSHFWLYHO\
+RZHYHULI\RXUXQWKLVVFULSWZLWKscalaYHUVLRQ\RXJHWWKLVRXWSXW
ClassWithT1
ClassExtendsT1

$WWHPSWVWRRYHUULGHDWUDLWGHILQHGvalZLOOEHDFFHSWHGE\WKHFRPSLOHU
EXWKDYHQRHIIHFWLQ6FDODYHUVLRQ;

7KHUHDUHWKUHHZRUNDURXQGV\RXFDQXVHZLWK6FDODYHUVLRQ7KHILUVWLVWRXVHVRPH
DGYDQFHGRSWLRQVIRU scalaDQG scalac7KH -XfutureRSWLRQZLOOHQDEOHWKHRYHUULGH
EHKDYLRUVXSSRUWHGLQYHUVLRQ7KH-XcheckinitRSWLRQZLOODQDO\]H\RXUFRGHDQG
UHSRUWZKHWKHUWKHEHKDYLRUFKDQJHZLOOEUHDNLW7KHRSWLRQ -XexperimentalZKLFK
HQDEOHV PDQ\ H[SHULPHQWDO FKDQJHV ZLOO DOVR ZDUQ \RX WKDW WKH val RYHUULGH
EHKDYLRULVGLIIHUHQW
7KHVHFRQGZRUNDURXQGLVWRPDNHWKHvalDEVWUDFWLQWKHWUDLW7KLVIRUFHVDQLQVWDQFH
XVLQJWKHWUDLWWRDVVLJQDYDOXH'HFODULQJDvalLQDWUDLWDEVWUDFWLVDSHUIHFWO\XVHIXO
GHVLJQDSSURDFKIRUERWKYHUVLRQVRI6FDOD,QIDFWWKLVZLOOEHWKHEHVWGHVLJQFKRLFH
ZKHQWKHUHLVQRDSSURSULDWHGHIDXOWYDOXHWRDVVLJQWRWKHvalLQWKHWUDLW
// code-examples/AdvOOP/overrides/trait-abs-val-script.scala

trait AbstractT1 {
val name: String

Overriding Members of Classes and Traits | 115

Download at WoweBook.Com
}

class Base

class ClassWithAbstractT1 extends Base with AbstractT1 {


val name = "ClassWithAbstractT1"
}

val c = new ClassWithAbstractT1()


println(c.name)

class ClassExtendsAbstractT1 extends AbstractT1 {


val name = "ClassExtendsAbstractT1"
}

val c2 = new ClassExtendsAbstractT1()


println(c2.name)

7KLVVFULSWSURGXFHVWKHRXWSXWWKDWZHZRXOGH[SHFW
ClassWithAbstractT1
ClassExtendsAbstractT1

6RDQDEVWUDFWvalZRUNVILQHXQOHVVWKHILHOGLVXVHGLQWKHWUDLWERG\LQDZD\WKDWZLOO
IDLOXQWLOWKHILHOGLVSURSHUO\LQLWLDOL]HG8QIRUWXQDWHO\WKHSURSHULQLWLDOL]DWLRQZRQ¦W
RFFXUXQWLODIWHUWKHWUDLW¦VERG\KDVH[HFXWHG&RQVLGHUWKHIROORZLQJH[DPSOH
// code-examples/AdvOOP/overrides/trait-invalid-init-val-script.scala
// ERROR: "value" read before initialized.

trait AbstractT2 {
println("In AbstractT2:")
val value: Int
val inverse = 1.0/value // ???
println("AbstractT2: value = "+value+", inverse = "+inverse)
}

val c2b = new AbstractT2 {


println("In c2b:")
val value = 10
}
println("c2b.value = "+c2b.value+", inverse = "+c2b.inverse)

:KLOH LW DSSHDUV WKDW ZH DUH FUHDWLQJ DQ LQVWDQFH RI WKH WUDLW ZLWK new
AbstractT2 ...ZHDUHDFWXDOO\XVLQJDQDQRQ\PRXVFODVVWKDWLPSOLFLWO\H[WHQGVWKH
WUDLW7KLVVFULSWVKRZVZKDWKDSSHQVZKHQinverseLVFDOFXODWHG
In AbstractT2:
AbstractT2: value = 0, inverse = Infinity
In c2b:
c2b.value = 10, inverse = Infinity

$V\RXPLJKWH[SHFWWKH inverseLVFDOFXODWHGWRRHDUO\1RWHWKDWDGLYLGHE\]HUR
H[FHSWLRQLVQ¦WWKURZQWKHFRPSLOHUUHFRJQL]HVWKHYDOXHLVLQILQLWHEXWLWKDVQ¦WDF
WXDOO\£WULHG¤WKHGLYLVLRQ\HW

116 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
7KHEHKDYLRURIWKLVVFULSWLVDFWXDOO\TXLWHVXEWOH$VDQH[HUFLVHWU\VHOHFWLYHO\UH
PRYLQJ RUFRPPHQWLQJRXW WKHGLIIHUHQWprintlnVWDWHPHQWVRQHDWDWLPH2EVHUYH
ZKDWKDSSHQVWRWKHUHVXOWV6RPHWLPHVinverseLVLQLWLDOL]HGSURSHUO\ +LQWUHPRYH
WKHprintln("In c2b:")VWDWHPHQW7KHQWU\SXWWLQJLWEDFNEXWDIWHUWKHval value =
10OLQH
:KDWWKLVH[SHULPHQWUHDOO\VKRZVLVWKDWVLGHHIIHFWV LHIURPWKHprintlnVWDWHPHQWV
FDQEHXQH[SHFWHGDQGVXEWOHHVSHFLDOO\GXULQJLQLWLDOL]DWLRQ,W¦VEHVWWRDYRLGWKHP
6FDODSURYLGHVWZRVROXWLRQVWRWKLVSUREOHPOD]\YDOXHVZKLFKZHGLVFXVVLQ£/D]\
9DOV¤RQSDJHDQGSUHLQLWLDOL]HGILHOGVZKLFKLVGHPRQVWUDWHGLQWKHIROORZLQJ
UHILQHPHQWWRWKHSUHYLRXVH[DPSOH
// code-examples/AdvOOP/overrides/trait-pre-init-val-script.scala

trait AbstractT2 {
println("In AbstractT2:")
val value: Int
val inverse = 1.0/value
println("AbstractT2: value = "+value+", inverse = "+inverse)
}

val c2c = new {


// Only initializations are allowed in pre-init. blocks.
// println("In c2c:")
val value = 10
} with AbstractT2

println("c2c.value = "+c2c.value+", inverse = "+c2c.inverse)

:HLQVWDQWLDWHDQDQRQ\PRXVLQQHUFODVVLQLWLDOL]LQJWKHvalueILHOGLQWKHEORFNEHIRUH
WKHwith AbstractT2FODXVH7KLVJXDUDQWHHVWKDWvalueLVLQLWLDOL]HGEHIRUHWKHERG\RI
AbstractT2LVH[HFXWHGDVVKRZQZKHQ\RXUXQWKHVFULSW
In AbstractT2:
AbstractT2: value = 10, inverse = 0.1
c2c.value = 10, inverse = 0.1

$OVRLI\RXVHOHFWLYHO\UHPRYHDQ\RIWKHprintlnVWDWHPHQWV\RXJHWWKHVDPHH[SHFWHG
DQGQRZSUHGLFWDEOHUHVXOWV
1RZOHW¦VFRQVLGHUWKHVHFRQGZRUNDURXQGZHGHVFULEHGHDUOLHUFKDQJLQJWKHGHFOD
UDWLRQWRvar7KLVVROXWLRQLVPRUHVXLWDEOHLIDJRRGGHIDXOWYDOXHH[LVWVDQG\RXGRQ¦W
ZDQWWRUHTXLUHLQVWDQFHVWKDWXVHWKHWUDLWWRDOZD\VVHWWKHYDOXH,QWKLVFDVHFKDQJH
WKH valWRD varHLWKHUDSXEOLF varRUDSULYDWH varKLGGHQEHKLQGUHDGHUDQGZULWHU
PHWKRGV(LWKHUZD\ZHFDQVLPSO\UHDVVLJQWKHYDOXHLQDGHULYHGWUDLWRUFODVV
5HWXUQLQJWRRXU VetoableClicksH[DPSOHKHUHLVWKHPRGLILHG VetoableClicksWUDLW
WKDWXVHVDSXEOLFvarIRUmaxAllowed

Overriding Members of Classes and Traits | 117

Download at WoweBook.Com
// code-examples/AdvOOP/ui3/vetoable-clicks.scala

package ui3
import observer._

trait VetoableClicks extends Clickable {


var maxAllowed = 1 // default
private var count = 0
abstract override def click() = {
count += 1
if (count <= maxAllowed)
super.click()
}
}

+HUHLVDQHZspecsREMHFWButtonClickableObserverVetoableSpec2WKDWGHPRQVWUDWHV
FKDQJLQJWKHYDOXHRImaxAllowed
// code-examples/AdvOOP/ui3/button-clickable-observer-vetoable2-spec.scala
package ui3

import org.specs._
import observer._
import ui.ButtonCountObserver

object ButtonClickableObserverVetoableSpec2 extends Specification {


"A Button Observer with Vetoable Clicks" should {
"observe only the first 'maxAllowed' clicks" in {
val observableButton =
new Button("Okay") with ObservableClicks with VetoableClicks {
maxAllowed = 2
}
observableButton.maxAllowed mustEqual 2
val buttonClickCountObserver = new ButtonCountObserver
observableButton.addObserver(buttonClickCountObserver)
for (i <- 1 to 3) observableButton.click()
buttonClickCountObserver.count mustEqual 2
}
}
}

1Roverride varLVUHTXLUHG:HMXVWDVVLJQDQHZYDOXH6LQFHWKHERG\RIWKHWUDLWLV
H[HFXWHG EHIRUH WKH ERG\ RI WKH FODVV XVLQJ LW UHDVVLJQLQJ WKH ILHOG YDOXH KDSSHQV
DIWHUWKHLQLWLDODVVLJQPHQWLQWKHWUDLW¦VERG\+RZHYHUDVZHVDZEHIRUHWKDWUHDV
VLJQPHQWFRXOGKDSSHQWRRODWHLIWKHILHOGLVXVHGLQWKHWUDLW¦VERG\LQVRPHFDOFXODWLRQ
WKDWZLOOEHFRPHLQYDOLGE\DUHDVVLJQPHQWODWHU<RXFDQDYRLGWKLVSUREOHPLI\RX
PDNHWKHILHOGSULYDWHDQGGHILQHDSXEOLFZULWHUPHWKRGWKDWUHGRHVDQ\GHSHQGHQW
FDOFXODWLRQV
$QRWKHUGLVDGYDQWDJHRIXVLQJDvarGHFODUDWLRQLVWKDWmaxAllowedZDVQRWLQWHQGHGWR
EHZULWDEOH$VZHZLOOVHHLQ&KDSWHUUHDGRQO\YDOXHVKDYHLPSRUWDQWEHQHILWV:H
ZRXOG SUHIHU IRU maxAllowed WR EH UHDGRQO\ DW OHDVW DIWHU WKH FRQVWUXFWLRQ SURFHVV
FRPSOHWHV

118 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
:HFDQVHHWKDWWKHVLPSOHDFWRIFKDQJLQJWKHvalWRDvarFDXVHVSRWHQWLDOSUREOHPV
IRUWKHPDLQWDLQHURIVetoableClicks&RQWURORYHUWKDWILHOGLVQRZORVW7KHPDLQWDLQHU
PXVWFDUHIXOO\FRQVLGHUZKHWKHURUQRWWKHYDOXHZLOOFKDQJHDQGLIDFKDQJHZLOOLQYD
OLGDWH WKH VWDWH RI WKH LQVWDQFH 7KLV LVVXH LV HVSHFLDOO\ SHUQLFLRXV LQ PXOWLWKUHDGHG
V\VWHPV VHH£7KH3UREOHPVRI6KDUHG6\QFKURQL]HG6WDWH¤RQSDJH 

$YRLG varILHOGVZKHQSRVVLEOH LQFODVVHVDVZHOODVWUDLWV &RQVLGHU


SXEOLFvarILHOGVHVSHFLDOO\ULVN\

Overriding Abstract and Concrete Fields in Classes


,QFRQWUDVWWRWUDLWVRYHUULGLQJD valGHFODUHGLQDFODVVZRUNVDVH[SHFWHG+HUHLVDQ
H[DPSOHZLWKERWKDvalRYHUULGHDQGDvarUHDVVLJQPHQWLQDGHULYHGFODVV
// code-examples/AdvOOP/overrides/class-field-script.scala

class C1 {
val name = "C1"
var count = 0
}

class ClassWithC1 extends C1 {


override val name = "ClassWithC1"
count = 1
}

val c = new ClassWithC1()


println(c.name)
println(c.count)

7KH overrideNH\ZRUGLVUHTXLUHGIRUWKHFRQFUHWH valILHOG nameEXWQRWIRUWKH var


ILHOGcount7KLVLVEHFDXVHZHDUHFKDQJLQJWKHLQLWLDOL]DWLRQRIDFRQVWDQW val ZKLFK
LVD£VSHFLDO¤RSHUDWLRQ
,I\RXUXQWKLVVFULSWWKHRXWSXWLVWKHIROORZLQJ
ClassWithC1
1

%RWKILHOGVDUHRYHUULGGHQLQWKHGHULYHGFODVVDVH[SHFWHG+HUHLVWKHVDPHH[DPSOH
PRGLILHGVRWKDWERWKWKHvalDQGWKHvarDUHDEVWUDFWLQWKHEDVHFODVV
// code-examples/AdvOOP/overrides/class-abs-field-script.scala

abstract class AbstractC1 {


val name: String
var count: Int
}

class ClassWithAbstractC1 extends AbstractC1 {


val name = "ClassWithAbstractC1"

Overriding Members of Classes and Traits | 119

Download at WoweBook.Com
var count = 1
}

val c = new ClassWithAbstractC1()


println(c.name)
println(c.count)

7KHoverrideNH\ZRUGLVQRWUHTXLUHGIRUnameLQClassWithAbstractC1VLQFHWKHRULJ
LQDOGHFODUDWLRQLVDEVWUDFW7KHRXWSXWRIWKLVVFULSWLVWKHIROORZLQJ
ClassWithAbstractC1
1

,W¦VLPSRUWDQWWRHPSKDVL]HWKDWnameDQGcountDUHDEVWUDFWILHOGVQRWFRQFUHWHILHOGV
ZLWK GHIDXOW YDOXHV $ VLPLODUORRNLQJ GHFODUDWLRQ RI name LQ D -DYD FODVV
String name;ZRXOGGHFODUHDFRQFUHWHILHOGZLWKWKHGHIDXOWYDOXH nullLQWKLVFDVH 
-DYDGRHVQ¦WVXSSRUWDEVWUDFWILHOGVRUW\SHV DVZH¦OOGLVFXVVQH[W RQO\PHWKRGV

Overriding Abstract Types


:H LQWURGXFHG DEVWUDFW W\SH GHFODUDWLRQV LQ £$EVWUDFW 7\SHV $QG 3DUDPHWHUL]HG
7\SHV¤RQSDJH5HFDOOWKHBulkReaderH[DPSOHIURPWKDWVHFWLRQ
// code-examples/TypeLessDoMore/abstract-types-script.scala

import java.io._

abstract class BulkReader {


type In
val source: In
def read: String
}

class StringBulkReader(val source: String) extends BulkReader {


type In = String
def read = source
}

class FileBulkReader(val source: File) extends BulkReader {


type In = File
def read = {
val in = new BufferedInputStream(new FileInputStream(source))
val numBytes = in.available()
val bytes = new Array[Byte](numBytes)
in.read(bytes, 0, numBytes)
new String(bytes)
}
}

println( new StringBulkReader("Hello Scala!").read )


println( new FileBulkReader(new File("abstract-types-script.scala")).read )

120 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
$EVWUDFWW\SHVDUHDQDOWHUQDWLYHWRSDUDPHWHUL]HGW\SHVZKLFKZH¦OOH[SORUHLQ£8Q
GHUVWDQGLQJ3DUDPHWHUL]HG7\SHV¤RQSDJH/LNHSDUDPHWHUL]HGW\SHVWKH\SUR
YLGHDQDEVWUDFWLRQPHFKDQLVPDWWKHW\SHOHYHO
7KHH[DPSOHVKRZVKRZWRGHFODUHDQDEVWUDFWW\SHDQGKRZWRGHILQHDFRQFUHWHYDOXH
LQ GHULYHG FODVVHV BulkReader GHFODUHV type In ZLWKRXW LQLWLDOL]LQJ LW 7KH FRQFUHWH
GHULYHGFODVVStringBulkReaderSURYLGHVDFRQFUHWHYDOXHXVLQJtype In = String
8QOLNH ILHOGV DQG PHWKRGV LW LV QRW SRVVLEOH WR RYHUULGH D FRQFUHWH type GHILQLWLRQ
+RZHYHUWKHDEVWUDFWGHFODUDWLRQFDQFRQVWUDLQWKHDOORZHGFRQFUHWHW\SHYDOXHV:H¦OO
OHDUQKRZLQ&KDSWHU
)LQDOO\\RXSUREDEO\QRWLFHGWKDWWKLVH[DPSOHDOVRGHPRQVWUDWHVGHILQLQJDQDEVWUDFW
ILHOGXVLQJDFRQVWUXFWRUSDUDPHWHUDQGDQDEVWUDFWPHWKRG
)RU DQRWKHU H[DPSOH OHW¦V UHYLVLW RXU Subject WUDLW IURP £7UDLWV $V 0L[
LQV¤RQSDJH7KHGHILQLWLRQRIWKHObserverW\SHLVDVWUXFWXUDOW\SHZLWKDPHWKRG
QDPHG receiveUpdate2EVHUYHUVPXVWKDYHWKLV£VWUXFWXUH¤/HW¦VJHQHUDOL]HWKHLP
SOHPHQWDWLRQQRZXVLQJDQDEVWUDFWW\SH
// code-examples/AdvOOP/observer/observer2.scala

package observer

trait AbstractSubject {
type Observer

private var observers = List[Observer]()


def addObserver(observer:Observer) = observers ::= observer
def notifyObservers = observers foreach (notify(_))

def notify(observer: Observer): Unit


}

trait SubjectForReceiveUpdateObservers extends AbstractSubject {


type Observer = { def receiveUpdate(subject: Any) }

def notify(observer: Observer): Unit = observer.receiveUpdate(this)


}

trait SubjectForFunctionalObservers extends AbstractSubject {


type Observer = (AbstractSubject) => Unit

def notify(observer: Observer): Unit = observer(this)


}

1RZAbstractSubjectGHFODUHVtype ObserverDVDEVWUDFW LPSOLFLWO\EHFDXVHWKHUHLV


QRGHILQLWLRQ 6LQFHWKHRULJLQDOVWUXFWXUDOW\SHLVJRQHZHGRQ¦WNQRZH[DFWO\KRZWR
QRWLI\DQREVHUYHU6RZHDOVRDGGHGDQDEVWUDFWPHWKRGnotifyZKLFKDFRQFUHWHFODVV
RUWUDLWZLOOGHILQHDVDSSURSULDWH

Overriding Members of Classes and Traits | 121

Download at WoweBook.Com
7KH SubjectForReceiveUpdateObserversGHULYHGWUDLWGHILQHV ObserverZLWKWKHVDPH
VWUXFWXUDO W\SH ZH XVHG LQ WKH RULJLQDO H[DPSOH DQG notify VLPSO\ FDOOV
receiveUpdateDVEHIRUH
7KH SubjectForFunctionalObservers GHULYHG WUDLW GHILQHV Observer WR EH D IXQFWLRQ
WDNLQJDQLQVWDQFHRI AbstractSubjectDQGUHWXUQLQJ Unit$OO notifyKDVWRGRLVFDOO
WKHREVHUYHUIXQFWLRQSDVVLQJWKHVXEMHFWDVWKHVROHDUJXPHQW1RWHWKDWWKLVLPSOH
PHQWDWLRQLVVLPLODUWRWKHDSSURDFKZHXVHGLQRXURULJLQDOEXWWRQLPSOHPHQWDWLRQ
ButtonWithCallbacksZKHUHWKH£FDOOEDFNV¤ZHUHXVHUVXSSOLHGIXQFWLRQV 6HH£,QWUR
GXFLQJ 7UDLWV¤ RQ SDJH  DQG D UHYLVLWHG YHUVLRQ LQ £&RQVWUXFWRUV LQ 6FDOD¤
RQSDJH
+HUHLVDVSHFLILFDWLRQWKDWH[HUFLVHVWKHVHWZRYDULDWLRQVREVHUYLQJEXWWRQFOLFNVDV
EHIRUH
// code-examples/AdvOOP/observer/button-observer2-spec.scala

package ui
import org.specs._
import observer._

object ButtonObserver2Spec extends Specification {


"An Observer watching a SubjectForReceiveUpdateObservers button" should {
"observe button clicks" in {
val observableButton =
new Button(name) with SubjectForReceiveUpdateObservers {
override def click() = {
super.click()
notifyObservers
}
}
val buttonObserver = new ButtonCountObserver
observableButton.addObserver(buttonObserver)
for (i <- 1 to 3) observableButton.click()
buttonObserver.count mustEqual 3
}
}
"An Observer watching a SubjectForFunctionalObservers button" should {
"observe button clicks" in {
val observableButton =
new Button(name) with SubjectForFunctionalObservers {
override def click() = {
super.click()
notifyObservers
}
}
var count = 0
observableButton.addObserver((button) => count += 1)
for (i <- 1 to 3) observableButton.click()
count mustEqual 3
}
}
}

122 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
)LUVWZHH[HUFLVH SubjectForReceiveUpdateObserversZKLFKORRNVYHU\VLPLODUWRRXU
HDUOLHU H[DPSOHV 1H[W ZH H[HUFLVH SubjectForFunctionalObservers ,Q WKLV FDVH ZH
GRQ¦WQHHGDQRWKHU£REVHUYHU¤LQVWDQFHDWDOO:HMXVWPDLQWDLQD countYDULDEOHDQG
SDVVDIXQFWLRQOLWHUDOWRaddObserverWRLQFUHPHQWWKHFRXQW DQGLJQRUHWKHEXWWRQ 
7KHPDLQYLUWXHRI SubjectForFunctionalObserversLVLWVPLQLPDOLVP,WUHTXLUHVQR
VSHFLDO LQVWDQFHV QR WUDLWV GHILQLQJ DEVWUDFWLRQV HWF )RU PDQ\ FDVHV LW LV DQ LGHDO
DSSURDFK
AbstractSubject LV PRUH UHXVDEOH WKDQ WKH RULJLQDO GHILQLWLRQ RI Subject EHFDXVH LW
LPSRVHVIHZHUFRQVWUDLQWVRQSRWHQWLDOREVHUYHUV

AbstractSubjectLOOXVWUDWHVWKDWDQDEVWUDFWLRQZLWKIHZHUFRQFUHWHGH
WDLOVLVXVXDOO\PRUHUHXVDEOH

%XWZDLWWKHUH¦VPRUH:H¦OOUHYLVLWWKHXVHRIDEVWUDFWW\SHVDQGWKH2EVHUYHU3DWWHUQ
LQ£6FDODEOH$EVWUDFWLRQV¤RQSDJH

When Accessor Methods and Fields Are Indistinguishable: The Uniform


Access Principle
6XSSRVHDXVHURI ButtonCountObserverIURP£7UDLWV$V0L[LQV¤RQSDJHDFFHVVHV
WKHcountPHPEHU
// code-examples/Traits/ui/button-count-observer-script.scala

val bco = new ui.ButtonCountObserver


val oldCount = bco.count
bco.count = 5
val newCount = bco.count
println(newCount + " == 5 and " + oldCount + " == 0?")

:KHQWKHcountILHOGLVUHDGRUZULWWHQDVLQWKLVH[DPSOHDUHPHWKRGVFDOOHGRULVWKH
ILHOGDFFHVVHGGLUHFWO\"$VRULJLQDOO\GHFODUHGLQ ButtonCountObserverWKHILHOGLVDF
FHVVHGGLUHFWO\+RZHYHUWKHXVHUGRHVQ¦WUHDOO\FDUH,QIDFWWKHIROORZLQJWZRGHIL
QLWLRQVDUHIXQFWLRQDOO\HTXLYDOHQWIURPWKHSHUVSHFWLYHRIWKHXVHU
class ButtonCountObserver {
var count = 0 // public field access (original definition)
// ...
}
class ButtonCountObserver {
private var cnt = 0 // private field
def count = cnt // reader method
def count_=(newCount: Int) = cnt = newCount // writer method
// ...
}

Overriding Members of Classes and Traits | 123

Download at WoweBook.Com
7KLVHTXLYDOHQFHLVDQH[DPSOHRIWKH8QLIRUP$FFHVV3ULQFLSOH&OLHQWVUHDGDQGZULWH
ILHOGYDOXHVDVLIWKH\DUHSXEOLFO\DFFHVVLEOHHYHQWKRXJKLQVRPHFDVHVWKH\DUHDFWXDOO\
FDOOLQJPHWKRGV7KHPDLQWDLQHURIButtonCountObserverKDVWKHIUHHGRPWRFKDQJHWKH
LPSOHPHQWDWLRQZLWKRXWIRUFLQJXVHUVWRPDNHFRGHFKDQJHV
7KHUHDGHUPHWKRGLQWKHVHFRQGYHUVLRQGRHVQRWKDYHSDUHQWKHVHV5HFDOOWKDWFRQ
VLVWHQF\LQWKHXVHRISDUHQWKHVHVLVUHTXLUHGLIDPHWKRGGHILQLWLRQRPLWVSDUHQWKHVHV
7KLVLVRQO\SRVVLEOHLIWKHPHWKRGWDNHVQRDUJXPHQWV)RUWKH8QLIRUP$FFHVV3ULQ
FLSOHWRZRUNZHZDQWWRGHILQHILHOGUHDGHUPHWKRGVZLWKRXWSDUHQWKHVHV &RQWUDVW
WKDWZLWK5XE\ZKHUHPHWKRGSDUHQWKHVHVDUHDOZD\VRSWLRQDODVORQJDVWKHSDUVHLV
XQDPELJXRXV
7KHZULWHUPHWKRGKDVWKHIRUPDWcount_=(...)$VDELWRIV\QWDFWLFVXJDUWKHFRPSLOHU
DOORZVLQYRFDWLRQVRIPHWKRGVZLWKWKLVIRUPDWWREHZULWWHQLQHLWKHURIWKHIROORZLQJ
ZD\V
obj.field_=(newValue)
// or
obj.field = newValue

:HQDPHGWKHSULYDWHYDULDEOH cntLQWKHDOWHUQDWLYHGHILQLWLRQ6FDODNHHSVILHOGDQG
PHWKRGQDPHVLQWKHVDPHQDPHVSDFHZKLFKPHDQVZHFDQ¦WQDPHWKHILHOGcountLID
PHWKRGLVQDPHGcount0DQ\ODQJXDJHVOLNH-DYDGRQ¦WKDYHWKLVUHVWULFWLRQEHFDXVH
WKH\NHHSILHOGDQGPHWKRGQDPHVLQVHSDUDWHQDPHVSDFHV+RZHYHUWKHVHODQJXDJHV
FDQ¦W VXSSRUW WKH 8QLIRUP $FFHVV 3ULQFLSOH DV D UHVXOW XQOHVV WKH\ EXLOG LQ DG KRF
VXSSRUWLQWKHLUJUDPPDUVRUFRPSLOHUV
6LQFHPHPEHUobjectGHILQLWLRQVEHKDYHVLPLODUWRILHOGVIURPWKHFDOOHU¦VSHUVSHFWLYH
WKH\DUHDOVRLQWKHVDPHQDPHVSDFHDVPHWKRGVDQGILHOGV+HQFHWKHIROORZLQJFODVV
ZRXOGQRWFRPSLOH
// code-examples/AdvOOP/overrides/member-namespace-wont-compile.scala
// WON'T COMPILE

class IllegalMemberNameUse {
def member(i: Int) = 2 * i
val member = 2 // ERROR
object member { // ERROR
def apply() = 2
}
}

7KHUHLVRQHRWKHUEHQHILWRIWKLVQDPHVSDFH£XQLILFDWLRQ¤,IDSDUHQWFODVVGHFODUHVD
SDUDPHWHUOHVV PHWKRG WKHQ D VXEFODVV FDQ RYHUULGH WKDW PHWKRG ZLWK D val ,I WKH
SDUHQW¦VPHWKRGLVFRQFUHWHWKHQWKHoverrideNH\ZRUGLVUHTXLUHG
// code-examples/AdvOOP/overrides/method-field-class-script.scala

class Parent {
def name = "Parent"
}

124 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
class Child extends Parent {
override val name = "Child"
}

println(new Child().name) // => "Child"

,IWKHSDUHQW¦VPHWKRGLVDEVWUDFWWKHQWKHoverrideNH\ZRUGLVRSWLRQDO
// code-examples/AdvOOP/overrides/abs-method-field-class-script.scala

abstract class AbstractParent {


def name: String
}

class ConcreteChild extends AbstractParent {


val name = "Child"
}

println(new ConcreteChild().name) // => "Child"

7KLVDOVRZRUNVIRUWUDLWV,IWKHWUDLW¦VPHWKRGLVFRQFUHWHZHKDYHWKHIROORZLQJ
// code-examples/AdvOOP/overrides/method-field-trait-script.scala

trait NameTrait {
def name = "NameTrait"
}

class ConcreteNameClass extends NameTrait {


override val name = "ConcreteNameClass"
}

println(new ConcreteNameClass().name) // => "ConcreteNameClass"

,IWKHWUDLW¦VPHWKRGLVDEVWUDFWZHKDYHWKHIROORZLQJ
// code-examples/AdvOOP/overrides/abs-method-field-trait-script.scala

trait AbstractNameTrait {
def name: String
}

class ConcreteNameClass extends AbstractNameTrait {


val name = "ConcreteNameClass"
}

println(new ConcreteNameClass().name) // => "ConcreteNameClass"

:K\LVWKLVIHDWXUHXVHIXO",WDOORZVGHULYHGFODVVHVDQGWUDLWVWRXVHDVLPSOHILHOGDFFHVV
ZKHQWKDWLVVXIILFLHQWRUDPHWKRGFDOOZKHQPRUHSURFHVVLQJLVUHTXLUHGVXFKDVOD]\
LQLWLDOL]DWLRQ7KHVDPHDUJXPHQWKROGVIRUWKH8QLIRUP$FFHVV3ULQFLSOHLQJHQHUDO
2YHUULGLQJD defZLWKDvalLQDVXEFODVVFDQDOVREHKDQG\ZKHQLQWHURSHUDWLQJZLWK
-DYDFRGH7XUQDJHWWHULQWRD valE\SODFLQJLWLQWKHFRQVWUXFWRU<RX¦OOVHHWKLVLQ
DFWLRQLQWKHIROORZLQJH[DPSOHLQZKLFKRXU6FDODFODVV PersonLPSOHPHQWVDK\SR
WKHWLFDOPersonInterfaceIURPVRPHOHJDF\-DYDFRGH

Overriding Members of Classes and Traits | 125

Download at WoweBook.Com
class Person(val getName: String) extends PersonInterface

,I\RXRQO\KDYHDIHZDFFHVVRUVLQWKH-DYDFRGH\RX¦UHLQWHJUDWLQJZLWKWKLVWHFKQLTXH
PDNHVTXLFNZRUNRIWKHP
:KDWDERXWRYHUULGLQJDSDUDPHWHUOHVVPHWKRGZLWKDvarRURYHUULGLQJDvalRUvar
ZLWKDPHWKRG"7KHVHDUHQRWSHUPLWWHGEHFDXVHWKH\FDQ¦WPDWFKWKHEHKDYLRUVRIWKH
WKLQJVWKH\DUHRYHUULGLQJ
,I\RXDWWHPSWWRXVHD varWRRYHUULGHDSDUDPHWHUOHVVPHWKRG\RXJHWDQHUURUWKDW
WKHZULWHUPHWKRG override name_=LVQRWRYHUULGLQJDQ\WKLQJ7KLVZRXOGDOVREH
LQFRQVLVWHQWZLWKDSKLORVRSKLFDOJRDORIIXQFWLRQDOSURJUDPPLQJWKDWDPHWKRGWKDW
WDNHV QR SDUDPHWHUV VKRXOG DOZD\V UHWXUQ WKH VDPH UHVXOW 7R GR RWKHUZLVH ZRXOG
UHTXLUH VLGH HIIHFWV LQ WKH LPSOHPHQWDWLRQ ZKLFK IXQFWLRQDO SURJUDPPLQJ WULHV WR
DYRLGIRUUHDVRQVZHZLOOH[DPLQHLQ&KDSWHU%HFDXVHDvarLVFKDQJHDEOHWKHQR
SDUDPHWHU£PHWKRG¤GHILQHGLQWKHSDUHQWW\SHZRXOGQRORQJHUUHWXUQWKHVDPHUHVXOW
FRQVLVWHQWO\
,I\RXFRXOGRYHUULGHDvalZLWKDPHWKRGWKHUHZRXOGEHQRZD\IRU6FDODWRJXDUDQWHH
WKDWWKHPHWKRGZRXOGDOZD\VUHWXUQWKHVDPHYDOXHFRQVLVWHQWZLWK valVHPDQWLFV
7KDWLVVXHGRHVQ¦WH[LVWZLWKDvarRIFRXUVHEXW\RXZRXOGKDYHWRRYHUULGHWKHvar
ZLWK WZR PHWKRGV D UHDGHU DQG D ZULWHU 7KH 6FDOD FRPSLOHU GRHVQ¦W VXSSRUW WKDW
VXEVWLWXWLRQ

Companion Objects
5HFDOOWKDWILHOGVDQGPHWKRGVGHILQHGLQobjectsVHUYHWKHUROHWKDWFODVV£VWDWLF¤ILHOGV
DQGPHWKRGVVHUYHLQODQJXDJHVOLNH-DYD:KHQobjectEDVHGILHOGVDQGPHWKRGVDUH
FORVHO\DVVRFLDWHGZLWKDSDUWLFXODU classWKH\DUHQRUPDOO\GHILQHGLQDFRPSDQLRQ
REMHFW
:H PHQWLRQHG FRPSDQLRQ REMHFWV EULHIO\ LQ &KDSWHU  DQG ZH GLVFXVVHG WKH Pair
H[DPSOHIURPWKH6FDODOLEUDU\LQ&KDSWHU/HW¦VILOOLQWKHUHPDLQLQJGHWDLOVQRZ
)LUVWUHFDOOWKDWLIDclass RUDtypeUHIHUULQJWRDFODVV DQGDQobjectDUHGHFODUHGLQ
WKHVDPHILOHLQWKHVDPHSDFNDJHDQGZLWKWKHVDPHQDPHWKH\DUHFDOOHGDFRPSDQLRQ
FODVV RUFRPSDQLRQW\SH DQGDFRPSDQLRQREMHFWUHVSHFWLYHO\
7KHUHLVQRQDPHVSDFHFROOLVLRQZKHQWKHQDPHLVUHXVHGLQWKLVZD\EHFDXVH6FDOD
VWRUHVWKHFODVVQDPHLQWKHW\SHQDPHVSDFHZKLOHLWVWRUHVWKHREMHFWQDPHLQWKHWHUP
QDPHVSDFH VHH>6FDOD6SHF@ 
7KH WZR PRVW LQWHUHVWLQJ PHWKRGV IUHTXHQWO\ GHILQHG LQ D FRPSDQLRQ REMHFW DUH
applyDQGunapply

126 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
Apply
6FDODSURYLGHVVRPHV\QWDFWLFVXJDULQWKHIRUPRIWKHapplyPHWKRG:KHQDQLQVWDQFH
RIDFODVVLVIROORZHGE\SDUHQWKHVHVZLWKDOLVWRI]HURRUPRUHSDUDPHWHUVWKHFRPSLOHU
LQYRNHVWKH applyPHWKRGIRUWKDWLQVWDQFH7KLVLVWUXHIRUDQ objectZLWKDGHILQHG
applyPHWKRG VXFKDVDFRPSDQLRQREMHFW DVZHOODVDQLQVWDQFHRIDclassWKDWGHILQHV
DQapplyPHWKRG
,QWKHFDVHRIDQobjectapplyLVFRQYHQWLRQDOO\XVHGDVDIDFWRU\PHWKRGUHWXUQLQJD
QHZLQVWDQFH7KLVLVZKDWPair.applyGRHVLQWKH6FDODOLEUDU\+HUHLVPairIURPWKH
VWDQGDUGOLEUDU\
type Pair[+A, +B] = Tuple2[A, B]
object Pair {
def apply[A, B](x: A, y: B) = Tuple2(x, y)
def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x)
}

6R\RXFDQFUHDWHDQHZPairDVIROORZV
val p = Pair(1, "one")

,WORRNVOLNHZHDUHVRPHKRZFUHDWLQJDPairLQVWDQFHZLWKRXWDnew5DWKHUWKDQFDOOLQJ
DPairFRQVWUXFWRUGLUHFWO\ZHDUHDFWXDOO\FDOOLQJPair.apply LHWKHFRPSDQLRQRE
MHFWPair ZKLFKWKHQFDOOVTuple2.applyRQWKHTuple2FRPSDQLRQREMHFW

,IWKHUHDUHVHYHUDODOWHUQDWLYHFRQVWUXFWRUVIRUDFODVVDQGLWDOVRKDVD
FRPSDQLRQREMHFWFRQVLGHUGHILQLQJIHZHUFRQVWUXFWRUVRQWKHFODVVDQG
GHILQLQJVHYHUDORYHUORDGHGapplyPHWKRGVRQWKHFRPSDQLRQREMHFWWR
KDQGOHWKHYDULDWLRQV

+RZHYHU applyLVQRWOLPLWHGWRLQVWDQWLDWLQJWKHFRPSDQLRQFODVV,WFRXOGLQVWHDG
UHWXUQDQLQVWDQFHRIDVXEFODVVRIWKHFRPSDQLRQFODVV+HUHLVDQH[DPSOHZKHUHZH
GHILQHDFRPSDQLRQREMHFW WidgetWKDWXVHVUHJXODUH[SUHVVLRQVWRSDUVHDVWULQJUHS
UHVHQWLQJDWidgetVXEFODVV:KHQDPDWFKRFFXUVWKHVXEFODVVLVLQVWDQWLDWHGDQGWKH
QHZLQVWDQFHLVUHWXUQHG
// code-examples/AdvOOP/objects/widget.scala

package objects

abstract class Widget {


def draw(): Unit
override def toString() = "(widget)"
}

object Widget {
val ButtonExtractorRE = """\(button: label=([^,]+),\s+\(Widget\)\)""".r
val TextFieldExtractorRE = """\(textfield: text=([^,]+),\s+\(Widget\)\)""".r

def apply(specification: String): Option[Widget] = specification match {

Companion Objects | 127

Download at WoweBook.Com
case ButtonExtractorRE(label) => new Some(new Button(label))
case TextFieldExtractorRE(text) => new Some(new TextField(text))
case _ => None
}
}

Widget.applyUHFHLYHVDVWULQJ£VSHFLILFDWLRQ¤WKDWGHILQHVZKLFKFODVVWRLQVWDQWLDWH
7KHVWULQJPLJKWFRPHIURPDFRQILJXUDWLRQILOHZLWKZLGJHWVWRFUHDWHDWVWDUWXSIRU
H[DPSOH7KHVWULQJIRUPDWLVWKHVDPHIRUPDWXVHGE\toString()5HJXODUH[SUHVVLRQV
DUHGHILQHGIRUHDFKW\SH 3DUVHUFRPELQDWRUVDUHDQDOWHUQDWLYH7KH\DUHGLVFXVVHGLQ
£([WHUQDO'6/VZLWK3DUVHU&RPELQDWRUV¤RQSDJH
7KHmatchH[SUHVVLRQDSSOLHVHDFKUHJXODUH[SUHVVLRQWRWKHVWULQJ$FDVHH[SUHVVLRQ
OLNH
case ButtonExtractorRE(label) => new Some(new Button(label))

PHDQVWKDWWKHVWULQJLVPDWFKHGDJDLQVWWKHButtonExtractorREUHJXODUH[SUHVVLRQ,I
VXFFHVVIXOLWH[WUDFWVWKHVXEVWULQJLQWKHILUVWFDSWXUHJURXSLQWKHUHJXODUH[SUHVVLRQ
DQGDVVLJQVLWWRWKHYDULDEOH label)LQDOO\DQHZ ButtonZLWKWKLVODEHOLVFUHDWHG
ZUDSSHGLQDSome:H¦OOOHDUQKRZWKLVH[WUDFWLRQSURFHVVZRUNVLQWKHQH[WVHFWLRQ
£8QDSSO\¤RQSDJH
$VLPLODUFDVHKDQGOHVTextFieldFUHDWLRQ TextFieldLVQRWVKRZQ6HHWKHRQOLQHFRGH
H[DPSOHV )LQDOO\LIapplyFDQ¦WPDWFKWKHVWULQJLWUHWXUQVNone
+HUHLVDspecsobjectWKDWH[HUFLVHVWidget.apply
// code-examples/AdvOOP/objects/widget-apply-spec.scala

package objects
import org.specs._

object WidgetApplySpec extends Specification {


"Widget.apply with a valid widget specification string" should {
"return a widget instance with the correct fields set" in {
Widget("(button: label=click me, (Widget))") match {
case Some(w) => w match {
case b:Button => b.label mustEqual "click me"
case x => fail(x.toString())
}
case None => fail("None returned.")
}
Widget("(textfield: text=This is text, (Widget))") match {
case Some(w) => w match {
case tf:TextField => tf.text mustEqual "This is text"
case x => fail(x.toString())
}
case None => fail("None returned.")
}
}
}
"Widget.apply with an invalid specification string" should {
"return None" in {

128 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
Widget("(button: , (Widget)") mustEqual None
}
}
}

7KHILUVWPDWFKVWDWHPHQWLPSOLFLWO\LQYRNHV Widget.applyZLWKWKHVWULQJ "(button:


label=click me, (Widget))",IDEXWWRQZUDSSHGLQD SomeLVQRWUHWXUQHGZLWKWKH
ODEHO"click me"WKLVWHVWZLOOIDLO1H[WDVLPLODUWHVWIRUDTextFieldZLGJHWLVGRQH
7KHILQDOWHVWXVHVDQLQYDOLGVWULQJDQGFRQILUPVWKDWNoneLVUHWXUQHG
$GUDZEDFNRIWKLVSDUWLFXODULPSOHPHQWDWLRQLVWKDWZHKDYHKDUGFRGHGDGHSHQGHQF\
RQHDFKGHULYHGFODVVRIWidgetLQWidgetLWVHOIZKLFKEUHDNVWKH2SHQ&ORVHG3ULQFL
SOH VHH>0H\HU@DQG>0DUWLQ@ $EHWWHULPSOHPHQWDWLRQZRXOGXVHDIDFWRU\
GHVLJQSDWWHUQIURP>*2)@1HYHUWKHOHVVWKHH[DPSOHLOOXVWUDWHVKRZDQ apply
PHWKRGFDQEHXVHGDVDUHDOIDFWRU\
7KHUHLVQRUHTXLUHPHQWIRUapplyLQDQobjectWREHXVHGDVDIDFWRU\1HLWKHULVWKHUH
DQ\UHVWULFWLRQRQWKHDUJXPHQWOLVWRUZKDW applyUHWXUQV+RZHYHUEHFDXVHLWLVVR
FRPPRQWRXVHapplyLQDQobjectDVDIDFWRU\XVHFDXWLRQZKHQXVLQJapplyIRURWKHU
SXUSRVHVDVLWFRXOGFRQIXVHXVHUV+RZHYHUWKHUHDUHJRRGFRXQWHUH[DPSOHVVXFK
DVWKHXVHRIapplyLQ'RPDLQ6SHFLILF/DQJXDJHV VHH&KDSWHU 
7KHIDFWRU\FRQYHQWLRQLVOHVVFRPPRQO\XVHGIRUapplyGHILQHGLQFODVVHV)RUH[DPSOH
LQWKH6FDODVWDQGDUGOLEUDU\Array.apply(i: int)UHWXUQVWKHHOHPHQWDWLQGH[iLQWKH
DUUD\0DQ\RIWKHRWKHUFROOHFWLRQVXVHapplyLQDVLPLODUZD\6RXVHUVFDQZULWHFRGH
OLNHWKHIROORZLQJ
val a = Array(1,2,3,4)
println(a(2)) // => 3

)LQDOO\DVDUHPLQGHUDOWKRXJKapplyLVKDQGOHGVSHFLDOO\E\WKHFRPSLOHULWLVRWKHU
ZLVHQRGLIIHUHQWIURPDQ\RWKHUPHWKRG<RXFDQRYHUORDGLW\RXFDQLQYRNHLWGLUHFWO\
HWF

Unapply
7KHQDPHunapplyVXJJHVWVWKDWLWGRHVWKH£RSSRVLWH¤RSHUDWLRQRIapply,QGHHGLWLV
XVHGWRH[WUDFWWKHFRQVWLWXHQWSDUWVRIDQLQVWDQFH3DWWHUQPDWFKLQJXVHVWKLVIHDWXUH
H[WHQVLYHO\+HQFHunapplyLVRIWHQGHILQHGLQFRPSDQLRQREMHFWVDQGLVXVHGWRH[WUDFW
WKHILHOGYDOXHVIURPLQVWDQFHVRIWKHFRUUHVSRQGLQJFRPSDQLRQW\SHV)RUWKLVUHDVRQ
unapplyPHWKRGVDUHFDOOHGH[WUDFWRUV
+HUHLVDQH[SDQGHGbutton.scalaZLWKDButtonobjectWKDWGHILQHVDQunapplyH[WUDFWRU
PHWKRG
// code-examples/AdvOOP/objects/button.scala

package objects
import ui3.Clickable

class Button(val label: String) extends Widget with Clickable {

Companion Objects | 129

Download at WoweBook.Com
def click() = {
// Logic to give the appearance of clicking a button...
}

def draw() = {
// Logic to draw the button on the display, web page, etc.
}

override def toString() = "(button: label="+label+", "+super.toString()+")"


}

object Button {
def unapply(button: Button) = Some(button.label)
}

Button.unapplyWDNHVDVLQJOHButtonDUJXPHQWDQGUHWXUQVDSomeZUDSSLQJWKH label
YDOXH7KLVGHPRQVWUDWHVWKHSURWRFROIRUunapplyPHWKRGV7KH\UHWXUQDSomeZUDS
SLQJWKHH[WUDFWHGILHOGV :H¦OOVHHKRZWRKDQGOHPRUHWKDQRQHILHOGLQDPRPHQW
+HUHLVDspecsobjectWKDWH[HUFLVHVButton.unapply
// code-examples/AdvOOP/objects/button-unapply-spec.scala

package objects
import org.specs._

object ButtonUnapplySpec extends Specification {


"Button.unapply" should {
"match a Button object" in {
val b = new Button("click me")
b match {
case Button(label) =>
case _ => fail()
}
}
"match a RadioButton object" in {
val b = new RadioButton(false, "click me")
b match {
case Button(label) =>
case _ => fail()
}
}
"not match a non-Button object" in {
val tf = new TextField("hello world!")
tf match {
case Button(label) => fail()
case _ =>
}
}
"extract the Button's label" in {
val b = new Button("click me")
b match {
case Button(label) => label mustEqual "click me"
case _ => fail()
}

130 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
}
"extract the RadioButton's label" in {
val rb = new RadioButton(false, "click me, too")
rb match {
case Button(label) => label mustEqual "click me, too"
case _ => fail()
}
}
}
}

7KH ILUVW WKUHH H[DPSOHV in FODXVHV  FRQILUP WKDW Button.unapply LV RQO\ FDOOHG IRU
DFWXDOButtonLQVWDQFHVRULQVWDQFHVRIGHULYHGFODVVHVOLNHRadioButton
6LQFHunapplyWDNHVDButtonDUJXPHQW LQWKLVFDVH WKH6FDODUXQWLPHW\SHFKHFNVWKH
LQVWDQFHEHLQJPDWFKHG,WWKHQORRNVIRUDFRPSDQLRQREMHFWZLWKDQunapplyPHWKRG
DQGLQYRNHVWKDWPHWKRGSDVVLQJWKHLQVWDQFH7KHGHIDXOWFDVHFODXVHcase _LVLQYRNHG
IRUWKHLQVWDQFHVWKDWGRQ¦WW\SHFKHFNDVFRPSDWLEOH7KHSDWWHUQPDWFKLQJSURFHVVLV
IXOO\W\SHVDIH
7KHUHPDLQLQJH[DPSOHV inFODXVHV FRQILUPWKDWWKHFRUUHFWYDOXHVIRUWKHlabelDUH
H[WUDFWHG7KH6FDODUXQWLPHDXWRPDWLFDOO\H[WUDFWVWKHLWHPLQWKHSome
:KDWDERXWH[WUDFWLQJPXOWLSOHILHOGV")RUDIL[HGVHWRINQRZQILHOGVDSomeZUDSSLQJ
DTupleLVUHWXUQHGDVVKRZQLQWKLVXSGDWHGYHUVLRQRIRadioButton
// code-examples/AdvOOP/objects/radio-button.scala

package objects

/**
* Button with two states, on or off, like an old-style,
* channel-selection botton on a radio.
*/
class RadioButton(val on: Boolean, label: String) extends Button(label)

object RadioButton {
def unapply(button: RadioButton) = Some((button.on, button.label))
// equivalent to: = Some(Pair(button.on, button.label))
}

$SomeZUDSSLQJDPair(button.on, button.label)LVUHWXUQHG$VZHGLVFXVVLQ£7KH
3UHGHI2EMHFW¤RQSDJH PairLVDW\SHGHILQHGWREHHTXDOWR Tuple2+HUHLVWKH
FRUUHVSRQGLQJspecsobjectWKDWWHVWVLW
// code-examples/AdvOOP/objects/radio-button-unapply-spec.scala

package objects
import org.specs._

object RadioButtonUnapplySpec extends Specification {


"RadioButton.unapply" should {
"should match a RadioButton object" in {
val b = new RadioButton(true, "click me")
b match {

Companion Objects | 131

Download at WoweBook.Com
case RadioButton(on, label) =>
case _ => fail()
}
}
"not match a Button (parent class) object" in {
val b = new Button("click me")
b match {
case RadioButton(on, label) => fail()
case _ =>
}
}
"not match a non-RadioButton object" in {
val tf = new TextField("hello world!")
tf match {
case RadioButton(on, label) => fail()
case _ =>
}
}
"extract the RadioButton's on/off state and label" in {
val b = new RadioButton(true, "click me")
b match {
case RadioButton(on, label) => {
label mustEqual "click me"
on mustEqual true
}
case _ => fail()
}
}
}
}

Apply and UnapplySeq for Collections


:KDWLI\RXZDQWWREXLOGDFROOHFWLRQIURPDYDULDEOHDUJXPHQWOLVWSDVVHGWRapply"
:KDWLI\RXZDQWWRH[WUDFWWKHILUVWIHZHOHPHQWVIURPDFROOHFWLRQDQG\RXGRQ¦WFDUH
DERXWWKHUHVWRILW"
,QWKLVFDVH\RXGHILQHapplyDQGunapplySeq £XQDSSO\VHTXHQFH¤ PHWKRGV+HUHDUH
WKRVHPHWKRGVIURP6FDOD¦VRZQListFODVV
def apply[A](xs: A*): List[A] = xs.toList

def unapplySeq[A](x: List[A]): Some[List[A]] = Some(x)

7KH[A]W\SHSDUDPHWHUL]DWLRQRQWKHVHPHWKRGVDOORZVWKHListobjectZKLFKLVQRW
SDUDPHWHUL]HG WR FRQVWUXFW D QHZ List[A] 6HH £8QGHUVWDQGLQJ 3DUDPHWHUL]HG
7\SHV¤RQSDJHIRUPRUHGHWDLOV 0RVWRIWKHWLPHWKHW\SHSDUDPHWHUZLOOEH
LQIHUUHGEDVHGRQWKHFRQWH[W
7KHSDUDPHWHUOLVWxs: A*LVDYDULDEOHDUJXPHQWOLVW&DOOHUVRIapplyFDQSDVVDVPDQ\
ALQVWDQFHVDVWKH\ZDQWLQFOXGLQJQRQH,QWHUQDOO\YDULDEOHDUJXPHQWOLVWVDUHVWRUHG
LQDQArray[A]ZKLFKLQKHULWVWKHtoListPHWKRGIURPIterableWKDWZHXVHGKHUH

132 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
7KLVLVDKDQG\LGLRPIRU$3,ZULWHUV$FFHSWLQJYDULDEOHDUJXPHQWVWR
DIXQFWLRQFDQEHFRQYHQLHQWIRUXVHUVDQGFRQYHUWLQJWKHDUJXPHQWV
WRDListLVRIWHQLGHDOIRULQWHUQDOPDQDJHPHQW

+HUHLVDQH[DPSOHVFULSWWKDWXVHVList.applyLPSOLFLWO\
// code-examples/AdvOOP/objects/list-apply-example-script.scala

val list1 = List()


val list2 = List(1, 2.2, "three", 'four)
val list3 = List("1", "2.2", "three", "four")
println("1: "+list1)
println("2: "+list2)
println("3: "+list3)

7KH'fourLVDV\PEROHVVHQWLDOO\DQLQWHUQHGVWULQJ6\PEROVDUHPRUHFRPPRQO\XVHG
LQ5XE\IRUH[DPSOHZKHUHWKHVDPHV\PEROZRXOGEHZULWWHQDV:four6\PEROVDUH
XVHIXOIRUUHSUHVHQWLQJLGHQWLWLHVFRQVLVWHQWO\
7KLVVFULSW\LHOGVWKHIROORZLQJRXWSXW
1: List()
2: List(1, 2.2, three, 'four)
3: List(1, 2.2, three, four)

7KHunapplySeqPHWKRGLVWULYLDOLWUHWXUQVWKHLQSXWOLVWZUDSSHGLQDSome+RZHYHU
WKLVLVVXIILFLHQWIRUSDWWHUQPDWFKLQJDVVKRZQLQWKLVH[DPSOH
// code-examples/AdvOOP/objects/list-unapply-example-script.scala

val list = List(1, 2.2, "three", 'four)


list match {
case List(x, y, _*) => println("x = "+x+", y = "+y)
case _ => throw new Exception("No match! "+list)
}

7KHList(x, y, _*)V\QWD[PHDQVZHZLOORQO\PDWFKRQDOLVWZLWKDWOHDVWWZRHOHPHQWV
DQGWKHILUVWWZRHOHPHQWVZLOOEHDVVLJQHGWRxDQGy:HGRQ¦WFDUHDERXWWKHUHVWRI
WKHOLVW7KH_*PDWFKHV]HURRUPRUHUHPDLQLQJHOHPHQWV
7KHRXWSXWLVWKHIROORZLQJ
x = 1, y = 2.2

:H¦OOKDYHPXFKPRUHWRVD\DERXWListDQGSDWWHUQPDWFKLQJLQ£/LVWVLQ)XQFWLRQDO
3URJUDPPLQJ¤RQSDJH

Companion Objects and Java Static Methods


7KHUHLVRQHPRUHWKLQJWRNQRZDERXWFRPSDQLRQREMHFWV:KHQHYHU\RXGHILQHD
mainPHWKRGWRXVHDVWKHHQWU\SRLQWIRUDQDSSOLFDWLRQ6FDODUHTXLUHV\RXWRSXWLWLQ
DQREMHFW+RZHYHUDWWKHWLPHRIWKLVZULWLQJ mainPHWKRGVFDQQRWEHGHILQHGLQD

Companion Objects | 133

Download at WoweBook.Com
FRPSDQLRQREMHFW%HFDXVHRILPSOHPHQWDWLRQGHWDLOVLQWKHJHQHUDWHGFRGHWKH-90
ZRQ¦WILQGWKH mainPHWKRG7KLVLVVXHPD\EHUHVROYHGLQDIXWXUHUHOHDVH)RUQRZ
\RXPXVWGHILQHDQ\mainPHWKRGLQDVLQJOHWRQREMHFW LHD£QRQFRPSDQLRQ¤REMHFW
VHH>6FDOD7LSV@ &RQVLGHUWKHIROORZLQJH[DPSOHRIDVLPSOH PersonFODVVDQGFRP
SDQLRQREMHFWWKDWDWWHPSWVWRGHILQHmain
// code-examples/AdvOOP/objects/person.scala

package objects

class Person(val name: String, val age: Int) {


override def toString = "name: " + name + ", age: " + age
}

object Person {
def apply(name: String, age: Int) = new Person(name, age)
def unapply(person: Person) = Some((person.name, person.age))

def main(args: Array[String]) = {


// Test the constructor...
val person = new Person("Buck Trends", 18)
assert(person.name == "Buck Trends")
assert(person.age == 21)
}
}

object PersonTest {
def main(args: Array[String]) = Person.main(args)
}

7KLVFRGHFRPSLOHVILQHEXWLI\RXDWWHPSWWRLQYRNHPerson.mainXVLQJscala -cp ...


objects.Person\RXJHWWKHIROORZLQJHUURU
java.lang.NoSuchMethodException: objects.Person.main([Ljava.lang.String;)

7KH objects/Person.classILOHH[LVWV,I\RXGHFRPSLOHLWZLWK javap -classpath ...


objects.Person UHIHU WR £7KH VFDODS MDYDS DQG MDG &RPPDQG/LQH
7RROV¤RQSDJH \RXFDQVHHWKDWLWGRHVQ¦WFRQWDLQD mainPHWKRG,I\RXGH
FRPSLOHobjects/Person$.classWKHILOHIRUWKHFRPSDQLRQREMHFW¦VE\WHFRGHLWKDVD
mainPHWKRGEXWQRWLFHWKDWLWLVQ¦WGHFODUHG static6RDWWHPSWLQJWRLQYRNH scala
-cp ... objects.Person$DOVRIDLOVWRILQGWKH£VWDWLF¤main
java.lang.NoSuchMethodException: objects.Person$.main is not static

7KHVHSDUDWHVLQJOHWRQREMHFW PersonTestGHILQHGLQWKLVH[DPSOHKDVWREHXVHG'H
FRPSLOLQJLWZLWKjavap -classpath ... objects.PersonTestVKRZVWKDWLWKDVDstatic
mainPHWKRG,I\RXLQYRNHLWXVLQJ scala -cp ... objects.PersonTestWKH PersonT
est.mainPHWKRGLVLQYRNHGZKLFKLQWXUQLQYRNHVPerson.main<RXJHWDQDVVHUWLRQ
HUURUIURPWKHVHFRQGFDOOWRassertZKLFKLVLQWHQWLRQDO
java.lang.AssertionError: assertion failed
at scala.Predef$.assert(Predef.scala:87)
at objects.Person$.test(person.scala:15)

134 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
at objects.PersonTest$.main(person.scala:20)
at objects.PersonTest.main(person.scala)
...

,QIDFWWKLVLVDJHQHUDOLVVXHZLWKPHWKRGVGHILQHGLQFRPSDQLRQREMHFWVWKDWQHHGWR
EHYLVLEOHWR-DYDFRGHDVVWDWLFPHWKRGV7KH\DUHQ¦WVWDWLFLQWKHE\WHFRGH<RXKDYH
WRSXWWKHVHPHWKRGVLQVLQJOHWRQREMHFWVLQVWHDG&RQVLGHUWKHIROORZLQJ-DYDFODVV
WKDWDWWHPSWVWRFUHDWHDXVHUZLWKPerson.apply
// code-examples/AdvOOP/objects/PersonUserWontCompile.java
// WON'T COMPILE

package objects;

public class PersonUserWontCompile {


public static void main(String[] args) {
Person buck = Person.apply("Buck Trends", 100); // ERROR
System.out.println(buck);
}
}

,IZHFRPSLOHLW DIWHUFRPSLOLQJPerson.scala ZHJHWWKHIROORZLQJHUURU


$ javac -classpath ... objects/PersonUserWontCompile.java
objects/PersonUserWontCompile.java:5: cannot find symbol
symbol : method apply(java.lang.String,int)
location: class objects.Person
Person buck = Person.apply("Buck Trends", 100);
^
1 error

+RZHYHUZHFDQXVHWKHIROORZLQJVLQJOHWRQREMHFW
// code-examples/AdvOOP/objects/person-factory.scala

package objects

object PersonFactory {
def make(name: String, age: Int) = new Person(name, age)
}

1RZWKHIROORZLQJ-DYDFODVVZLOOFRPSLOH
// code-examples/AdvOOP/objects/PersonUser.java

package objects;

public class PersonUser {


public static void main(String[] args) {
// The following line won't compile.
// Person buck = Person.apply("Buck Trends", 100);
Person buck = PersonFactory.make("Buck Trends", 100);
System.out.println(buck);
}
}

Companion Objects | 135

Download at WoweBook.Com
'RQRWGHILQHmainRUDQ\RWKHUPHWKRGLQDFRPSDQLRQREMHFWWKDWQHHGV
WREHYLVLEOHWR-DYDFRGHDVD staticPHWKRG'HILQHLWLQDVLQJOHWRQ
REMHFWLQVWHDG

,I\RXKDYHQRRWKHUFKRLFHEXWWRFDOODPHWKRGLQDFRPSDQLRQREMHFWIURP-DYD\RX
FDQH[SOLFLWO\FUHDWHDQLQVWDQFHRIWKHREMHFWZLWK newVLQFHWKHREMHFWLVD£UHJXODU¤
-DYDFODVVLQWKHE\WHFRGHDQGFDOOWKHPHWKRGRQWKHLQVWDQFH

Case Classes
,Q£0DWFKLQJRQ&DVH&ODVVHV¤RQSDJHZHEULHIO\LQWURGXFHG\RXWRFDVHFODVVHV
&DVHFODVVHVKDYHVHYHUDOXVHIXOIHDWXUHVEXWDOVRVRPHGUDZEDFNV
/HW¦VUHZULWHWKH ShapeH[DPSOHZHXVHGLQ£$7DVWHRI&RQFXUUHQF\¤RQSDJHWR
XVHFDVHFODVVHV+HUHLVWKHRULJLQDOLPSOHPHQWDWLRQ
// code-examples/IntroducingScala/shapes.scala

package shapes {
class Point(val x: Double, val y: Double) {
override def toString() = "Point(" + x + "," + y + ")"
}

abstract class Shape() {


def draw(): Unit
}

class Circle(val center: Point, val radius: Double) extends Shape {


def draw() = println("Circle.draw: " + this)
override def toString() = "Circle(" + center + "," + radius + ")"
}

class Rectangle(val lowerLeft: Point, val height: Double, val width: Double)
extends Shape {
def draw() = println("Rectangle.draw: " + this)
override def toString() =
"Rectangle(" + lowerLeft + "," + height + "," + width + ")"
}

class Triangle(val point1: Point, val point2: Point, val point3: Point)
extends Shape() {
def draw() = println("Triangle.draw: " + this)
override def toString() =
"Triangle(" + point1 + "," + point2 + "," + point3 + ")"
}
}

+HUHLVWKHH[DPSOHUHZULWWHQXVLQJWKHcaseNH\ZRUG
// code-examples/AdvOOP/shapes/shapes-case.scala

package shapes {

136 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
case class Point(x: Double, y: Double)

abstract class Shape() {


def draw(): Unit
}

case class Circle(center: Point, radius: Double) extends Shape() {


def draw() = println("Circle.draw: " + this)
}

case class Rectangle(lowerLeft: Point, height: Double, width: Double)


extends Shape() {
def draw() = println("Rectangle.draw: " + this)
}

case class Triangle(point1: Point, point2: Point, point3: Point)


extends Shape() {
def draw() = println("Triangle.draw: " + this)
}
}

$GGLQJWKH caseNH\ZRUGFDXVHVWKHFRPSLOHUWRDGGDQXPEHURIXVHIXOIHDWXUHVDX
WRPDWLFDOO\ 7KH NH\ZRUG VXJJHVWV DQ DVVRFLDWLRQ ZLWK case H[SUHVVLRQV LQ SDWWHUQ
PDWFKLQJ,QGHHGWKH\DUHSDUWLFXODUO\ZHOOVXLWHGIRUWKDWDSSOLFDWLRQDVZHZLOOVHH
)LUVWWKHFRPSLOHUDXWRPDWLFDOO\FRQYHUWVWKHFRQVWUXFWRUDUJXPHQWVLQWRLPPXWDEOH
ILHOGV valV 7KHvalNH\ZRUGLVRSWLRQDO,I\RXZDQWPXWDEOHILHOGVXVHWKHvarNH\
ZRUG6RRXUFRQVWUXFWRUDUJXPHQWOLVWVDUHQRZVKRUWHU
6HFRQGWKHFRPSLOHUDXWRPDWLFDOO\LPSOHPHQWVequalshashCodeDQGtoStringPHWK
RGVWRWKHFODVVZKLFKXVHWKHILHOGVVSHFLILHGDVFRQVWUXFWRUDUJXPHQWV6RZHQR
ORQJHUQHHGRXURZQtoStringPHWKRGV,QIDFWWKHJHQHUDWHGtoStringPHWKRGVSUR
GXFH WKH VDPH RXWSXWV DV WKH RQHV ZH LPSOHPHQWHG RXUVHOYHV $OVR WKH ERG\ RI
PointLVJRQHEHFDXVHWKHUHDUHQRPHWKRGVWKDWZHQHHGWRGHILQH
7KHIROORZLQJVFULSWXVHVWKHVHPHWKRGVWKDWDUHQRZLQWKHVKDSHV
// code-examples/AdvOOP/shapes/shapes-usage-example1-script.scala

import shapes._

val shapesList = List(


Circle(Point(0.0, 0.0), 1.0),
Circle(Point(5.0, 2.0), 3.0),
Rectangle(Point(0.0, 0.0), 2, 5),
Rectangle(Point(-2.0, -1.0), 4, 3),
Triangle(Point(0.0, 0.0), Point(1.0, 0.0), Point(0.0, 1.0)))

val shape1 = shapesList.head // grab the first one.


println("shape1: "+shape1+". hash = "+shape1.hashCode)
for (shape2 <- shapesList) {
println("shape2: "+shape2+". 1 == 2 ? "+(shape1 == shape2))
}

Case Classes | 137

Download at WoweBook.Com
7KLVVFULSWRXWSXWVWKHIROORZLQJ
shape1: Circle(Point(0.0,0.0),1.0). hash = 2061963534
shape2: Circle(Point(0.0,0.0),1.0). 1 == 2 ? true
shape2: Circle(Point(5.0,2.0),3.0). 1 == 2 ? false
shape2: Rectangle(Point(0.0,0.0),2.0,5.0). 1 == 2 ? false
shape2: Rectangle(Point(-2.0,-1.0),4.0,3.0). 1 == 2 ? false
shape2: Triangle(Point(0.0,0.0),Point(1.0,0.0),Point(0.0,1.0)). 1 == 2 ? false

$VZH¦OOVHHLQ£(TXDOLW\RI2EMHFWV¤RQSDJHWKH==PHWKRGDFWXDOO\LQYRNHVWKH
equalsPHWKRG
(YHQRXWVLGHRIcaseH[SUHVVLRQVDXWRPDWLFJHQHUDWLRQRIWKHVHWKUHHPHWKRGVLVYHU\
FRQYHQLHQWIRUVLPSOH£VWUXFWXUDO¤FODVVHVLHFODVVHVWKDWFRQWDLQUHODWLYHO\VLPSOH
ILHOGVDQGEHKDYLRUV
7KLUGZKHQWKHcaseNH\ZRUGLVXVHGWKHFRPSLOHUDXWRPDWLFDOO\FUHDWHVDFRPSDQLRQ
REMHFW ZLWK DQ apply IDFWRU\ PHWKRG WKDW WDNHV WKH VDPH DUJXPHQWV DV WKH SULPDU\
FRQVWUXFWRU7KHSUHYLRXVH[DPSOHXVHGWKHDSSURSULDWH applyPHWKRGVWRFUHDWHWKH
PointsWKHGLIIHUHQW ShapesDQGDOVRWKH ListLWVHOI7KDW¦VZK\ZHGRQ¦WQHHG new
ZH¦UHDFWXDOO\FDOOLQJapply(x,y)LQWKHPointFRPSDQLRQREMHFWIRUH[DPSOH

<RXFDQKDYHVHFRQGDU\FRQVWUXFWRUVLQFDVHFODVVHVEXWWKHUHZLOOEH
QRRYHUORDGHGapplyPHWKRGJHQHUDWHGWKDWKDVWKHVDPHDUJXPHQWOLVW
<RX¦OOKDYHWRXVHnewWRFUHDWHLQVWDQFHVZLWKWKRVHFRQVWUXFWRUV

7KHFRPSDQLRQREMHFWDOVRJHWVDQ unapplyH[WUDFWRUPHWKRGZKLFKH[WUDFWVDOOWKH
ILHOGVRIDQLQVWDQFHLQDQHOHJDQWIDVKLRQ7KHIROORZLQJVFULSWGHPRQVWUDWHVWKHH[
WUDFWRUVLQSDWWHUQPDWFKLQJcaseVWDWHPHQWV
// code-examples/AdvOOP/shapes/shapes-usage-example2-script.scala

import shapes._

val shapesList = List(


Circle(Point(0.0, 0.0), 1.0),
Circle(Point(5.0, 2.0), 3.0),
Rectangle(Point(0.0, 0.0), 2, 5),
Rectangle(Point(-2.0, -1.0), 4, 3),
Triangle(Point(0.0, 0.0), Point(1.0, 0.0), Point(0.0, 1.0)))

def matchOn(shape: Shape) = shape match {


case Circle(center, radius) =>
println("Circle: center = "+center+", radius = "+radius)
case Rectangle(ll, h, w) =>
println("Rectangle: lower-left = "+ll+", height = "+h+", width = "+w)
case Triangle(p1, p2, p3) =>
println("Triangle: point1 = "+p1+", point2 = "+p2+", point3 = "+p3)
case _ =>
println("Unknown shape!"+shape)
}

138 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
shapesList.foreach { shape => matchOn(shape) }

7KLVVFULSWRXWSXWVWKHIROORZLQJ
Circle: center = Point(0.0,0.0), radius = 1.0
Circle: center = Point(5.0,2.0), radius = 3.0
Rectangle: lower-left = Point(0.0,0.0), height = 2.0, width = 5.0
Rectangle: lower-left = Point(-2.0,-1.0), height = 4.0, width = 3.0
Triangle: point1 = Point(0.0,0.0), point2 = Point(1.0,0.0), point3 = Point(0.0,1.0)

Syntactic Sugar for Binary Operations


%\WKHZD\UHPHPEHULQ£0DWFKLQJRQ6HTXHQFHV¤RQSDJHZKHQZHGLVFXVVHG
PDWFKLQJRQOLVWV":HZURWHWKLVcaseH[SUHVVLRQ
def processList(l: List[Any]): Unit = l match {
case head :: tail => ...
...
}

,WWXUQVRXWWKDWWKHIROORZLQJH[SUHVVLRQVDUHLGHQWLFDO
case head :: tail => ...
case ::(head, tail) => ...

:HDUHXVLQJWKHFRPSDQLRQREMHFWIRUWKHFDVHFODVVQDPHG::ZKLFKLVXVHGIRUQRQ
HPSW\OLVWV:KHQXVHGLQ caseH[SUHVVLRQVWKHFRPSLOHUVXSSRUWVWKLVVSHFLDOLQIL[
RSHUDWRUQRWDWLRQIRULQYRFDWLRQVRIunapply
,WZRUNVQRWRQO\IRUunapplyPHWKRGVZLWKWZRDUJXPHQWVEXWDOVRZLWKRQHRUPRUH
DUJXPHQWV:HFRXOGUHZULWHRXUmatchOnPHWKRGWKLVZD\
def matchOn(shape: Shape) = shape match {
case center Circle radius => ...
case ll Rectangle (h, w) => ...
case p1 Triangle (p2, p3) => ...
case _ => ...
}

)RU DQ unapply WKDW WDNHV RQH DUJXPHQW \RX ZRXOG KDYH WR LQVHUW DQ HPSW\ VHW RI
SDUHQWKHVHVWRDYRLGDSDUVLQJDPELJXLW\
case arg Foo () => ...

)URPWKHSRLQWRIYLHZRIFODULW\WKLVV\QWD[LVHOHJDQWIRUVRPHFDVHVZKHQWKHUHDUH
WZRDUJXPHQWV)RUOLVWV head :: tailPDWFKHVWKHH[SUHVVLRQVIRUEXLOGLQJXSOLVWV
VRWKHUHLVDEHDXWLIXOV\PPHWU\ZKHQWKHH[WUDFWLRQSURFHVVXVHVWKHVDPHV\QWD[
+RZHYHUWKHPHULWVRIWKLVV\QWD[DUHOHVVFOHDUIRURWKHUH[DPSOHVHVSHFLDOO\ZKHQ
WKHUHDUH1 DUJXPHQWV

Case Classes | 139

Download at WoweBook.Com
The copy Method in Scala Version 2.8
,Q6FDODYHUVLRQDQRWKHULQVWDQFHPHWKRGLVDXWRPDWLFDOO\JHQHUDWHGFDOOHGcopy
7KLVPHWKRGLVXVHIXOZKHQ\RXZDQWWRPDNHDQHZLQVWDQFHRIDFDVHFODVVWKDWLV
LGHQWLFDOWRDQRWKHULQVWDQFHZLWKDIHZILHOGVFKDQJHG&RQVLGHUWKHIROORZLQJH[DPSOH
VFULSW
// code-examples/AdvOOP/shapes/shapes-usage-example3-v28-script.scala
// Scala version 2.8 only.

import shapes._

val circle1 = Circle(Point(0.0, 0.0), 2.0)


val circle2 = circle1 copy (radius = 4.0)

println(circle1)
println(circle2)

7KH VHFRQG FLUFOH LV FUHDWHG E\ FRS\LQJ WKH ILUVW DQG VSHFLI\LQJ D QHZ UDGLXV 7KH
copyPHWKRGLPSOHPHQWDWLRQWKDWLVJHQHUDWHGE\WKHFRPSLOHUH[SORLWVWKHQHZQDPHG
DQGGHIDXOWSDUDPHWHUVLQ6FDODYHUVLRQZKLFKZHGLVFXVVHGLQ£0HWKRG'HIDXOW
DQG1DPHG$UJXPHQWV 6FDOD9HUVLRQ ¤RQSDJH7KHJHQHUDWHGLPSOHPHQWDWLRQ
RICircle.copyORRNVURXJKO\OLNHWKHIROORZLQJ
case class Circle(center: Point, radius: Double) extends Shape() {
...
def copy(center: Point = this.center, radius: Double = this.radius) =
new Circle(center, radius)
}

6RGHIDXOWYDOXHVDUHSURYLGHGIRUDOOWKHDUJXPHQWVWRWKHPHWKRG RQO\WZRLQWKLV
FDVH :KHQXVLQJWKHcopyPHWKRGWKHXVHUVSHFLILHVE\QDPHRQO\WKHILHOGVWKDWDUH
FKDQJLQJ7KHYDOXHVIRUWKHUHVWRIWKHILHOGVDUHXVHGZLWKRXWKDYLQJWRUHIHUHQFHWKHP
H[SOLFLWO\

Case Class Inheritance


'LG\RXQRWLFHWKDWWKHQHZShapesFRGHLQ£&DVH&ODVVHV¤RQSDJHGLGQRWSXWWKH
caseNH\ZRUGRQWKHDEVWUDFW ShapeFODVV"7KLVLVDOORZHGE\WKHFRPSLOHUEXWWKHUH
DUHUHDVRQVIRUQRWKDYLQJRQHFDVHFODVVLQKHULWDQRWKHU)LUVWLWFDQFRPSOLFDWHILHOG
LQLWLDOL]DWLRQ6XSSRVHZHPDNH ShapeDFDVHFODVV6XSSRVHZHZDQWWRDGGDVWULQJ
ILHOGWRDOOVKDSHVUHSUHVHQWLQJDQidWKDWWKHXVHUZDQWVWRVHW,WPDNHVVHQVHWRGHILQH
WKLVILHOGLQShape/HW¦VPDNHWKHVHWZRFKDQJHVWRShape
abstract case class Shape(id: String) {
def draw(): Unit
}

1RZWKHGHULYHGVKDSHVQHHGWRSDVVWKH idWRWKH ShapeFRQVWUXFWRU)RUH[DPSOH


CircleZRXOGEHFRPHWKHIROORZLQJ

140 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
case class Circle(id: String, center: Point, radius: Double) extends Shape(id){
def draw(): Unit
}

+RZHYHULI\RXFRPSLOHWKLVFRGH\RX¦OOJHWHUURUVOLNHWKHIROORZLQJ
... error: error overriding value id in class Shape of type String;
value id needs `override' modifier
case class Circle(id: String, center: Point, radius: Double) extends Shape(id){
^

5HPHPEHU WKDW ERWK GHILQLWLRQV RI id WKH RQH LQ Shape DQG WKH RQH LQ Circle DUH
FRQVLGHUHG val ILHOG GHILQLWLRQV 7KH HUURU PHVVDJH WHOOV XV WKH DQVZHU XVH WKH
override NH\ZRUG DV ZH GLVFXVVHG LQ £2YHUULGLQJ 0HPEHUV RI &ODVVHV DQG
7UDLWV¤RQSDJH6RWKHFRPSOHWHVHWRIUHTXLUHGPRGLILFDWLRQVDUHDVIROORZV
// code-examples/AdvOOP/shapes/shapes-case-id.scala

package shapesid {
case class Point(x: Double, y: Double)

abstract case class Shape(id: String) {


def draw(): Unit
}

case class Circle(override val id: String, center: Point, radius: Double)
extends Shape(id) {
def draw() = println("Circle.draw: " + this)
}

case class Rectangle(override val id: String, lowerLeft: Point,


height: Double, width: Double) extends Shape(id) {
def draw() = println("Rectangle.draw: " + this)
}

case class Triangle(override val id: String, point1: Point,


point2: Point, point3: Point) extends Shape(id) {
def draw() = println("Triangle.draw: " + this)
}
}

1RWHWKDWZHDOVRKDYHWRDGGWKHvalNH\ZRUGV7KLVZRUNVEXWLWLVVRPHZKDWXJO\
$PRUHRPLQRXVSUREOHPLQYROYHVWKHJHQHUDWHGequalsPHWKRGV8QGHULQKHULWDQFH
WKHequalsPHWKRGVGRQ¦WREH\DOOWKHVWDQGDUGUXOHVIRUUREXVWREMHFWHTXDOLW\:H¦OO
GLVFXVVWKRVHUXOHVLQ£(TXDOLW\RI2EMHFWV¤RQSDJH)RUQRZFRQVLGHUWKHIRO
ORZLQJH[DPSOH
// code-examples/AdvOOP/shapes/shapes-case-equals-ambiguity-script.scala

import shapesid._

case class FancyCircle(name: String, override val id: String,


override val center: Point, override val radius: Double)
extends Circle(id, center, radius) {
override def draw() = println("FancyCircle.draw: " + this)

Case Classes | 141

Download at WoweBook.Com
}

val fc = FancyCircle("me", "circle", Point(0.0,0.0), 10.0)


val c = Circle("circle", Point(0.0,0.0), 10.0)
format("FancyCircle == Circle? %b\n", (fc == c))
format("Circle == FancyCircle? %b\n", (c == fc))

,I\RXUXQWKLVVFULSW\RXJHWWKHIROORZLQJRXWSXW
FancyCircle == Circle? false
Circle == FancyCircle? true

6RCircle.equalsHYDOXDWHVWRtrueZKHQJLYHQDFancyCircleZLWKWKHVDPHYDOXHVIRU
WKH Circle ILHOGV 7KH UHYHUVH FDVH LVQ¦W WUXH :KLOH \RX PLJKW DUJXH WKDW DV IDU DV
CircleLVFRQFHUQHGWKH\UHDOO\DUHHTXDOPRVWSHRSOHZRXOGDUJXHWKDWWKLVLVDULVN\
£UHOD[HG¤LQWHUSUHWDWLRQRIHTXDOLW\,W¦VWUXHWKDWDIXWXUHYHUVLRQRI6FDODFRXOGJHQ
HUDWHequalsPHWKRGVIRUcaseFODVVHVWKDWGRH[DFWW\SHHTXDOLW\FKHFNLQJ
6RWKHFRQYHQLHQFHVSURYLGHGE\FDVHFODVVHVVRPHWLPHVOHDGWRSUREOHPV,WLVEHVWWR
DYRLGLQKHULWDQFHRIRQHFDVHFODVVE\DQRWKHU1RWHWKDWLW¦VILQHIRUDFDVHFODVVWR
LQKHULWIURPDQRQFDVHFODVVRUWUDLW,W¦VDOVRILQHIRUDQRQFDVHFODVVRUWUDLWWRLQKHULW
IURPDFDVHFODVV
%HFDXVHRIWKHVHLVVXHVLWLVSRVVLEOHWKDWFDVHFODVVLQKHULWDQFHZLOOEHGHSUHFDWHGDQG
UHPRYHGLQIXWXUHYHUVLRQVRI6FDOD

$YRLGLQKHULWLQJDFDVHFODVVIURPDQRWKHUFDVHFODVV

Equality of Objects
,PSOHPHQWLQJDUHOLDEOHHTXDOLW\WHVWIRULQVWDQFHVLVGLIILFXOWWRGRFRUUHFWO\(IIHFWLYH
-DYD >%ORFK@ DQGWKH6FDODGRFSDJHIRUAnyRef.equalsGHVFULEHWKHUHTXLUHPHQWV
IRUDJRRGHTXDOLW\WHVW$YHU\JRRGGHVFULSWLRQRIWKHWHFKQLTXHVIRUZULWLQJFRUUHFW
equalsDQGhashCodePHWKRGVFDQEHIRXQGLQ>2GHUVN\@ZKLFKXVHV-DYDV\QWD[
EXWLVDGDSWHGIURP&KDSWHURI3URJUDPPLQJLQ6FDOD >2GHUVN\@ &RQVXOW
WKHVHUHIHUHQFHVZKHQ\RXQHHGWRLPSOHPHQW\RXURZQequalsDQGhashCodePHWKRGV
5HFDOOWKDWWKHVHPHWKRGVDUHFUHDWHGDXWRPDWLFDOO\IRUcaseFODVVHV
+HUHZHIRFXVRQWKHGLIIHUHQWHTXDOLW\PHWKRGVDYDLODEOHLQ6FDODDQGWKHLUPHDQLQJV
7KHUH DUH VRPH VOLJKW LQFRQVLVWHQFLHV EHWZHHQ WKH 6FDOD VSHFLILFDWLRQ VHH >6FDOD6
SHF@  DQG WKH 6FDODGRF SDJHV IRU WKH HTXDOLW\UHODWHG PHWKRGV IRU Any DQG
AnyRefEXWWKHJHQHUDOEHKDYLRULVFOHDU

6RPHRIWKHHTXDOLW\PHWKRGVKDYHWKHVDPHQDPHVDVHTXDOLW\PHWKRGV
LQRWKHUODQJXDJHVEXWWKHVHPDQWLFVDUHVRPHWLPHVGLIIHUHQW

142 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
The equals Method
7KH equalsPHWKRGWHVWVIRUYDOXHHTXDOLW\7KDWLV obj1 equals obj2LVWUXHLIERWK
obj1DQGobj2KDYHWKHVDPHYDOXH7KH\GRQRWQHHGWRUHIHUWRWKHVDPHLQVWDQFH
+HQFHequalsEHKDYHVOLNHWKHequalsPHWKRGLQ-DYDDQGWKHeql?PHWKRGLQ5XE\

The == and != Methods


:KLOH==LVDQRSHUDWRULQPDQ\ODQJXDJHVLWLVDPHWKRGLQ6FDODGHILQHGDVfinalLQ
Any,WWHVWVIRUYDOXHHTXDOLW\OLNHequals7KDWLVobj1 == obj2LVWUXHLIERWKobj1DQG
obj2KDYHWKHVDPHYDOXH,QIDFW ==GHOHJDWHVWR equals+HUHLVSDUWRIWKH6FDODGRF
HQWU\IRUAny.==
o == arg0 is the same as o.equals(arg0).

+HUHLVWKHFRUUHVSRQGLQJSDUWRIWKH6FDODGRFHQWU\IRUAnyRef.==
o == arg0 is the same as if (o eq null) arg0 eq null else o.equals(arg0).

$V\RXZRXOGH[SHFW!=LVWKHQHJDWLRQLHLWLVHTXLYDOHQWWR!(obj1 == obj2)
6LQFH==DQG!=DUHGHFODUHGfinalLQAny\RXFDQ¦WRYHUULGHWKHPEXW\RXGRQ¦WQHHG
WRVLQFHWKH\GHOHJDWHWRequals

,Q -DYD & DQG & WKH == RSHUDWRU WHVWV IRU UHIHUHQFH QRW YDOXH
HTXDOLW\,QFRQWUDVW5XE\¦V==RSHUDWRUWHVWVIRUYDOXHHTXDOLW\:KDW
HYHUODQJXDJH\RX¦UHXVHGWRPDNHVXUHWRUHPHPEHUWKDWLQ6FDOD==
LVWHVWLQJIRUYDOXHHTXDOLW\

The ne and eq Methods


7KHeqPHWKRGWHVWVIRUUHIHUHQFHHTXDOLW\7KDWLVobj1 eq obj2LVWUXHLIERWKobj1DQG
obj2SRLQWWRWKHVDPHORFDWLRQLQPHPRU\7KHVHPHWKRGVDUHRQO\GHILQHGIRUAnyRef
+HQFHeqEHKDYHVOLNHWKH==RSHUDWRULQ-DYD&DQG&EXWQRW==LQ5XE\
7KHnePHWKRGLVWKHQHJDWLRQRIeqLHLWLVHTXLYDOHQWWR!(obj1 eq obj2)

Array Equality and the sameElements Method


&RPSDULQJWKHFRQWHQWVRIWZRArrayVGRHVQ¦WKDYHDQREYLRXVUHVXOWLQ6FDOD
scala> Array(1, 2) == Array(1, 2)
res0: Boolean = false

7KDW¦V D VXUSULVH 7KDQNIXOO\ WKHUH¦V D VLPSOH VROXWLRQ LQ WKH IRUP RI WKH
sameElementsPHWKRG
scala> Array(1, 2).sameElements(Array(1, 2))
res1: Boolean = true

Equality of Objects | 143

Download at WoweBook.Com
0XFKEHWWHU5HPHPEHUWRXVHsameElementsZKHQ\RXZDQWWRWHVWLIWZRArrayVFRQ
WDLQWKHVDPHHOHPHQWV
:KLOHWKLVPD\VHHPOLNHDQLQFRQVLVWHQF\HQFRXUDJLQJDQH[SOLFLWWHVWRIWKHHTXDOLW\
RIWZRPXWDEOHGDWDVWUXFWXUHVLVDFRQVHUYDWLYHDSSURDFKRQWKHSDUWRIWKHODQJXDJH
GHVLJQHUV ,Q WKH ORQJ UXQ LW VKRXOG VDYH \RX IURP XQH[SHFWHG UHVXOWV LQ \RXU
FRQGLWLRQDOV

Recap and What’s Next


:HH[SORUHGWKHILQHSRLQWVRIRYHUULGLQJPHPEHUVLQGHULYHGFODVVHV:HOHDUQHGDERXW
REMHFWHTXDOLW\FDVHFODVVHVDQGFRPSDQLRQFODVVHVDQGREMHFWV
,Q WKH QH[W FKDSWHU ZH¦OO OHDUQ DERXW WKH 6FDOD W\SH KLHUDUFK\¢LQ SDUWLFXODU WKH
PredefREMHFWWKDWLQFOXGHVPDQ\XVHIXOGHILQLWLRQV:H¦OODOVROHDUQDERXW6FDOD¦VDO
WHUQDWLYHWR-DYD¦VstaticFODVVPHPEHUVDQGWKHOLQHDUL]DWLRQUXOHVIRUPHWKRGORRNXS

144 | Chapter 6:—Advanced Object-Oriented Programming In Scala

Download at WoweBook.Com
CHAPTER 7
The Scala Object System

The Predef Object


)RU\RXUFRQYHQLHQFHZKHQHYHU\RXFRPSLOHFRGHWKH6FDODFRPSLOHUDXWRPDWLFDOO\
LPSRUWVWKHGHILQLWLRQVLQWKH java.langSDFNDJH javacGRHVWKLVWRR 2QWKH1(7
SODWIRUPLWLPSRUWVWKHsystemSDFNDJH7KHFRPSLOHUDOVRLPSRUWVWKHGHILQLWLRQVLQ
WKHDQDORJRXV6FDODSDFNDJHscala+HQFHFRPPRQ-DYDRU1(7W\SHVFDQEHXVHG
ZLWKRXWH[SOLFLWO\LPSRUWLQJWKHPRUIXOO\TXDOLI\LQJWKHPZLWKWKHjava.lang.SUHIL[
LQWKH-DYDFDVH6LPLODUO\DQXPEHURIFRPPRQ6FDODVSHFLILFW\SHVDUHPDGHDYDLODEOH
ZLWKRXWTXDOLILFDWLRQVXFKDV List:KHUHWKHUHDUH-DYDDQG6FDODW\SHQDPHVWKDW
RYHUODSOLNHStringWKH6FDODYHUVLRQLVLPSRUWHGODVWVRLW£ZLQV¤
7KHFRPSLOHUDOVRDXWRPDWLFDOO\LPSRUWVWKH PredefREMHFWZKLFKGHILQHVRULPSRUWV
VHYHUDOXVHIXOW\SHVREMHFWVDQGIXQFWLRQV

<RXFDQOHDUQDORWRI6FDODE\YLHZLQJWKHVRXUFHIRUPredef,WLVDYDLO
DEOHE\FOLFNLQJWKH£VRXUFH¤OLQNLQWKH Predef6FDODGRFSDJHRU\RX
FDQ GRZQORDG WKH IXOO VRXUFH FRGH IRU 6FDOD DW KWWSZZZVFDODODQJ
RUJ

7DEOHVKRZVDSDUWLDOOLVWRIWKHLWHPVLPSRUWHGRUGHILQHGE\ PredefRQWKH-DYD
SODWIRUP
7DEOH,WHPVLPSRUWHGRUGHILQHGE\3UHGHI
Types Character, Class, Error, Function, Integer, Map, Pair, Runnable, Set, String, Throwa
ble, Triple.
Exceptions Exception, ArrayIndexOutOfBoundsException, ClassCastException, IllegalArgumen
tException, IndexOutOfBoundsException, NoSuchElementException, NullPointerEx
ception, NumberFormatException, RuntimeException, StringIndexOutOfBoundsExcep
tion, UnsupportedOperationException.
Values Map, Set.

145

Download at WoweBook.Com
Objects Pair, Triple.
Classes Ensuring, ArrowAssoc.
Methods Factory methods to create tuples; overloaded versions of exit, error, assert, assume, and require;
implicit type conversion methods; I/O methods like readLine, println, and format; and a method
currentThread, which calls java.lang.Thread.currentThread.

PredefGHFODUHVWKHW\SHVDQGH[FHSWLRQVOLVWHGLQWKHWDEOHXVLQJWKH typeNH\ZRUG
7KH\DUHGHILQLWLRQVWKDWHTXDOWKHFRUUHVSRQGLQJ scala.<Type>RU java.lang.<Type>
FODVVHVVRWKH\EHKDYHOLNH£DOLDVHV¤RULPSRUWVIRUWKHFRUUHVSRQGLQJFODVVHV)RUH[
DPSOHStringLVGHFODUHGDVIROORZV
type String = java.lang.String

,Q WKLV FDVH WKH GHFODUDWLRQ KDV WKH VDPH QHW HIIHFW DV DQ import java.lang.String
VWDWHPHQWZRXOGKDYH
%XWGLGQ¦WZHMXVWVD\WKDWGHILQLWLRQVLQ java.langDUHLPSRUWHGDXWRPDWLFDOO\OLNH
String"7KHUHDVRQWKHUHLVDW\SHGHILQLWLRQLVWRHQDEOHVXSSRUWIRUDXQLIRUPVWULQJ
W\SHDFURVVDOOUXQWLPHHQYLURQPHQWV7KHGHILQLWLRQLVRQO\UHGXQGDQWRQWKH-90
7KHW\SHPairLVDQ£DOLDV¤IRUTuple2
type Pair[+A, +B] = Tuple2[A, B]

7KHUH DUH WZR W\SH SDUDPHWHUV A DQG B RQH IRU HDFK LWHP LQ WKH SDLU 5HFDOO IURP
£$EVWUDFW7\SHV$QG3DUDPHWHUL]HG7\SHV¤RQSDJHWKDWZHH[SODLQHGWKHPHDQLQJ
RIWKH+LQIURQWRIHDFKW\SHSDUDPHWHU
%ULHIO\DPair[A2,B2]IRUVRPHA2DQGB2LVDVXEFODVVRIPair[A1,B1]IRUVRPHA1DQG
B1LIA2LVDVXEW\SHRIA1DQGB2LVDVXEW\SHRIB1,Q£8QGHUVWDQGLQJ3DUDPHWHUL]HG
7\SHV¤RQSDJHZH¦OOGLVFXVV+DQGRWKHUW\SHTXDOLILHUVLQPRUHGHWDLO
7KHPairFODVVDOVRKDVDFRPSDQLRQREMHFWPairZLWKDQapplyIDFWRU\PHWKRGDVGLV
FXVVHGLQ£&RPSDQLRQ2EMHFWV¤RQSDJH+HQFHZHFDQFUHDWHPairLQVWDQFHVDV
LQWKLVH[DPSOH
val p = Pair(1, "one")

Pair.applyLVFDOOHGZLWKWKHWZRDUJXPHQWV7KHW\SHVADQGBVKRZQLQWKHGHILQLWLRQ
RIPairDUHLQIHUUHG$QHZTuple2LQVWDQFHLVUHWXUQHG
Map DQG Set DSSHDU LQ ERWK WKH W\SHV DQG YDOXHV OLVWV ,Q WKH YDOXHV OLVW WKH\ DUH
DVVLJQHG WKH FRPSDQLRQ REMHFWV scala.collection.immutable.Map DQG scala.collec
tion.immutable.SetUHVSHFWLYHO\+HQFH MapDQG SetLQ PredefDUHYDOXHVQRWREMHFW
GHILQLWLRQVEHFDXVHWKH\UHIHUWRREMHFWVGHILQHGHOVHZKHUHZKHUHDV PairDQG Triple
DUH GHILQHG LQ Predef LWVHOI 7KH W\SHV Map DQG Set DUH DVVLJQHG WKH FRUUHVSRQGLQJ
LPPXWDEOHFODVVHV

146 | Chapter 7:—The Scala Object System

Download at WoweBook.Com
7KHArrowAssocFODVVGHILQHVWZRPHWKRGV->DQGWKH8QLFRGHHTXLYDOHQW→7KHXWLOLW\
RIWKHVHPHWKRGVZDVGHPRQVWUDWHGSUHYLRXVO\LQ£2SWLRQ6RPHDQG1RQH$YRLGLQJ
QXOOV¤RQSDJHZKHUHZHFUHDWHGDPDSRI86VWDWHFDSLWDOV
val stateCapitals = Map(
"Alabama" -> "Montgomery",
"Alaska" -> "Juneau",
// ...
"Wyoming" -> "Cheyenne")
// ...

7KHGHILQLWLRQRIWKH ArrowAssocFODVVDQGWKH MapDQG SetYDOXHVLQ PredefPDNHWKH


FRQYHQLHQWMapLQLWLDOL]DWLRQV\QWD[SRVVLEOH)LUVWZKHQ6FDODVHHVMap(...)LWFDOOVWKH
applyPHWKRGRQWKHMapFRPSDQLRQREMHFWMXVWDVZHGLVFXVVHGIRUPair
Map.applyH[SHFWV]HURRUPRUHPairs HJ(a1, b2), (a2, b2), ... ZKHUHHDFKWXSOH
KROGVDQDPHDQGYDOXH,QWKHH[DPSOHWKHWXSOHW\SHVDUHDOOLQIHUUHGWREHRIW\SH
Pair[String,String]7KHGHFODUDWLRQRIMap.applyLVDVIROORZV
object Map {
...
def apply[A, B](elems : (A, B)*) : Map[A, B] = ...
}

5HFDOOWKDWWKHUHFDQEHQRW\SHSDUDPHWHUVRQWKHMapFRPSDQLRQREMHFWEHFDXVHWKHUH
FDQEHRQO\RQHLQVWDQFH+RZHYHUapplyFDQKDYHW\SHSDUDPHWHUV
7KHDSSO\PHWKRGWDNHVDYDULDEOHOHQJWKDUJXPHQWOLVW,QWHUQDOO\xZLOOEHDVXEW\SH
RIArray[X]6RIRU Map.applyelemsLVRIW\SHArray[(A,B)]RUArray[Tuple2[A,B]]LI
\RXSUHIHU
6RQRZWKDWZHNQRZZKDWMap.applyH[SHFWVKRZGRZHJHWIURPa -> bWR(a, b)"
Predef DOVR GHILQHV DQ LPSOLFLW W\SH FRQYHUVLRQ PHWKRG FDOOHG any2ArrowAssoc 7KH
FRPSLOHUNQRZVWKDW StringGRHVQRWGHILQHD ->PHWKRGVRLWORRNVIRUDQLPSOLFLW
FRQYHUVLRQ LQ VFRSH WR D W\SH WKDW GHILQHV VXFK D PHWKRG VXFK DV ArrowAssoc 7KH
any2ArrowAssocPHWKRGSHUIRUPVWKDWFRQYHUVLRQ,WKDVWKHIROORZLQJLPSOHPHQWDWLRQ
implicit def any2ArrowAssoc[A](x: A): ArrowAssoc[A] = new ArrowAssoc(x)

,WLVDSSOLHGWRHDFKLWHPWRWKHOHIWRIDQDUURZ ->HJWKH "Alabama"VWULQJ7KHVH


VWULQJVDUHZUDSSHGLQArrowAssocLQVWDQFHVXSRQZKLFKWKH->PHWKRGLVWKHQLQYRNHG
7KLVPHWKRGKDVWKHIROORZLQJLPSOHPHQWDWLRQ
class ArrowAssoc[A](x: A) {
...
def -> [B](y: B): Tuple2[A, B] = Tuple2(x, y)
}

:KHQLWLVLQYRNHGLWLVSDVVHGWKHVWULQJRQWKHULJKWKDQGVLGHRIWKH->7KHPHWKRG
UHWXUQVDWXSOHZLWKWKHYDOXH ("Alabama", "Montgomery")IRUH[DPSOH,QWKLVZD\
HDFKkey -> valueLVFRQYHUWHGLQWRDWXSOHDQGWKHUHVXOWLQJFRPPDVHSDUDWHGOLVWRI
WXSOHVLVSDVVHGWRWKHMap.applyIDFWRU\PHWKRG

The Predef Object | 147

Download at WoweBook.Com
7KHGHVFULSWLRQPD\VRXQGFRPSOLFDWHGDWILUVWEXWWKHEHDXW\RI6FDODLVWKDWWKLVPDS
LQLWLDOL]DWLRQV\QWD[LVQRWDQDGKRFODQJXDJHIHDWXUHVXFKDVDVSHFLDOSXUSRVHRSHU
DWRU ->GHILQHGLQWKHODQJXDJHJUDPPDU,QVWHDGWKLVV\QWD[LVGHILQHGZLWKQRUPDO
GHILQLWLRQVRIW\SHVDQGPHWKRGVFRPELQHGZLWKDIHZJHQHUDOSXUSRVHSDUVLQJFRQ
YHQWLRQVVXFKDVVXSSRUWIRULPSOLFLWV)XUWKHUPRUHLWLVDOOW\SHVDIH<RXFDQXVHWKH
VDPHWHFKQLTXHVWRZULWH\RXURZQFRQYHQLHQW£RSHUDWRUV¤IRUPLQL'RPDLQ6SHFLILF
/DQJXDJHV VHH&KDSWHU 
,PSOLFLW W\SH FRQYHUVLRQV DUH GLVFXVVHG LQ PRUH GHWDLO LQ £,PSOLFLW &RQYHU
VLRQV¤RQSDJH
1H[W UHFDOO IURP &KDSWHU  WKDW ZH ZHUH DEOH WR UHSODFH FDOOV WR
Console.println(...) ZLWK println(...) 7KLV £EDUH¤ println PHWKRG LV GHILQHG LQ
PredefWKHQLPSRUWHGDXWRPDWLFDOO\E\WKHFRPSLOHU7KHGHILQLWLRQFDOOVWKHFRUUH
VSRQGLQJPHWKRGLQ Console6LPLODUO\DOOWKHRWKHU,2PHWKRGVGHILQHGE\ Predef
HJreadLineDQGformatFDOOWKHFRUUHVSRQGLQJConsolePHWKRGV
)LQDOO\ WKH assert assume DQG require PHWKRGV DUH HDFK RYHUORDGHG ZLWK YDULRXV
DUJXPHQWOLVWRSWLRQV7KH\DUHXVHGIRUUXQWLPHWHVWLQJRIERROHDQFRQGLWLRQV,ID
FRQGLWLRQLVIDOVHDQH[FHSWLRQLVWKURZQ7KHEnsuringFODVVVHUYHVDVLPLODUSXUSRVH
<RXFDQXVHWKHVHIHDWXUHVIRU'HVLJQE\&RQWUDFWSURJUDPPLQJDVGLVFXVVHGLQ£%HWWHU
'HVLJQZLWK'HVLJQ%\&RQWUDFW¤RQSDJH
)RUWKHIXOOOLVWRIIHDWXUHVGHILQHGE\PredefVHHWKHFRUUHVSRQGLQJ6FDODGRFHQWU\LQ
>6FDOD$3,@

Four Ways to Create a Two-Item Tuple


:HQRZNQRZIRXUZD\VWRFUHDWHDWZRLWHPWXSOH WZRSOH" 
 £+HOOR¤
 3DLU £+HOOR¤
 7XSOH £+HOOR¤
 £+HOOR¤z

Classes and Objects: Where Are the Statics?


0DQ\REMHFWRULHQWHGODQJXDJHVDOORZFODVVHVWRKDYHFODVVOHYHOFRQVWDQWVILHOGVDQG
PHWKRGVFDOOHG£VWDWLF¤PHPEHUVLQ-DYD&DQG&7KHVHFRQVWDQWVILHOGVDQG
PHWKRGVDUHQRWDVVRFLDWHGZLWKDQ\LQVWDQFHVRIWKHFODVV
$QH[DPSOHRIDFODVVOHYHOILHOGLVDVKDUHGORJJLQJLQVWDQFHXVHGE\DOOLQVWDQFHVRID
FODVVIRUORJJLQJPHVVDJHV$QH[DPSOHRIDFODVVOHYHOFRQVWDQWLVWKHGHIDXOWORJJLQJ
£WKUHVKROG¤OHYHO

148 | Chapter 7:—The Scala Object System

Download at WoweBook.Com
$QH[DPSOHRIDFODVVOHYHOPHWKRGLVD£ILQGHU¤PHWKRGWKDWORFDWHVDOOLQVWDQFHVRI
WKHFODVVLQVRPHUHSRVLWRU\WKDWPDWFKVRPHXVHUVSHFLILHGFULWHULD$QRWKHUH[DPSOH
LV D IDFWRU\ PHWKRG DV XVHG LQ RQH RI WKH IDFWRU\UHODWHG GHVLJQ SDWWHUQV VHH
>*2)@ 
7RUHPDLQFRQVLVWHQWZLWKWKHJRDOWKDW£HYHU\WKLQJLVDQREMHFW¤LQ6FDODFODVVOHYHO
ILHOGVDQGPHWKRGVDUHQRWVXSSRUWHG,QVWHDG6FDODVXSSRUWVGHFODUDWLRQVRIFODVVHV
WKDW DUH VLQJOHWRQV XVLQJ WKH object NH\ZRUG LQVWHDG RI WKH class NH\ZRUG 7KH
objects SURYLGH DQ REMHFWRULHQWHG DSSURDFK WR £VWDWLF¤ GDWD DQG PHWKRGV +HQFH
6FDODGRHVQRWHYHQKDYHDstaticNH\ZRUG
ObjectsDUHLQVWDQWLDWHGDXWRPDWLFDOO\DQGOD]LO\E\WKHUXQWLPHV\VWHP VHH6HFWLRQ
RI>6FDOD6SHF@ -XVWDVIRUFODVVHVDQGWUDLWVWKHERG\RIWKH objectLVWKHFRQ
VWUXFWRUEXWVLQFHWKHV\VWHPLQVWDQWLDWHVWKHREMHFWWKHUHLVQRZD\IRUWKHXVHUWR
VSHFLI\DSDUDPHWHUOLVWIRUWKHFRQVWUXFWRUVRWKH\DUHQ¦WVXSSRUWHG$Q\GDWDGHILQHG
LQWKHREMHFWKDVWREHLQLWLDOL]HGZLWKGHIDXOWYDOXHV)RUWKHVDPHUHDVRQVDX[LOLDU\
FRQVWUXFWRUVFDQ¦WEHXVHGDQGDUHQRWVXSSRUWHG
:H¦YHDOUHDG\VHHQVRPHH[DPSOHVRIREMHFWVVXFKDVWKHspecsREMHFWVXVHGSUHYLRXVO\
IRUWHVWVDQGWKHPairW\SHDQGLWVFRPSDQLRQREMHFWZKLFKZHH[SORUHGLQ£7KH3UHGHI
2EMHFW¤RQSDJH
type Pair[+A, +B] = Tuple2[A, B]
object Pair {
def apply[A, B](x: A, y: B) = Tuple2(x, y)
def unapply[A, B](x: Tuple2[A, B]): Option[Tuple2[A, B]] = Some(x)
}

7R UHIHUHQFH DQ REMHFW ILHOG RU PHWKRG \RX XVH WKH V\QWD[ object_name.field RU
object_name.method(...)UHVSHFWLYHO\)RUH[DPSOH Pair.apply(...)1RWHWKDWWKLV
LVWKHVDPHV\QWD[WKDWLVFRPPRQO\XVHGLQODQJXDJHVZLWKVWDWLFILHOGVDQGPHWKRGV

:KHQDQREMHFWQDPHGMyObjectLVFRPSLOHGWRDFODVVILOHWKHFODVVILOH
QDPHZLOOEHMyObject$.class

,Q-DYDDQG&WKHFRQYHQWLRQIRUGHILQLQJFRQVWDQWVLVWRXVH final staticILHOGV


&DOVRKDVDconstantNH\ZRUGIRUVLPSOHILHOGVOLNHintsDQGstrings ,Q6FDODWKH
FRQYHQWLRQLVWRXVHvalILHOGVLQREMHFWV
)LQDOO\UHFDOOIURP£1HVWHG&ODVVHV¤RQSDJHWKDWFODVVGHILQLWLRQVFDQEHQHVWHG
ZLWKLQRWKHUFODVVGHILQLWLRQV7KLVSURSHUW\JHQHUDOL]HVIRUREMHFWV<RXFDQGHILQH
QHVWHGREMHFWVWUDLWVDQGFODVVHVLQVLGHRWKHUREMHFWVWUDLWVDQGFODVVHV

Classes and Objects: Where Are the Statics? | 149

Download at WoweBook.Com
Package Objects
6FDODYHUVLRQLQWURGXFHVDQHZVFRSLQJFRQVWUXFWFDOOHGSDFNDJHREMHFWV7KH\DUH
XVHGWRGHILQHW\SHVYDULDEOHVDQGPHWKRGVWKDWDUHYLVLEOHDWWKHOHYHORIWKHFRUUH
VSRQGLQJ SDFNDJH 7R XQGHUVWDQG WKHLU XVHIXOQHVV OHW¦V VHH DQ H[DPSOH IURP 6FDOD
YHUVLRQ  LWVHOI 7KH FROOHFWLRQ OLEUDU\ LV EHLQJ UHRUJDQL]HG WR UHILQH WKH SDFNDJH
VWUXFWXUHDQGWRXVHLWPRUHFRQVLVWHQWO\ DPRQJRWKHUFKDQJHV 7KH6FDODWHDPIDFHG
DGLOHPPD7KH\ZDQWHGWRPRYHW\SHVWRQHZSDFNDJHVEXWDYRLGEUHDNLQJEDFNZDUG
FRPSDWLELOLW\ 7KH package object FRQVWUXFW SURYLGHG D VROXWLRQ DORQJ ZLWK RWKHU
EHQHILWV
)RUH[DPSOHWKHLPPXWDEOHListLVGHILQHGLQWKHscalaSDFNDJHLQYHUVLRQEXWLW
LV PRYHG WR WKH scala.collection.immutable SDFNDJH LQ YHUVLRQ  'HVSLWH WKH
FKDQJHListLVPDGHYLVLEOHLQWKH scalaSDFNDJHXVLQJpackage object scalaIRXQG
LQWKHVUFOLEUDU\VFDODSDFNDJHVFDODILOHLQWKHYHUVLRQVRXUFHFRGHGLVWULEXWLRQ
1RWHWKHILOHQDPH,W¦VQRWUHTXLUHGEXWLW¦VDXVHIXOFRQYHQWLRQIRUSDFNDJHREMHFWV
+HUHLVWKHIXOOSDFNDJHREMHFWGHILQLWLRQ DWWKHWLPHRIWKLVZULWLQJLWFRXOGFKDQJH
EHIRUHWKHILQDOYHUVLRQLVUHOHDVHG 
package object scala {
type Iterable[+A] = scala.collection.Iterable[A]
val Iterable = scala.collection.Iterable

@deprecated("use Iterable instead") type Collection[+A] = Iterable[A]


@deprecated("use Iterable instead") val Collection = Iterable

type Seq[+A] = scala.collection.Sequence[A]


val Seq = scala.collection.Sequence

type RandomAccessSeq[+A] = scala.collection.Vector[A]


val RandomAccessSeq = scala.collection.Vector

type Iterator[+A] = scala.collection.Iterator[A]


val Iterator = scala.collection.Iterator

type BufferedIterator[+A] = scala.collection.BufferedIterator[A]

type List[+A] = scala.collection.immutable.List[A]


val List = scala.collection.immutable.List

val Nil = scala.collection.immutable.Nil

type ::[A] = scala.collection.immutable.::[A]


val :: = scala.collection.immutable.::

type Stream[+A] = scala.collection.immutable.Stream[A]


val Stream = scala.collection.immutable.Stream

type StringBuilder = scala.collection.mutable.StringBuilder


val StringBuilder = scala.collection.mutable.StringBuilder
}

150 | Chapter 7:—The Scala Object System

Download at WoweBook.Com
1RWHWKDWSDLUVRIGHFODUDWLRQVOLNHtype List[+] = ...DQGval List = ...DUHHIIHF
WLYHO\£DOLDVHV¤IRUWKHFRPSDQLRQFODVVDQGREMHFWUHVSHFWLYHO\%HFDXVHWKHFRQWHQWV
RIWKHscalaSDFNDJHDUHDXWRPDWLFDOO\LPSRUWHGE\WKHFRPSLOHU\RXFDQVWLOOUHIHUHQFH
DOOWKHGHILQLWLRQVLQWKLVREMHFWLQDQ\VFRSHZLWKRXWDQH[SOLFLWLPSRUWVWDWHPHQWIRU
IXOO\TXDOLILHGQDPHV
2WKHUWKDQWKHZD\WKHPHPEHUVLQSDFNDJHREMHFWVDUHVFRSHGWKH\EHKDYHMXVWOLNH
RWKHUREMHFWGHFODUDWLRQV:KLOHWKLVH[DPSOHFRQWDLQVRQO\ valVDQG typeV\RXFDQ
DOVRGHILQHPHWKRGVDQG\RXFDQVXEFODVVDQRWKHUFODVVRUWUDLWDQGPL[LQRWKHUWUDLWV
$QRWKHUEHQHILWRISDFNDJHREMHFWVLVWKDWLWSURYLGHVDPRUHVXFFLQFWLPSOHPHQWDWLRQ
RIZKDWZDVDQDZNZDUGLGLRPEHIRUH:LWKRXWSDFNDJHREMHFWV\RXZRXOGKDYHWR
SXWGHILQLWLRQVLQDQDGKRFREMHFWLQVLGHWKHGHVLUHGSDFNDJHWKHQLPSRUWIURPWKH
REMHFW)RUH[DPSOHKHUHLVKRZ ListZRXOGKDYHWREHKDQGOHGZLWKRXWDSDFNDJH
REMHFW
package scala {
object toplevel {
...
type List[+A] = scala.collection.immutable.List[A]
val List = scala.collection.immutable.List
...
}
}

...
import scala.toplevel._
...

)LQDOO\DQRWKHUEHQHILWRISDFNDJHREMHFWVLVWKHZD\WKH\SURYLGHDFOHDUVHSDUDWLRQ
EHWZHHQWKHDEVWUDFWLRQVH[SRVHGE\DSDFNDJHDQGWKHLPSOHPHQWDWLRQVWKDWVKRXOG
EHKLGGHQLQVLGHLW,QDODUJHUDSSOLFDWLRQDSDFNDJHREMHFWFRXOGEHXVHGWRH[SRVH
DOOWKHSXEOLFW\SHVYDOXHVDQGRSHUDWLRQV PHWKRGV IRUD£FRPSRQHQW¤ZKLOHHY
HU\WKLQJHOVHLQWKHSDFNDJHDQGQHVWHGSDFNDJHVFRXOGEHWUHDWHGDVLQWHUQDOLPSOH
PHQWDWLRQGHWDLOV

Sealed Class Hierarchies


5HFDOOIURP£&DVH&ODVVHV¤RQSDJHWKDWZHGHPRQVWUDWHGSDWWHUQPDWFKLQJZLWK
RXUShapesKLHUDUFK\ZKLFKXVHFDVHFODVVHV:HKDGDGHIDXOWcase _ => ...H[SUHV
VLRQ,W¦VXVXDOO\ZLVHWRKDYHRQH2WKHUZLVHLIVRPHRQHGHILQHVDQHZVXEW\SHRI
ShapeDQGSDVVHVLWWRWKLVmatchVWDWHPHQWDUXQWLPHscala.MatchErrorZLOOEHWKURZQ
EHFDXVHWKHQHZVKDSHZRQ¦WPDWFKWKHVKDSHVFRYHUHGLQWKHPDWFKVWDWHPHQW+RZ
HYHULW¦VQRWDOZD\VSRVVLEOHWRGHILQHUHDVRQDEOHEHKDYLRUIRUWKHGHIDXOWFDVH
7KHUHLVDQDOWHUQDWLYHVROXWLRQLI\RXNQRZWKDWWKHFDVHFODVVKLHUDUFK\LVXQOLNHO\WR
FKDQJHDQG\RXFDQGHILQHWKHZKROHKLHUDUFK\LQRQHILOH,QWKLVVLWXDWLRQ\RXFDQ
DGGWKHsealedNH\ZRUGWRWKHGHFODUDWLRQRIWKHFRPPRQEDVHFODVV:KHQVHDOHGWKH

Sealed Class Hierarchies | 151

Download at WoweBook.Com
FRPSLOHUNQRZVDOOWKHSRVVLEOHFODVVHVWKDWFRXOGDSSHDULQWKHmatchH[SUHVVLRQEH
FDXVHDOORIWKHPPXVWEHGHILQHGLQWKHVDPHVRXUFHILOH6RLI\RXFRYHUDOOWKRVH
FODVVHVLQWKHcaseH[SUHVVLRQV HLWKHUH[SOLFLWO\RUWKURXJKVKDUHGSDUHQWFODVVHV WKHQ
\RXFDQVDIHO\HOLPLQDWHWKHGHIDXOWcaseH[SUHVVLRQ
+HUHLVDQH[DPSOHXVLQJWKH+773PHWKRGV VHH>+773@ ZKLFKDUHQRWOLNHO\
WRFKDQJHYHU\RIWHQVRZHGHFODUHD£VHDOHG¤VHWRIFDVHFODVVHVIRUWKHP
// code-examples/ObjectSystem/sealed/http-script.scala

sealed abstract class HttpMethod()


case class Connect(body: String) extends HttpMethod
case class Delete (body: String) extends HttpMethod
case class Get (body: String) extends HttpMethod
case class Head (body: String) extends HttpMethod
case class Options(body: String) extends HttpMethod
case class Post (body: String) extends HttpMethod
case class Put (body: String) extends HttpMethod
case class Trace (body: String) extends HttpMethod

def handle (method: HttpMethod) = method match {


case Connect (body) => println("connect: " + body)
case Delete (body) => println("delete: " + body)
case Get (body) => println("get: " + body)
case Head (body) => println("head: " + body)
case Options (body) => println("options: " + body)
case Post (body) => println("post: " + body)
case Put (body) => println("put: " + body)
case Trace (body) => println("trace: " + body)
}

val methods = List(


Connect("connect body..."),
Delete ("delete body..."),
Get ("get body..."),
Head ("head body..."),
Options("options body..."),
Post ("post body..."),
Put ("put body..."),
Trace ("trace body..."))

methods.foreach { method => handle(method) }

7KLVVFULSWRXWSXWVWKHIROORZLQJ
connect: connect body...
delete: delete body...
get: get body...
head: head body...
options: options body...
post: post body...
put: put body...
trace: trace body...

152 | Chapter 7:—The Scala Object System

Download at WoweBook.Com
1RGHIDXOWFDVHLVQHFHVVDU\VLQFHZHFRYHUDOOWKHSRVVLELOLWLHV&RQYHUVHO\LI\RXRPLW
RQHRIWKHFODVVHVDQG\RXGRQ¦WSURYLGHDGHIDXOWFDVHRUDFDVHIRUDVKDUHGSDUHQW
FODVVWKHFRPSLOHUZDUQV\RXWKDWWKH£PDWFKLVQRWH[KDXVWLYH¤)RUH[DPSOHLI\RX
FRPPHQWRXWWKHFDVHIRUPut\RXJHWWKLVZDUQLQJ
warning: match is not exhaustive!
missing combination Put

def handle (method: HttpMethod) = method match {


...

<RXDOVRJHWDMatchErrorH[FHSWLRQLIDPutLQVWDQFHLVSDVVHGWRWKHPDWFK
8VLQJsealedKDVRQHGUDZEDFN(YHU\WLPH\RXDGGRUUHPRYHDFODVVIURPWKHKLHU
DUFK\\RXKDYHWRPRGLI\WKHILOHVLQFHWKHHQWLUHKLHUDUFK\KDVWREHGHFODUHGLQWKH
VDPHILOH7KLVEUHDNVWKH2SHQ&ORVHG3ULQFLSOH VHH>0H\HU@DQG>0DUWLQ@ 
ZKLFKLVDVROXWLRQWRWKHSUDFWLFDOSUREOHPWKDWLWFDQEHFRVWO\WRPRGLI\H[LVWLQJFRGH
UHWHVWLW DQGRWKHUFRGHWKDWXVHVLW DQGUHGHSOR\LW,W¦VPXFKOHVV£FRVWO\¤LI\RXFDQ
H[WHQGWKHV\VWHPE\DGGLQJQHZGHULYHGW\SHVLQVHSDUDWHVRXUFHILOHV7KLVLVZK\ZH
SLFNHGWKH+773PHWKRGKLHUDUFK\IRUWKHH[DPSOH7KHOLVWRIPHWKRGVLVYHU\VWDEOH

$YRLGsealedFDVHFODVVKLHUDUFKLHVLIWKHKLHUDUFK\FKDQJHVIUHTXHQWO\
IRUDQDSSURSULDWHGHILQLWLRQRI£IUHTXHQWO\¤ 

)LQDOO\\RXPD\KDYHQRWLFHGVRPHGXSOLFDWLRQLQWKHH[DPSOH$OOWKHFRQFUHWHFODVVHV
KDYHDbodyILHOG:K\GLGQ¦WZHSXWWKDWILHOGLQWKHSDUHQWHttpMethodFODVV"%HFDXVH
ZHGHFLGHGWRXVHFDVHFODVVHVIRUWKHFRQFUHWHFODVVHVZH¦OOUXQLQWRWKHVDPHSUREOHP
ZLWK FDVH FODVV LQKHULWDQFH WKDW ZH GLVFXVVHG LQ £&DVH &ODVV ,QKHUL
WDQFH¤RQSDJHZKHUHZHDGGHGDVKDUHGidILHOGLQWKHShapeKLHUDUFK\:HQHHG
WKHbodyDUJXPHQWIRUHDFK+773PHWKRG¦VFRQVWUXFWRU\HWLWZLOOEHPDGHDILHOGRI
HDFKPHWKRGW\SHDXWRPDWLFDOO\6RZHZRXOGKDYHWRXVHWKHoverride valWHFKQLTXH
ZHGHPRQVWUDWHGSUHYLRXVO\
:HFRXOGUHPRYHWKHFDVHNH\ZRUGVDQGLPSOHPHQWWKHPHWKRGVDQGFRPSDQLRQRE
MHFWVWKDWZHQHHG+RZHYHULQWKLVFDVHWKHGXSOLFDWLRQLVPLQLPDODQGWROHUDEOH
:KDWLIZHZDQWWRXVHFDVHFODVVHV\HWDOVRUHIHUHQFHWKH bodyILHOGLQ HttpMethod"
)RUWXQDWHO\ZHNQRZWKDW6FDODZLOOJHQHUDWHDbodyUHDGHUPHWKRGLQHYHU\FRQFUHWH
VXEFODVV DVORQJDVZHXVHWKHQDPHbodyFRQVLVWHQWO\ 6RZHFDQGHFODUHWKDWPHWKRG
DEVWUDFWLQHttpMethodWKHQXVHLWDVZHVHHILW7KHIROORZLQJH[DPSOHGHPRQVWUDWHV
WKLVWHFKQLTXH
// code-examples/ObjectSystem/sealed/http-body-script.scala

sealed abstract class HttpMethod() {


def body: String
def bodyLength = body.length

Sealed Class Hierarchies | 153

Download at WoweBook.Com
}

case class Connect(body: String) extends HttpMethod


case class Delete (body: String) extends HttpMethod
case class Get (body: String) extends HttpMethod
case class Head (body: String) extends HttpMethod
case class Options(body: String) extends HttpMethod
case class Post (body: String) extends HttpMethod
case class Put (body: String) extends HttpMethod
case class Trace (body: String) extends HttpMethod

def handle (method: HttpMethod) = method match {


case Connect (body) => println("connect: " + body)
case Delete (body) => println("delete: " + body)
case Get (body) => println("get: " + body)
case Head (body) => println("head: " + body)
case Options (body) => println("options: " + body)
case Post (body) => println("post: " + body)
case Put (body) => println("put: " + body)
case Trace (body) => println("trace: " + body)
}

val methods = List(


Connect("connect body..."),
Delete ("delete body..."),
Get ("get body..."),
Head ("head body..."),
Options("options body..."),
Post ("post body..."),
Put ("put body..."),
Trace ("trace body..."))

methods.foreach { method =>


handle(method)
println("body length? " + method.bodyLength)
}

:HGHFODUHGbodyDEVWUDFWLQHttpMethod:HDGGHGDVLPSOHbodyLengthPHWKRGWKDW
FDOOVbody7KHORRSDWWKHHQGRIWKHVFULSWFDOOV bodyLength5XQQLQJWKLVVFULSWSUR
GXFHVWKHIROORZLQJRXWSXW
connect: connect body...
body length? 15
delete: delete body...
body length? 14
get: get body...
body length? 11
head: head body...
body length? 12
options: options body...
body length? 15
post: post body...
body length? 12
put: put body...
body length? 11

154 | Chapter 7:—The Scala Object System

Download at WoweBook.Com
trace: trace body...
body length? 13

$VDOZD\VHYHU\IHDWXUHKDVSOXVHVDQGPLQXVHV&DVHFODVVHVDQGVHDOHGFODVVKLHUDU
FKLHVKDYHYHU\XVHIXOSURSHUWLHVEXWWKH\DUHQ¦WVXLWDEOHIRUDOOVLWXDWLRQV

The Scala Type Hierarchy


:HKDYHPHQWLRQHGDQXPEHURIW\SHVLQ6FDOD¦VW\SHKLHUDUFK\DOUHDG\/HW¦VORRNDW
WKHJHQHUDOVWUXFWXUHRIWKHKLHUDUFK\DVLOOXVWUDWHGLQ)LJXUH

)LJXUH6FDOD¦VW\SHKLHUDUFK\

7DEOHVDQGGLVFXVVWKHW\SHVVKRZQLQ)LJXUHDVZHOODVVRPHRWKHULP
SRUWDQWW\SHVWKDWDUHQ¦WVKRZQ6RPHGHWDLOVDUHRPLWWHGIRUFODULW\:KHQWKHXQGHU
O\LQJ£UXQWLPH¤LVGLVFXVVHGWKHSRLQWVPDGHDSSO\HTXDOO\WRWKH-90DQGWKH1(7
&/5H[FHSWZKHUHQRWHG

The Scala Type Hierarchy | 155

Download at WoweBook.Com
7DEOH$Q\$Q\9DODQG$Q\5HI
Name Parent Description
Any none The root of the hierarchy. Defines a few final methods like ==, !=, isInstanceOf[T] (for type
checking), and asInstanceOf[T] (for type casting), as well as default versions of equals,
hashCode, and toString, which are designed to be overridden by subclasses.
AnyVal Any The parent of all value types, which correspond to the primitive types on the runtime platform, plus
Unit. All the AnyVal instances are immutable value instances, and all the AnyVal types are
abstract final. Hence, none of them can be instantiated with new. Rather, new instances are
created with literal values (e.g., 3.14 for a Double) or by calling methods on instances that return
new values.
AnyRef Any The parent of all reference types, including all java.* and scala.* types. It is equivalent to
java.lang.Object for the JVM and object (System.Object) for the .NET runtime. Instances
of reference types are created with new.

7KHYDOXHW\SHVDUHFKLOGUHQRIAnyVal
7DEOH'LUHFWVXEW\SHVRI$Q\9DOWKHYDOXHW\SHV
Name Runtime primitive type
Boolean Boolean (true and false).
Byte Byte.
Char Char.
Short Short.
Int Int.
Long Long.
Float Float.
Double Double.
Unit Serves the same role as void in most imperative languages. Used primarily as a function return value.
There is only one instance of Unit, named (). Think of it as a tuple with zero items.

$OORWKHUW\SHVWKHUHIHUHQFHW\SHVDUHFKLOGUHQRIAnyRef7DEOHOLVWVVRPHRIWKH
PRUHFRPPRQO\XVHGUHIHUHQFHW\SHV1RWHWKDWWKHUHDUHVRPHVLJQLILFDQWGLIIHUHQFHV
EHWZHHQWKHYHUVLRQ;DQGFROOHFWLRQV
7DEOH'LUHFWDQGLQGLUHFWVXEW\SHVRI$Q\5HIWKHUHIHUHQFHW\SHV
Name Parent Description
Collection[+T] Iterable[T] Trait for collections of known size.
Either[+T1, +T2] AnyRef Used most often as a return type when a method could return an instance
of one of two unrelated types. For example, an exception or a “successful”
result. The Either can be pattern matched for its Left or Right
subtypes. (It is analogous to Option, with Some and None.) For the

156 | Chapter 7:—The Scala Object System

Download at WoweBook.Com
Name Parent Description
exception-handling idiom, it is conventional to use Left for the
exception.
FunctionN[-T1, -T2, AnyRef Trait representing a function that takes N arguments, each of which can
..., -TN, +R] have its own type, and returns a value of type R. (Traits are defined for
N = 0 to 22.) The variance annotations (+ and -) in front of the types will
be explained in “Variance Under Inheritance” on page 251.
Iterable[+T] AnyRef Trait with methods for operating on collections of instances. Users
implement the abstract elements method to return an Iterable
instance.
List[+T] Seq[T] sealed abstract class for ordered collections with functional-
style list semantics. It is the most widely used collection in Scala, so it is
defined in the scala package, rather than one of the collection packages.
(In Scala version2.8, it is actually defined in scala.collec
tion.immutable and “aliased” in package object scala). It
has two subclasses, case object Nil, which extends List[Noth
ing] and represents an empty list, and case final class ::
[T], which represents a non-empty list, characterized by a head element
and a tail list, which would be Nil for a one-element list.
Nothing All other types Nothing is the subtype of all other types. It has no instances. It is used
primarily for defining other types in a type-safe way, such as the special
List subtype Nil. See also “Nothing and Null” on page 267.
Null All reference types Null has one instance, null, corresponding to the runtime’s concept
of null.
Option[T] Product Wraps an optional item. It is a sealed abstract type and the only
allowed instances are an instance of its derived case class
Some[T], wrapping an instance of T, or its derived case object
None, which extends Option[Nothing].
Predef AnyRef An object that defines and imports many commonly used types and
methods. See “The Predef Object” on page 145 for details.
Product AnyRef Trait with methods for determining arity and getting the nth item in a
“Cartesian product.” Subtraits are defined for Product, called
ProductN, for dimension N from 1 through 22.
ScalaObject AnyRef Mixin trait added to all Scala reference type instances.
Seq[+T] Collection[T] Trait for ordered collections.
TupleN ProductN Separate case classes for arity N = 1 through 22. Tuples support the
literal syntax (x1, x2, ..., xN).

%HVLGHV ListVRPHRIWKHRWKHUOLEUDU\FROOHFWLRQVLQFOXGH Map Set QueueDQG Stack


7KHVHRWKHUFROOHFWLRQVFRPHLQWZRYDULHWLHVPXWDEOHDQGLPPXWDEOH7KHLPPXWDEOH
FROOHFWLRQVDUHLQWKHSDFNDJH scala.collection.immutableZKLOHWKHPXWDEOHFROOHF
WLRQVDUHLQscala.collection.mutable2QO\DQLPPXWDEOHYHUVLRQRIListLVSURYLGHG
IRUDPXWDEOHOLVWXVHD ListBufferZKLFKFDQUHWXUQD ListYLDWKH toListPHWKRG
)RU 6FDOD YHUVLRQ  WKH FROOHFWLRQV LPSOHPHQWDWLRQV UHXVH FRGH IURP

The Scala Type Hierarchy | 157

Download at WoweBook.Com
scala.collection.generic8VHUVRIWKHFROOHFWLRQVZRXOGQRUPDOO\QRWXVHDQ\W\SHV
GHILQHG LQ WKLV SDFNDJH :H¦OO H[SORUH VRPH RI WKHVH FROOHFWLRQV LQ JUHDWHU GHWDLO LQ
£)XQFWLRQDO'DWD6WUXFWXUHV¤RQSDJH
&RQVLVWHQW ZLWK LWV HPSKDVLV RQ IXQFWLRQDO SURJUDPPLQJ VHH &KDSWHU   6FDOD HQ
FRXUDJHV\RXWRXVHWKHLPPXWDEOHFROOHFWLRQVVLQFH ListLVDXWRPDWLFDOO\LPSRUWHG
DQG Predef GHILQHV W\SHV Map DQG Set WKDW UHIHU WR WKH LPPXWDEOH YHUVLRQV RI WKHVH
FROOHFWLRQV$OORWKHUFROOHFWLRQVKDYHWREHLPSRUWHGH[SOLFLWO\
PredefGHILQHVDQXPEHURILPSOLFLWFRQYHUVLRQPHWKRGVIRUWKHYDOXHW\SHV H[FOXGLQJ
Unit 7KHUHDUHLPSOLFLWFRQYHUVLRQVWRWKHFRUUHVSRQGLQJscala.runtime.RichXW\SHV
)RUH[DPSOHWKH byteWrapperPHWKRGFRQYHUWVD ByteWRD scala.runtime.RichByte
7KHUHDUHLPSOLFLWFRQYHUVLRQVEHWZHHQWKH£QXPHULF¤W\SHV¢Byte Short Int Long
DQGFloat¢WRWKHRWKHUW\SHVWKDWDUH£ZLGHU¤WKDQWKHRULJLQDO)RUH[DPSOHByteWR
IntIntWRLongIntWRDoubleHWF)LQDOO\WKHUHDUHFRQYHUVLRQVWRWKHFRUUHVSRQGLQJ
-DYDZUDSSHUW\SHVHJIntWRjava.lang.Integer:HGLVFXVVLPSOLFLWFRQYHUVLRQVLQ
PRUHGHWDLOLQ£,PSOLFLW&RQYHUVLRQV¤RQSDJH
7KHUHDUHVHYHUDOH[DPSOHVRIOptionHOVHZKHUHHJ£2SWLRQ6RPHDQG1RQH$YRLG
LQJQXOOV¤RQSDJH+HUHLVDVFULSWWKDWLOOXVWUDWHVXVLQJDQ EitherUHWXUQYDOXHWR
KDQGOHDWKURZQH[FHSWLRQRUVXFFHVVIXOUHVXOW DGDSWHGIURPKWWSGFVREUDOEORJVSRW
FRPFDWFKLQJH[FHSWLRQVKWPO 
// code-examples/ObjectSystem/typehierarchy/either-script.scala

def exceptionToLeft[T](f: => T): Either[java.lang.Throwable, T] = try {


Right(f)
} catch {
case ex => Left(ex)
}

def throwsOnOddInt(i: Int) = i % 2 match {


case 0 => i
case 1 => throw new RuntimeException(i + " is odd!")
}

for(i <- 0 to 3)
exceptionToLeft(throwsOnOddInt(i)) match {
case Left(ex) => println("Oops, got exception " + ex.toString)
case Right(x) => println(x)
}

7KH exceptionToLeftPHWKRGHYDOXDWHV f,WFDWFKHVD ThrowableDQGUHWXUQVLWDVWKH


LeftYDOXHRUUHWXUQVWKHQRUPDOUHVXOWDVWKHRightYDOXH7KHforORRSXVHVWKLVPHWKRG
WRLQYRNH throwsOnOddInt,WSDWWHUQPDWFKHVRQWKHUHVXOWDQGSULQWVDQDSSURSULDWH
PHVVDJH7KHRXWSXWRIWKHVFULSWLVWKHIROORZLQJ
0
Oops, got exception java.lang.RuntimeException: 1 is odd!
2
Oops, got exception java.lang.RuntimeException: 3 is odd!

158 | Chapter 7:—The Scala Object System

Download at WoweBook.Com
$ FunctionNWUDLWZKHUH NLVWRLVLQVWDQWLDWHGIRUDQDQRQ\PRXVIXQFWLRQZLWK
NDUJXPHQWV6RFRQVLGHUWKHIROORZLQJDQRQ\PRXVIXQFWLRQ
(t1: T1, ..., tN: TN) => new R(...)

,WLVV\QWDFWLFVXJDUIRUWKHIROORZLQJFUHDWLRQRIDQDQRQ\PRXVFODVV
new FunctionN {
def apply(t1: T1, ..., tN: TN): R = new R(...)

// other methods
}

:H¦OOUHYLVLW FunctionNLQ£9DULDQFH8QGHU,QKHULWDQFH¤RQSDJHDQG£)XQFWLRQ
7\SHV¤RQSDJH

Linearization of an Object’s Hierarchy


%HFDXVHRIVLQJOHLQKHULWDQFHWKHLQKHULWDQFHKLHUDUFK\ZRXOGEHOLQHDULIZHLJQRUHG
PL[HGLQWUDLWV:KHQWUDLWVDUHFRQVLGHUHGHDFKRIZKLFKPD\EHGHULYHGIURPRWKHU
WUDLWVDQGFODVVHVWKHLQKHULWDQFHKLHUDUFK\IRUPVDGLUHFWHGDF\FOLFJUDSK VHH>6FD
OD6SHF@ 7KHWHUPOLQHDUL]DWLRQUHIHUVWRWKHDOJRULWKPXVHGWR£IODWWHQ¤WKLVJUDSK
IRUWKHSXUSRVHVRIUHVROYLQJPHWKRGORRNXSSULRULWLHVFRQVWUXFWRULQYRFDWLRQRUGHU
ELQGLQJRIsuperHWF
,QIRUPDOO\ZHVDZLQ£6WDFNDEOH7UDLWV¤RQSDJHWKDWZKHQDQLQVWDQFHKDVPRUH
WKDQRQHWUDLWWKH\ELQGULJKWWROHIWDVGHFODUHG&RQVLGHUWKHIROORZLQJH[DPSOHRI
OLQHDUL]DWLRQ
// code-examples/ObjectSystem/linearization/linearization1-script.scala

class C1 {
def m = List("C1")
}

trait T1 extends C1 {
override def m = { "T1" :: super.m }
}

trait T2 extends C1 {
override def m = { "T2" :: super.m }
}

trait T3 extends C1 {
override def m = { "T3" :: super.m }
}

class C2 extends T1 with T2 with T3 {


override def m = { "C2" :: super.m }
}

val c2 = new C2
println(c2.m)

Linearization of an Object’s Hierarchy | 159

Download at WoweBook.Com
5XQQLQJWKLVVFULSW\LHOGVWKHIROORZLQJRXWSXW
List(C2, T3, T2, T1, C1)

7KLVOLVWRIVWULQJVEXLOWXSE\WKHmPHWKRGVUHIOHFWVWKHOLQHDUL]DWLRQRIWKHLQKHULWDQFH
KLHUDUFK\ZLWKDIHZPLVVLQJSLHFHVZH¦OOGLVFXVVVKRUWO\:H¦OODOVRVHHZK\&LVDW
WKHHQGRIWKHOLVW)LUVWOHW¦VVHHZKDWWKHLQYRFDWLRQVHTXHQFHRIWKHFRQVWUXFWRUVORRNV
OLNH
// code-examples/ObjectSystem/linearization/linearization2-script.scala

var clist = List[String]()

class C1 {
clist ::= "C1"
}

trait T1 extends C1 {
clist ::= "T1"
}

trait T2 extends C1 {
clist ::= "T2"
}

trait T3 extends C1 {
clist ::= "T3"
}

class C2 extends T1 with T2 with T3 {


clist ::= "C2"
}

val c2 = new C2
println(clist.reverse)

5XQQLQJWKLVVFULSW\LHOGVWKHIROORZLQJRXWSXW
List(C1, T1, T2, T3, C2)

6RWKHFRQVWUXFWLRQVHTXHQFHLVWKHUHYHUVH :HKDGWRUHYHUVHWKHOLVWRQWKHODVWOLQH
EHFDXVHWKHZD\LWZDVFRQVWUXFWHGSXWWKHHOHPHQWVLQWKHUHYHUVHRUGHU 7KLVLQYR
FDWLRQRUGHUPDNHVVHQVH)RUSURSHUFRQVWUXFWLRQWRRFFXUWKHSDUHQWW\SHVQHHGWR
EH FRQVWUXFWHG EHIRUH WKH GHULYHG W\SHV VLQFH D GHULYHG W\SH RIWHQ XVHV ILHOGV DQG
PHWKRGVLQWKHSDUHQWW\SHVGXULQJLWVFRQVWUXFWLRQSURFHVV
7KHRXWSXWRIWKHILUVWOLQHDUL]DWLRQVFULSWLVDFWXDOO\PLVVLQJWKUHHW\SHVDWWKHHQG7KH
IXOOOLQHDUL]DWLRQIRUUHIHUHQFHW\SHVDFWXDOO\HQGVZLWK ScalaObject AnyRefDQG Any
6RWKHOLQHDUL]DWLRQIRUC2LVDFWXDOO\
List(C2, T3, T2, T1, C1, ScalaObject, AnyRef, Any)

6FDODLQVHUWVWKHScalaObjectWUDLWDVWKHODVWPL[LQMXVWEHIRUHAnyRefDQGAnyWKDWDUH
WKHSHQXOWLPDWHDQGXOWLPDWHSDUHQWFODVVHVRIDQ\UHIHUHQFHW\SH2IFRXUVHWKHVHWKUHH

160 | Chapter 7:—The Scala Object System

Download at WoweBook.Com
W\SHVGRQRWVKRZXSLQWKHRXWSXWRIWKHVFULSWVEHFDXVHZHXVHGDQDGKRFmPHWKRG
WRILJXUHRXWWKHEHKDYLRUE\EXLOGLQJXSDQRXWSXWVWULQJ
7KH£YDOXHW\SHV¤VXEFODVVHVRIAnyValDUHDOOGHFODUHGabstract final7KHFRPSLOHU
PDQDJHVLQVWDQWLDWLRQRIWKHP6LQFHZHFDQ¦WVXEFODVVWKHPWKHLUOLQHDUL]DWLRQVDUH
VLPSOHDQGVWUDLJKWIRUZDUG
7KHOLQHDUL]DWLRQGHILQHVWKHRUGHULQZKLFKPHWKRGORRNXSRFFXUV/HW¦VH[DPLQHLW
PRUHFORVHO\
$OORXUFODVVHVDQGWUDLWVGHILQHWKHPHWKRG m7KHRQHLQ C2LVFDOOHGILUVWVLQFHWKH
LQVWDQFHLVRIWKDWW\SHC2.mFDOOVsuper.mZKLFKUHVROYHVWRT3.m7KHVHDUFKDSSHDUV
WREHEUHDGWKILUVWUDWKHUWKDQGHSWKILUVW,ILWZHUHGHSWKILUVWLWZRXOGLQYRNH C1.m
DIWHUT3.m$IWHUZDUGT3.mT2.mWKHQT1.mDQGILQDOO\C1.mDUHLQYRNHGC1LVWKHSDUHQW
RIWKHWKUHHWUDLWV)URPZKLFKRIWKHWUDLWVGLGZHWUDYHUVHWRC1"$FWXDOO\LWLVEUHDGWK
ILUVWZLWK£GHOD\HG¤HYDOXDWLRQDVZHZLOOVHH/HW¦VPRGLI\RXUILUVWH[DPSOHDQGVHH
KRZZHJRWWRC1
// code-examples/ObjectSystem/linearization/linearization3-script.scala

class C1 {
def m(previous: String) = List("C1("+previous+")")
}

trait T1 extends C1 {
override def m(p: String) = { "T1" :: super.m("T1") }
}

trait T2 extends C1 {
override def m(p: String) = { "T2" :: super.m("T2") }
}

trait T3 extends C1 {
override def m(p: String) = { "T3" :: super.m("T3") }
}

class C2 extends T1 with T2 with T3 {


override def m(p: String) = { "C2" :: super.m("C2") }
}

val c2 = new C2
println(c2.m(""))

1RZZHSDVVWKHQDPHRIWKHFDOOHURIsuper.mDVDSDUDPHWHUWKHQC1SULQWVRXWZKR
FDOOHGLW5XQQLQJWKLVVFULSW\LHOGVWKHIROORZLQJRXWSXW
List(C2, T3, T2, T1, C1(T1))

,W¦VWKHODVWRQHT1:HPLJKWKDYHH[SHFWHGT3IURPD£QDwYH¤DSSOLFDWLRQRIEUHDGWK
ILUVWWUDYHUVDO
+HUHLVWKHDFWXDODOJRULWKPIRUFDOFXODWLQJWKHOLQHDUL]DWLRQ$PRUHIRUPDOGHILQLWLRQ
LVJLYHQLQ>6FDOD6SHF@

Linearization of an Object’s Hierarchy | 161

Download at WoweBook.Com
Linearization Algorithm for Reference Types
 3XWWKHDFWXDOW\SHRIWKHLQVWDQFHDVWKHILUVWHOHPHQW
 6WDUWLQJZLWKWKHULJKWPRVWSDUHQWW\SHDQGZRUNLQJOHIWFRPSXWHWKHOLQHDUL]DWLRQ
RIHDFKW\SHDSSHQGLQJLWVOLQHDUL]DWLRQWRWKHFXPXODWLYHOLQHDUL]DWLRQ ,JQRUH
ScalaObjectAnyRefDQGAnyIRUQRZ
 :RUNLQJIURPOHIWWRULJKWUHPRYHDQ\W\SHLILWDSSHDUVDJDLQWRWKHULJKWRIWKH
FXUUHQWSRVLWLRQ
 $SSHQGScalaObjectAnyRefDQGAny

7KLVH[SODLQVKRZZHJRWWRC1IURPT1LQWKHSUHYLRXVH[DPSOHT3DQGT2DOVRKDYHLW
LQWKHLUOLQHDUL]DWLRQVEXWWKH\FRPHEHIRUHT1VRWKHC1WHUPVWKH\FRQWULEXWHGZHUH
GHOHWHG
/HW¦VZRUNWKURXJKWKHDOJRULWKPXVLQJDVOLJKWO\PRUHLQYROYHGH[DPSOH
// code-examples/ObjectSystem/linearization/linearization4-script.scala

class C1 {
def m = List("C1")
}

trait T1 extends C1 {
override def m = { "T1" :: super.m }
}

trait T2 extends C1 {
override def m = { "T2" :: super.m }
}

trait T3 extends C1 {
override def m = { "T3" :: super.m }
}

class C2A extends T2 {


override def m = { "C2A" :: super.m }
}

class C2 extends C2A with T1 with T2 with T3 {


override def m = { "C2" :: super.m }
}

def calcLinearization(obj: C1, name: String) = {


val lin = obj.m ::: List("ScalaObject", "AnyRef", "Any")
println(name + ": " + lin)
}

calcLinearization(new C2, "C2 ")


println("")
calcLinearization(new T3 {}, "T3 ")
calcLinearization(new T2 {}, "T2 ")

162 | Chapter 7:—The Scala Object System

Download at WoweBook.Com
calcLinearization(new T1 {}, "T1 ")
calcLinearization(new C2A, "C2A")
calcLinearization(new C1, "C1 ")

7KHRXWSXWLVWKHIROORZLQJ
C2 : List(C2, T3, T1, C2A, T2, C1, ScalaObject, AnyRef, Any)

T3 : List(T3, C1, ScalaObject, AnyRef, Any)


T2 : List(T2, C1, ScalaObject, AnyRef, Any)
T1 : List(T1, C1, ScalaObject, AnyRef, Any)
C2A: List(C2A, T2, C1, ScalaObject, AnyRef, Any)
C1 : List(C1, ScalaObject, AnyRef, Any)

7R KHOS XV DORQJ ZH FDOFXODWHG WKH OLQHDUL]DWLRQV IRU WKH RWKHU W\SHV DQG ZH DOVR
DSSHQGHG ScalaObject AnyRefDQG AnyWRUHPLQGRXUVHOYHVWKDWWKH\VKRXOGDOVREH
WKHUH:HDOVRUHPRYHGWKHORJLFWRSDVVWKHFDOOHU¦VQDPHWR m7KDWFDOOHURI C1ZLOO
DOZD\VEHWKHHOHPHQWWRLWVLPPHGLDWHOHIW
6ROHW¦VZRUNWKURXJKWKHDOJRULWKPIRUC2DQGFRQILUPRXUUHVXOWV:H¦OOVXSSUHVVWKH
ScalaObjectAnyRefDQGAnyIRUFODULW\XQWLOWKHHQG6HH7DEOH

7DEOH+DQGFDOFXODWLRQRI&OLQHDUL]DWLRQ&H[WHQGV&$ZLWK7ZLWK7ZLWK7^`
# Linearization Description
1 C2 Add the type of the instance.
2 C2, T3, C1 Add the linearization for T3 (farthest on the right).
3 C2, T3, C1, T2, C1 Add the linearization for T2.
4 C2, T3, C1, T2, C1, T1, C1 Add the linearization for T1.
5 C2, T3, C1, T2, C1, T1, C1, C2A, T2, C1 Add the linearization for C2A.
6 C2, T3, T2, T1, C2A, T2, C1 Remove duplicates of C1; all but the last C1.
7 C2, T3, T1, C2A, T2, C1 Remove duplicate T2; all but the last T2.
8 C2, T3, T1, C2A, T2, C1, ScalaObject, Finish!
AnyRef, Any

:KDWWKHDOJRULWKPGRHVLVSXVKDQ\VKDUHGW\SHVWRWKHULJKWXQWLOWKH\FRPHDIWHU
DOOWKHW\SHVWKDWGHULYHIURPWKHP
7U\PRGLI\LQJWKHODVWVFULSWZLWKGLIIHUHQWKLHUDUFKLHVDQGVHHLI\RXFDQUHSURGXFHWKH
UHVXOWVXVLQJWKHDOJRULWKP

2YHUO\ FRPSOH[ W\SH KLHUDUFKLHV FDQ UHVXOW LQ PHWKRG ORRNXS £VXU
SULVHV¤,I\RXKDYHWRZRUNWKURXJKWKLVDOJRULWKPWRILJXUHRXWZKDW¦V
JRLQJRQWU\WRVLPSOLI\\RXUFRGH

Linearization of an Object’s Hierarchy | 163

Download at WoweBook.Com
Recap and What’s Next
:H KDYH ILQLVKHG RXU VXUYH\ RI 6FDOD¦V REMHFW PRGHO ,I \RX FRPH IURP DQ REMHFW
RULHQWHG ODQJXDJH EDFNJURXQG \RX QRZ NQRZ HQRXJK DERXW 6FDOD WR UHSODFH \RXU
H[LVWLQJREMHFWRULHQWHGODQJXDJHZLWKREMHFWRULHQWHG6FDOD
+RZHYHUWKHUHLVPXFKPRUHWRFRPH6FDODVXSSRUWVIXQFWLRQDOSURJUDPPLQJZKLFK
RIIHUVSRZHUIXOPHFKDQLVPVIRUDGGUHVVLQJDQXPEHURIGHVLJQSUREOHPVVXFKDVFRQ
FXUUHQF\:H¦OOVHHWKDWIXQFWLRQDOSURJUDPPLQJDSSHDUVWRFRQWUDGLFWREMHFWRULHQWHG
SURJUDPPLQJDWOHDVWRQWKHVXUIDFH7KDWVDLGDJXLGLQJSULQFLSOHEHKLQG6FDODLVWKDW
WKHVHWZRSDUDGLJPVFRPSOHPHQWHDFKRWKHUPRUHWKDQWKH\FRQIOLFW&RPELQHGWKH\
JLYH\RXPRUHRSWLRQVIRUEXLOGLQJUREXVWVFDODEOHVRIWZDUH6FDODOHWV\RXFKRRVHWKH
WHFKQLTXHVWKDWZRUNEHVWIRU\RXUQHHGV

164 | Chapter 7:—The Scala Object System

Download at WoweBook.Com
CHAPTER 8
Functional Programming in Scala

(YHU\GHFDGHRUWZRDPDMRUFRPSXWLQJLGHDJRHVPDLQVWUHDP7KHVHLGHDVPD\KDYH
OXUNHGLQWKHEDFNJURXQGRIDFDGHPLFFRPSXWHUVFLHQFHUHVHDUFKRUSRVVLEO\LQVRPH
OHVVHUNQRZQILHOGRILQGXVWU\7KHWUDQVLWLRQWRPDLQVWUHDPDFFHSWDQFHFRPHVLQUH
VSRQVHWRDSHUFHLYHGSUREOHPIRUZKLFKWKHLGHDLVZHOOVXLWHG2EMHFWRULHQWHGSUR
JUDPPLQJZKLFKZDVLQYHQWHGLQWKHVZHQWPDLQVWUHDPLQWKHVDUJXDEO\
LQUHVSRQVHWRWKHHPHUJHQFHRIJUDSKLFDOXVHULQWHUIDFHVIRUZKLFKWKH223SDUDGLJP
LVDQDWXUDOILW
)XQFWLRQDOSURJUDPPLQJDSSHDUVWREHH[SHULHQFLQJDVLPLODUEUHDNRXW/RQJWKHWRSLF
RIFRPSXWHUVFLHQFHUHVHDUFKDQGHYHQROGHUWKDQREMHFWRULHQWHGSURJUDPPLQJIXQF
WLRQDOSURJUDPPLQJRIIHUVHIIHFWLYHWHFKQLTXHVIRUFRQFXUUHQWSURJUDPPLQJZKLFKLV
JURZLQJLQLPSRUWDQFH
%HFDXVHIXQFWLRQDOSURJUDPPLQJLVOHVVZLGHO\XQGHUVWRRGWKDQREMHFWRULHQWHGSUR
JUDPPLQJZHZRQ¦WDVVXPHWKDW\RXKDYHSULRUH[SHULHQFHZLWKLW:H¦OOVWDUWWKLV
FKDSWHUZLWKSOHQW\RIEDFNJURXQGLQIRUPDWLRQ$V\RX¦OOVHHIXQFWLRQDOSURJUDPPLQJ
LV QRW RQO\ D YHU\ HIIHFWLYH ZD\ WR DSSURDFK FRQFXUUHQW SURJUDPPLQJ ZKLFK ZH¦OO
H[SORUH LQ GHSWK LQ &KDSWHU  EXW IXQFWLRQDO SURJUDPPLQJ FDQ DOVR LPSURYH \RXU
REMHFWV
2IFRXUVHZHFDQ¦WSURYLGHDQH[KDXVWLYHLQWURGXFWLRQWRIXQFWLRQDOSURJUDPPLQJ7R
OHDUQPRUHDERXWLW>2¦6XOOLYDQ@KDVDPRUHGHWDLOHGLQWURGXFWLRQLQWKHFRQWH[W
RIWKH+DVNHOOODQJXDJH>$EHOVRQ@>9DQ5R\@DQG>7XUEDN@RIIHUWKRU
RXJK LQWURGXFWLRQV WR JHQHUDO SURJUDPPLQJ DSSURDFKHV LQFOXGLQJ IXQFWLRQDO SUR
JUDPPLQJ)LQDOO\>2NDVDNL@DQG>5DEKL@GLVFXVVIXQFWLRQDOGDWDVWUXFWXUHV
DQGDOJRULWKPVLQGHWDLO

What Is Functional Programming?


'RQ¦WDOOSURJUDPPLQJODQJXDJHVKDYHIXQFWLRQVRIVRPHVRUW":KHWKHUWKH\DUHFDOOHG
PHWKRGV SURFHGXUHV RU GOTOs SURJUDPPHUV DUH DOZD\V GHDOLQJ LQ IXQFWLRQV

165

Download at WoweBook.Com
)XQFWLRQDOSURJUDPPLQJLVEDVHGRQWKHEHKDYLRURIIXQFWLRQVLQWKHPDWKHPDWLFDO
VHQVHZLWKDOOWKHLPSOLFDWLRQVWKDWVWDUWLQJSRLQWLPSOLHV

Functions in Mathematics
,QPDWKHPDWLFVIXQFWLRQVKDYHQRVLGHHIIHFWV&RQVLGHUWKHFODVVLFIXQFWLRQsin(x)
y = sin(x)

1RPDWWHUKRZPXFKZRUNsin(x)GRHVDOOWKHUHVXOWVDUHUHWXUQHGDQGDVVLJQHGWRy
1RJOREDOVWDWHRIDQ\NLQGLVPRGLILHGLQWHUQDOO\E\sin(x)+HQFHZHVD\WKDWVXFK
DIXQFWLRQLVIUHHRIVLGHHIIHFWVRUSXUH
7KLVSURSHUW\VLPSOLILHVHQRUPRXVO\WKHFKDOOHQJHRIDQDO\]LQJWHVWLQJDQGGHEXJJLQJ
DIXQFWLRQ<RXFDQGRWKHVHWKLQJVZLWKRXWKDYLQJWRNQRZDQ\WKLQJDERXWWKHFRQWH[W
LQZKLFKWKHIXQFWLRQLVLQYRNHGH[FHSWIRUDQ\RWKHUIXQFWLRQVLWPLJKWFDOO+RZHYHU
\RXFDQDQDO\]HWKHPLQWKHVDPHZD\ZRUNLQJERWWRPXSWRYHULI\WKHZKROH£VWDFN¤
7KLVREOLYLRXVQHVVWRWKHVXUURXQGLQJFRQWH[WLVNQRZQDV5HIHUHQWLDO7UDQVSDUHQF\
<RXFDQFDOOVXFKDIXQFWLRQDQ\ZKHUHDQGEHFRQILGHQWWKDWLWZLOODOZD\VEHKDYHWKH
VDPH ZD\ ,I QR JOREDO VWDWH LV PRGLILHG FRQFXUUHQW LQYRFDWLRQ RI WKH IXQFWLRQ LV
VWUDLJKWIRUZDUGDQGUHOLDEOH
,QIXQFWLRQDOSURJUDPPLQJ\RXFDQFRPSRVHIXQFWLRQVIURPRWKHUIXQFWLRQV)RUH[
DPSOHtan(x) = sin(x)/cos(x)$QLPSOLFDWLRQRIFRPSRVDELOLW\LVWKDWIXQFWLRQVFDQ
EHWUHDWHGDVYDOXHV,QRWKHUZRUGVIXQFWLRQVDUHILUVWFODVVMXVWOLNHGDWD<RXFDQ
DVVLJQIXQFWLRQVWRYDULDEOHV<RXFDQSDVVIXQFWLRQVWRRWKHUIXQFWLRQV<RXFDQUHWXUQ
IXQFWLRQVDVYDOXHVIURPIXQFWLRQV,QWKHIXQFWLRQDOSDUDGLJPIXQFWLRQVEHFRPHD
SULPLWLYHW\SHDEXLOGLQJEORFNWKDW¦VMXVWDVHVVHQWLDOWRWKHZRUNRISURJUDPPLQJDV
LQWHJHUVRUVWULQJV
:KHQDIXQFWLRQWDNHVRWKHUIXQFWLRQVDVDUJXPHQWVRUUHWXUQVDIXQFWLRQLWLVFDOOHG
DKLJKHURUGHUIXQFWLRQ,QPDWKHPDWLFVWZRH[DPSOHVRIKLJKHURUGHUIXQFWLRQVIURP
FDOFXOXVDUHGHULYDWLRQDQGLQWHJUDWLRQ

Variables that Aren’t


7KHZRUG£YDULDEOH¤WDNHVRQDQHZPHDQLQJLQIXQFWLRQDOSURJUDPPLQJ,I\RXFRPH
IURPDSURFHGXUDORUREMHFWRULHQWHGSURJUDPPLQJEDFNJURXQG\RXDUHDFFXVWRPHG
WRYDULDEOHVWKDWDUHPXWDEOH,QIXQFWLRQDOSURJUDPPLQJYDULDEOHVDUHLPPXWDEOH
7KLVLVDQRWKHUFRQVHTXHQFHRIWKHPDWKHPDWLFDORULHQWDWLRQ,QWKHH[SUHVVLRQ y =
sin(x)RQFH\RXSLFNxWKHQyLVIL[HG$VDQRWKHUH[DPSOHLI\RXLQFUHPHQWWKHLQWHJHU
E\\RXGRQ¦W£PRGLI\WKHREMHFW¤\RXFUHDWHDQHZYDOXHWRUHSUHVHQW
7REHPRUHSUHFLVHLWLVWKHYDOXHVWKDWDUHLPPXWDEOH)XQFWLRQDOSURJUDPPLQJODQ
JXDJHVSUHYHQW\RXIURPDVVLJQLQJDQHZYDOXHWRDYDULDEOHWKDWDOUHDG\KDVDYDOXH

166 | Chapter 8:—Functional Programming in Scala

Download at WoweBook.Com
,PPXWDELOLW\LVGLIILFXOWZKHQ\RX¦UHQRWXVHGWRLW,I\RXFDQ¦WFKDQJHDYDULDEOHWKHQ
\RXFDQ¦WKDYHORRSFRXQWHUVIRUH[DPSOH:H¦UHDFFXVWRPHGWRREMHFWVWKDWFKDQJH
WKHLUVWDWHZKHQZHFDOOPHWKRGVRQWKHP/HDUQLQJWRWKLQNLQLPPXWDEOHWHUPVWDNHV
VRPHHIIRUW
+RZHYHULPPXWDELOLW\KDVHQRUPRXVEHQHILWVIRUFRQFXUUHQF\$OPRVWDOOWKHGLIILFXOW\
RIPXOWLWKUHDGHGSURJUDPPLQJOLHVLQV\QFKURQL]LQJDFFHVVWRVKDUHGPXWDEOHVWDWH,I
\RXUHPRYHPXWDELOLW\WKHQWKHSUREOHPVHVVHQWLDOO\JRDZD\,WLVWKHFRPELQDWLRQRI
UHIHUHQWLDOO\ WUDQVSDUHQW IXQFWLRQV DQG LPPXWDEOH YDOXHV WKDW PDNH IXQFWLRQDO SUR
JUDPPLQJFRPSHOOLQJDVDEHWWHUZD\WRZULWHFRQFXUUHQWVRIWZDUH
7KHVH TXDOLWLHV EHQHILW SURJUDPV LQ RWKHU ZD\V $OPRVW DOO WKH FRQVWUXFWV ZH KDYH
LQYHQWHGLQRGG\HDUVRIFRPSXWHUSURJUDPPLQJKDYHEHHQDWWHPSWVWRPDQDJH
FRPSOH[LW\+LJKHURUGHUIXQFWLRQVDQGUHIHUHQWLDOWUDQVSDUHQF\SURYLGHYHU\IOH[LEOH
EXLOGLQJEORFNVIRUFRPSRVLQJSURJUDPV
,PPXWDELOLW\JUHDWO\UHGXFHVUHJUHVVLRQEXJVPDQ\RIZKLFKDUHFDXVHGE\XQLQWHQ
GHGVWDWHFKDQJHVLQRQHSDUWRIDSURJUDPGXHWRLQWHQGHGFKDQJHVLQDQRWKHUSDUW
7KHUHDUHRWKHUFRQWULEXWRUVWRVXFKQRQORFDOHIIHFWVEXWPXWDELOLW\LVRQHRIWKHPRVW
LPSRUWDQW
,W¦VFRPPRQLQREMHFWRULHQWHGGHVLJQVWRHQFDSVXODWHDFFHVVWRGDWDVWUXFWXUHVLQRE
MHFWV,IWKHVHVWUXFWXUHVDUHPXWDEOHZHFDQ¦WVLPSO\VKDUHWKHPZLWKFOLHQWV:HKDYH
WRDGGVSHFLDODFFHVVRUPHWKRGVWRFRQWURODFFHVVVRFOLHQWVFDQ¦WPRGLI\WKHPRXWVLGH
RXUFRQWURO7KHVHDGGLWLRQVLQFUHDVHFRGHVL]HZKLFKLQFUHDVHVWKHWHVWLQJDQGPDLQ
WHQDQFHEXUGHQDQGWKH\LQFUHDVHWKHHIIRUWUHTXLUHGE\FOLHQWVWRXQGHUVWDQGWKHDG
KRFIHDWXUHVRIRXU$3,V
,QFRQWUDVWZKHQZHKDYHLPPXWDEOHGDWDVWUXFWXUHVPDQ\RIWKHVHSUREOHPVVLPSO\
JRDZD\:HFDQSURYLGHDFFHVVWRFROOHFWLRQVZLWKRXWIHDURIGDWDORVVRUFRUUXSWLRQ
2IFRXUVHWKHJHQHUDOSULQFLSOHVRIPLQLPDOFRXSOLQJVWLOODSSO\VKRXOGFOLHQWVFDUHLI
DSetRUListLVXVHGDVORQJforeachLVDYDLODEOH"
,PPXWDEOHGDWDDOVRLPSOLHVWKDWORWVRIFRSLHVZLOOEHPDGHZKLFKFDQEHH[SHQVLYH
)XQFWLRQDOGDWDVWUXFWXUHVRSWLPL]HIRUWKLVSUREOHP VHH>2NDVDNL@ DQGPDQ\RI
WKHEXLOWLQ6FDODW\SHVDUHHIILFLHQWDWFUHDWLQJQHZFRSLHVIURPH[LVWLQJFRSLHV
,W¦VWLPHWRGLYHLQWRWKHSUDFWLFDOLWLHVRIIXQFWLRQDOSURJUDPPLQJLQ6FDOD:H¦OOGLVFXVV
RWKHUDVSHFWVDQGEHQHILWVRIWKHDSSURDFKDVZHSURFHHG

Functional Programming in Scala


$VDK\EULGREMHFWIXQFWLRQDOODQJXDJH6FDODGRHVQRWUHTXLUHIXQFWLRQVWREHSXUH
QRUGRHVLWUHTXLUHYDULDEOHVWREHLPPXWDEOH,WGRHVKRZHYHUHQFRXUDJH\RXWRZULWH
\RXU FRGH WKLV ZD\ ZKHQHYHU SRVVLEOH <RX KDYH WKH IUHHGRP WR XVH SURFHGXUDO RU
REMHFWRULHQWHGWHFKQLTXHVZKHQDQGZKHUHWKH\VHHPPRVWDSSURSULDWH

Functional Programming in Scala | 167

Download at WoweBook.Com
7KRXJK IXQFWLRQDO ODQJXDJHV DUH DOO DERXW HOLPLQDWLQJ VLGH HIIHFWV D ODQJXDJH WKDW
QHYHUDOORZHGIRUVLGHHIIHFWVZRXOGEHXVHOHVV,QSXWDQGRXWSXW ,2 DUHLQKHUHQWO\
DERXWVLGHHIIHFWVDQG,2LVHVVHQWLDOWRDOOSURJUDPPLQJWDVNV)RUWKLVUHDVRQDOO
IXQFWLRQDOODQJXDJHVSURYLGHPHFKDQLVPVIRUSHUIRUPLQJVLGHHIIHFWVLQDFRQWUROOHG
ZD\
6FDODGRHVQ¦WUHVWULFWZKDW\RXFDQGREXWZHHQFRXUDJH\RXWRXVHLPPXWDEOHYDOXHV
DQGSXUHIXQFWLRQVDQGPHWKRGVZKHQHYHUSRVVLEOH:KHQPXWDELOLW\DQGVLGHHIIHFWV
DUHQHFHVVDU\SXUVXHWKHPLQD£SULQFLSOHG¤ZD\LVRODWHGLQZHOOGHILQHGPRGXOHVDQG
IRFXVHGRQLQGLYLGXDOWDVNV
,I\RX¦UHQHZWRIXQFWLRQDOSURJUDPPLQJNHHSLQPLQGWKDWLW¦VHDV\WRIDOOEDFNWRROG
KDELWV:HHQFRXUDJH\RXWRPDVWHUWKHIXQFWLRQDOVLGHRI6FDODDQGWROHDUQWRXVHLW
HIIHFWLYHO\

$IXQFWLRQWKDWUHWXUQVUnitLPSOLHVWKDWWKHIXQFWLRQKDVSXUHVLGHHI
IHFWVPHDQLQJWKDWLILWGRHVDQ\XVHIXOZRUNWKDWZRUNPXVWEHDOOVLGH
HIIHFWVVLQFHWKHIXQFWLRQGRHVQ¦WUHWXUQDQ\WKLQJ

:H¦YHVHHQPDQ\H[DPSOHVRIKLJKHURUGHUIXQFWLRQVDQGFRPSRVDELOLW\LQ6FDOD)RU
H[DPSOHList.mapWDNHVDIXQFWLRQWRWUDQVIRUPHDFKHOHPHQWRIWKHOLVWWRVRPHWKLQJ
HOVH
// code-examples/FP/basics/list-map-example-script.scala

List(1, 2, 3, 4, 5) map { _ * 2 }

5HFDOOWKDW_ * 2LVDIXQFWLRQOLWHUDOWKDWLVVKRUWKDQGIRUi => i * 2)RUHDFKDUJXPHQW


WRWKHIXQFWLRQ\RXFDQXVH_LIWKHDUJXPHQWLVXVHGRQO\RQFH:HDOVRXVHGWKHLQIL[
RSHUDWRUQRWDWLRQWRLQYRNH map+HUH¦VDQH[DPSOHWKDW£UHGXFHV¤WKHVDPHOLVWE\
PXOWLSO\LQJDOOWKHHOHPHQWVWRJHWKHU
// code-examples/FP/basics/list-reduceLeft-example-script.scala

List(1, 2, 3, 4, 5) reduceLeft { _ * _ }

7KHILUVW_UHSUHVHQWVWKHDUJXPHQWWKDWLVDFFXPXODWLQJWKHYDOXHRIWKHUHGXFWLRQDQG
WKHVHFRQG_UHSUHVHQWVWKHFXUUHQWHOHPHQWRIWKHOLVW
%RWK H[DPSOHV VXFFHVVIXOO\ £ORRSHG¤ WKURXJK WKH OLVW ZLWKRXW WKH XVH RI D PXWDEOH
FRXQWHUWRWUDFNLWHUDWLRQV0RVWFRQWDLQHUVLQWKH6FDODOLEUDU\SURYLGHIXQFWLRQDOO\
SXUHLWHUDWLRQPHWKRGV,QRWKHUFDVHVUHFXUVLRQLVWKHSUHIHUUHG