Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin Workshop day #2

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Kotlin Workshop day #2

Android Academy TLV - Kotlin workshop day #2

Co-created with
Eden Bugdary Machluf and Hadas Peled

Avatar for Gil Goldzweig

Gil Goldzweig

October 16, 2019
Tweet

More Decks by Gil Goldzweig

Other Decks in Programming

Transcript

  1. ▢ Workspace + git ▢ Kotlin basics - variables,null safety,

    conditions, loops, when, ranges. ▢ Functions - syntax, main, filters, lambdas. ▢ Classes - properties, getters & setters, constructors, init, visibility modifiers. 2
  2. ▢ More classes: ❏ Inheritance ❏ Abstract ❏ Interfaces ▢

    Data class ▢ Special classes ▢ Pairs ▢ Collections ▢ Operators overloading ▢ Constants ▢ Extensions & infix 3
  3. 4

  4. 5

  5. class IceCream(var flavor:String="Vanilla",var cone:Boolean=true){ val cup = !cone val base

    = if(cup) "cup" else "cone" constructor(topping :String): this(){ cone = false } } 6
  6. 7

  7. class IceCream(var flavor:String="Vanilla",var cone:Boolean=true){ val cup = !cone val base

    = if(cup) "cup" else "cone" //.. } class PizuzIceCream(): IceCream{ //.. } 9
  8. class IceCream(var flavor:String="Vanilla",var cone:Boolean=true){ val cup = !cone val base

    = if(cup) "cup" else "cone" //.. } class PizuzIceCream(): IceCream{ //.. } 10
  9. class IceCream(var flavor:String="Vanilla",var cone:Boolean=true){ val cup = !cone val base

    = if(cup) "cup" else "cone" //.. } class PizuzIceCream(): IceCream{ //.. } 11
  10. class IceCream(var flavor:String="Vanilla",var cone:Boolean=true){ val cup = !cone val base

    = if(cup) "cup" else "cone" //.. } class PizuzIceCream(): IceCream{ //.. } open 12
  11. open class IceCream(var flavor:String="Vanilla",var cone:Boolean=true){ val cup = !cone val

    base = if(cup) "cup" else "cone" //.. } class PizuzIceCream(): IceCream{ override val cup = true //.. } 13
  12. open class IceCream(var flavor:String="Vanilla",var cone:Boolean=true){ val cup = !cone val

    base = if(cup) "cup" else "cone" //.. } open class PizuzIceCream(): IceCream{ override val cup = true addOreos() } 14
  13. open class IceCream(var flavor:String="Vanilla",var cone:Boolean=true){ val cup = !cone val

    base = if(cup) "cup" else "cone" //.. } class PizuzIceCream(): IceCream{ override val cup = true addOreos() } open 15
  14. open class IceCream(var flavor:String="Vanilla",var cone:Boolean=true){ open val cup = !cone

    val base = if(cup) "cup" else "cone" //.. } class PizuzIceCream(): IceCream{ override val cup = true addOreos() } 16
  15. 17

  16. 18

  17. abstract class PersonName { abstract val firstName: String val lastName:

    String = "Shmupidoo" abstract fun eat() fun drink() { println("drinking") } } 23
  18. abstract class PersonName(var nickName: String) { abstract val firstName: String

    val lastName: String = "Shmupidoo" abstract fun eat() fun drink() { println("drinking") } } 24
  19. abstract class PersonName { abstract val firstName: String } class

    Person(name: String): PersonName() { override val firstName: String = name } 26
  20. abstract class PersonName { abstract val firstName: String } class

    Person(name: String): PersonName() { override val firstName: String = name } 27
  21. abstract class PersonName { abstract val firstName: String } class

    Person(name: String): PersonName() { override val firstName: String = name } 28
  22. abstract class PersonName { abstract val firstName: String } class

    Person(name: String): PersonName() { override val firstName: String = name } 29
  23. abstract class PersonName { abstract val firstName: String } class

    Person(name: String): PersonName() { override val firstName: String = name } 30
  24. abstract class PersonName { abstract val firstName: String } class

    Person(name: String): PersonName() { override val firstName: String = name } 31
  25. abstract class PersonName { abstract val firstName: String } class

    Person(name: String): PersonName() { override val firstName: String = name } val person = Person("Rafi") 32
  26. 33

  27. interface PersonAction { fun talk(saying: String) val firstName: String val

    lastName: String get() = "Shmupidoo" fun drink() { println("drinking") } } 42
  28. interface PersonAction { fun talk(saying: String) } abstract class PersonName

    { abstract val firstName: String } class Person(name: String): PersonName() { override val firstName: String = name } 44
  29. interface PersonAction { fun talk(saying: String) } abstract class PersonName

    { abstract val firstName: String } class Person(name: String): PersonName() { override val firstName: String = name } 45
  30. interface PersonAction { fun talk(saying: String) } abstract class PersonName

    { abstract val firstName: String } class Person(name: String): PersonName() { override val firstName: String = name } 46
  31. interface PersonAction { fun talk(saying: String) } abstract class PersonName

    { abstract val firstName: String } class Person(name: String): PersonName(), PersonAction { override val firstName: String = name } 47
  32. interface PersonAction { fun talk(saying: String) } abstract class PersonName

    { abstract val firstName: String } class Person(name: String): PersonName(), PersonAction { override val firstName: String = name override fun talk(saying: String){ println(saying) } } 48
  33. interface PersonAction { fun talk(saying: String) } abstract class PersonName

    { abstract val firstName: String } class Person(name: String): PersonName(), PersonAction { override val firstName: String = name override fun talk(saying: String){ println(saying) } } 49
  34. 50

  35. Is when you use an instance of another class as

    opposed to inheriting from it. 55
  36. let’s you add features to a class while using an

    instance of another class as opposed to inheriting from it. 56
  37. interface Color { val color: String } class JellyBean(): Color

    { override val color: String = "Red" } object Red: Color { override val color = "Red" } 57
  38. interface Color { val color: String } class JellyBean(): Color

    { override val color: String = "Red" } object Red: Color { override val color = "Red" } 58
  39. interface Color { val color: String } class JellyBean(): Color

    { override val color: String = "Red" } object Red: Color { override val color = "Red" } 59
  40. interface Color { val color: String } class JellyBean(): Color

    { override val color: String = "Red" } object Red: Color { override val color = "Red" } 60
  41. interface Color { val color: String } class JellyBean(): Color

    { override val color: String = "Red" } object Red: Color { override val color = "Red" } 61
  42. interface Color { val color: String } class JellyBean(): Color

    { override val color: String = "Red" } object Red: Color { override val color = "Red" } 62
  43. interface Color { val color :String } class JellyBean(): Color

    { override val color :String = "Red" } object Red: Color { override val color = "Red" } 63
  44. interface Color { val color :String } class JellyBean(): Color

    { override val color :String = "Red" } object Red: Color{ override val color = "Red" } 64
  45. interface Color { val color :String } class JellyBean(): Color

    { override val color :String = "Red" } object Red: Color { override val color = "Red" } 65
  46. interface Color { val color :String } class JellyBean(): Color

    { override val color :String = "Red" } object Red: Color { override val color = "Red" } 66
  47. interface Color { val color: String } class JellyBean(): Color

    { override val color: String = "Red" } object Red: Color { override val color = "Red" } 67
  48. interface Color { val color: String } class JellyBean(): Color

    { override val color: String = "Red" } object Red: Color { override val color = "Red" } 68
  49. interface Color { val color: String } class JellyBean(): Color

    by Red object Red: Color { override val color = "Red" } 69
  50. interface Color { val color: String } class JellyBean(): Color

    by Red object Red: Color { override val color = "Red" } 70
  51. interface Color { val color: String } class JellyBean(): Color

    by Red object Red: Color { override val color = "Red" } val jellyOne = JellyBean() 71
  52. interface Color { val color: String } class JellyBean(): Color

    by Red object Red: Color { override val color = "Red" } val jellyOne = JellyBean() val jellyTwo = JellyBean() 72
  53. interface Color { val color: String } class JellyBean(): Color

    by Red object Red: Color { override val color = "Red" } val jellyOne = JellyBean() val jellyTwo = JellyBean() val jellyThree = JellyBean() 73
  54. interface Color { val color: String } class JellyBean(): Color

    by Red object Red: Color { override val color = "Red" } val jellyOne = JellyBean() val jellyTwo = JellyBean() val jellyThree = JellyBean() 74
  55. 75

  56. interface Color { val color: String } class JellyBean(): Color

    by Red object Red: Color { override val color = "Red" } 76
  57. interface Color { val color: String } class JellyBean(jBColor: Color):

    Color by Red object Red: Color { override val color = "Red" } 77
  58. interface Color { val color: String } class JellyBean(jBColor: Color

    = Red): Color by Red object Red: Color { override val color = "Red" } 78
  59. interface Color { val color: String } class JellyBean(jBColor: Color

    = Red): Color by Red object Red: Color { override val color = "Red" } 79
  60. interface Color { val color: String } class JellyBean(jBColor: Color

    = Red): Color by jBColor object Red: Color { override val color = "Red" } 80
  61. interface Color { val color: String } class JellyBean(jBColor: Color

    = Red): Color by jBColor object Red:Color { override val color = "Red" } 81
  62. object Red: Color { override val color = "Red" }

    object Yellow: Color { override val color = "Yellow" } object Blue: Color { override val color = "Blue" } 82
  63. object Red: Color { override val color = "Red" }

    object Yellow: Color { override val color = "Yellow" } object Blue: Color { override val color = "Blue" } 83
  64. object Red: Color { override val color = "Red" }

    object Yellow: Color { override val color = "Yellow" } object Blue: Color { override val color = "Blue" } 84
  65. class JellyBean(jBColor: Color = Red): Color by jBColor val redJelly

    = JellyBean() val yellowJelly = JellyBean(Yellow) 87
  66. class JellyBean(jBColor: Color = Red): Color by jBColor val redJelly

    = JellyBean() val yellowJelly = JellyBean(Yellow) val blueJelly = JellyBean(Blue) 88
  67. The compiler automatically derives the following members from all properties

    declared in the primary constructor: • toString() • componentN() functions • equals() / hashCode() pair • copy() function 94
  68. val myOrder = Order(1, "Vanilla") val orderNum = myOrder.component1() //

    orderNum: Int = 1 val flavor = myOrder.component2() 101
  69. val myOrder = Order(1, "Vanilla") val orderNum = myOrder.component1() val

    flavor = myOrder.component2() // flavor: String = Vanilla 102
  70. val firstOrder = Order(1, "Vanilla") firstOrder.name = "Hadas" val secondOrder

    = Order(1, "Vanilla") secondOrder.name = "Gil" 104
  71. val firstOrder = Order(1, "Vanilla") firstOrder.name = "Hadas" val secondOrder

    = Order(1, "Vanilla") secondOrder.name = "Gil" 105
  72. val firstOrder = Order(1, "Vanilla") firstOrder.name = "Hadas" val secondOrder

    = Order(1, "Vanilla") secondOrder.name = "Gil" 106
  73. val firstOrder = Order(1, "Vanilla") firstOrder.name = "Hadas" val secondOrder

    = Order(1, "Vanilla") secondOrder.name = "Gil" 107
  74. val firstOrder = Order(1, "Vanilla") firstOrder.name = "Hadas" val secondOrder

    = Order(1, "Vanilla") secondOrder.name = "Gil" println( firstOrder.equals(secondOrder) ) 108
  75. val firstOrder = Order(1, "Vanilla") firstOrder.name = "Hadas" val secondOrder

    = Order(1, "Vanilla") secondOrder.name = "Gil" println( firstOrder.equals(secondOrder) )// true or false ?? 109
  76. val firstOrder = Order(1, "Vanilla") firstOrder.name = "Hadas" val secondOrder

    = Order(1, "Vanilla") secondOrder.name = "Gil" println( firstOrder.equals(secondOrder) )// true or false ?? 110
  77. val myOrder = Order(1, "Vanilla") val brandNewOrder = myOrder.copy(flavor =

    "Caramel") println(myOrder) println(brandNewOrder) //Order(orderNum=1, flavor=Vanilla) //Order(orderNum=1, flavor=Caramel) 117
  78. val myOrder = Order(1, "Chocolate") val (orderNum, flavor) = myOrder

    println("The best order is #$orderNum, I love $flavor") //The best order is #1, I love Chocolate 118
  79. val myOrder = Order(1, "Chocolate") val (orderNum, flavor) = myOrder

    println("The best order is #$orderNum, I love $flavor") //The best order is #1, I love Chocolate 119
  80. val myOrder = Order(1, "Chocolate") val (orderNum, flavor) = myOrder

    println("The best order is #$orderNum, I love $flavor") //The best order is #1, I love Chocolate 120
  81. val myOrder = Order(1, "Chocolate") val (orderNum, flavor) = myOrder

    println("The best order is #$orderNum, I love $flavor") //The best order is #1, I love Chocolate 121
  82. • The primary constructor needs to have at least one

    parameter • All primary constructor parameters need to be marked as val or var • Data classes cannot be abstract, open, sealed or inner 122
  83. 123

  84. 124

  85. object Configuration { fun registerDataProvider() { /** */ } }

    Configuration.registerDataProvider(...) 128
  86. object Configuration { fun registerDataProvider() { /** */ } }

    Configuration.registerDataProvider(...) Called directly 129
  87. • Objects are thread safe • Objects are lazily initialized

    • Functions and variables inside are called directly, just like static 130
  88. 131

  89. enum class Direction { NORTH, SOUTH, WEST, EAST } enum

    class Color(val rgb: Int) { RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF) } 133
  90. fun printBestSource(topping: Toppings) { when (topping) { Toppings.CHOCOLATE -> println("Melting

    Chocolate") Toppings.STRAWBERRY -> println("From fruit") Toppings.CARAMEL -> println("Hershey's Caramel Syrup") Toppings.BLOOD -> println("Humans?") } } 136
  91. fun log(logger: Loggers, data: Any) { when (logger) { Loggers.INFO

    -> println("INFO: $data") Loggers.DEBUG -> println("DEBUG: $data") } } 141
  92. fun log(logger: Loggers, data: Any) { when (logger) { Loggers.INFO

    -> println("INFO: $data") Loggers.DEBUG -> println("DEBUG: $data") Loggers.ERROR -> println("ERROR: $data") } } 142
  93. 147

  94. interface Logger { fun log(data: Any) } enum class Loggers

    : Logger { INFO { override fun log(data: Any) = print("INFO: $data") }, DEBUG, ERROR } 152
  95. interface Logger { fun log(data: Any) } enum class Loggers

    : Logger { INFO { override fun log(data: Any) = print("INFO: $data") }, DEBUG { override fun log(data: Any) = print("DEBUG: $data") }, ERROR } 153
  96. interface Logger { fun log(data: Any) } enum class Loggers

    : Logger { INFO { override fun log(data: Any) = print("INFO: $data") }, DEBUG { override fun log(data: Any) = print("DEBUG: $data") }, ERROR { override fun log(data: Any) = print("ERROR: $data") } } 154
  97. interface Logger { fun log(data: Any) } enum class Loggers

    : Logger { INFO { override fun log(data: Any) = print("INFO: $data") }, DEBUG { override fun log(data: Any) = print("DEBUG: $data") }, ERROR { override fun log(data: Any) = print("ERROR: $data") } } 155
  98. interface Logger … enum class Loggers : Logger … fun

    main() { Loggers.INFO.log("me!!!") } 157
  99. interface Logger … enum class Loggers : Logger … fun

    main() { Loggers.INFO.log("me!!!") // prints -> INFO: me!!! } 158
  100. fun parseResponse(response: Response): String { return when (response) { is

    SuccessfulResponse -> "Success" is ErrorResponse -> "Error" } } 160
  101. 166

  102. val sameType = Pair ("I am String", "me too") val

    withNull = Pair ("I am String", null) 170
  103. val sameType = Pair ("I am String", "me too") val

    withNull = Pair ("I am String", null) val differentType = Pair (10, "I am String") 171
  104. val sameType = Pair ("I am String", "me too") val

    withNull = Pair ("I am String", null) val differentType = Pair (10, "I am String") 172
  105. val sameType = Pair ("I am String", "me too") val

    withNull = Pair ("I am String", null) val differentType = Pair (10, "I am String") 173
  106. val sameType = "I am String" to "me too" val

    withNull = "I am String" to null val differentType = 10 to "I am String" 174
  107. 175

  108. 178

  109. val breakfast = "cereal" to "milk" val cereal = breakfast.first

    By constructure Pair(first: A, second: B) 183
  110. val breakfast = "cereal" to "milk" val cereal = breakfast.first

    By constructure Pair(first: A, second: B) 184
  111. val breakfast = "cereal" to "milk" val cereal = breakfast.first

    val milk = breakfast.second By constructure Pair(first: A, second: B) 185
  112. val breakfast = "cereal" to "milk" val cereal = breakfast.first

    val milk = breakfast.second By constructure Pair(first: A, second: B) 186
  113. val breakfast = "cereal" to "milk" val cereal = breakfast.component1()

    val milk = breakfast.component2() By componentN 191
  114. val breakfast = "cereal" to "milk" val cereal = breakfast.component1()

    val milk = breakfast.component2() By componentN 192
  115. val breakfast = "cereal" to "milk" val breakfastString = breakfast.toString()

    val breakfastList: List<String> = breakfast.toList() 201
  116. val breakfast = "cereal" to "milk" val breakfastString = breakfast.toString()

    val breakfastList: List<String> = breakfast.toList() 202
  117. 203

  118. val breakfast = "cereal" to "milk" to "eggs" to "orange

    juice" (((cereal, milk), eggs), orange juice) 205
  119. val breakfast = "cereal" to "milk" to "eggs" to "orange

    juice" (((cereal, milk), eggs), orange juice) println(breakfast.first) 206
  120. val breakfast = "cereal" to "milk" to "eggs" to "orange

    juice" (((cereal, milk), eggs), orange juice) println(breakfast.first) ((cereal, milk), eggs) 207
  121. val breakfast = "cereal" to "milk" to "eggs" to "orange

    juice" (((cereal, milk), eggs), orange juice) println(breakfast.first) ((cereal, milk), eggs) breakfast.first 208
  122. val breakfast = "cereal" to "milk" to "eggs" to "orange

    juice" (((cereal, milk), eggs), orange juice) println(breakfast.first) ((cereal, milk), eggs) breakfast.second 209
  123. val breakfast = "cereal" to "milk" to "eggs" to "orange

    juice" (((cereal, milk), eggs), orange juice) println(breakfast.first.second) 210
  124. val breakfast = "cereal" to "milk" to "eggs" to "orange

    juice" (((cereal, milk), eggs), orange juice) println(breakfast.first.second) 211
  125. val breakfast = "cereal" to "milk" to "eggs" to "orange

    juice" breakfast.first breakfast.first.first 213
  126. val breakfast = "cereal" to "milk" to "eggs" to "orange

    juice" breakfast.first breakfast.first.first breakfast.first.second 214
  127. val breakfast = ("cereal" to "milk") to ("eggs" to "orange

    juice") breakfast.first breakfast.second 218
  128. val breakfast = ("cereal" to "milk") to ("eggs" to "orange

    juice") breakfast.first.second??? breakfast.first breakfast.second 219
  129. val breakfast = ("cereal" to "milk") to ("eggs" to "orange

    juice") breakfast.first breakfast.first.first 221
  130. val breakfast = ("cereal" to "milk") to ("eggs" to "orange

    juice") breakfast.first breakfast.first.first breakfast.first.second 222
  131. 223

  132. class IceCream(var flavor: String = "Vanilla",var cone: Boolean = true)

    fun findBestIceCream(iceCreams: List<IceCream>) 226
  133. class IceCream(var flavor: String = "Vanilla",var cone: Boolean = true)

    fun findBestIceCream(iceCreams: List<IceCream>): IceCream 227
  134. class IceCream(var flavor: String = "Vanilla",var cone: Boolean = true)

    fun findBestIceCream(iceCreams: List<IceCream>): IceCream { val result = IceCream() } 228
  135. class IceCream(var flavor: String = "Vanilla",var cone: Boolean = true)

    fun findBestIceCream(iceCreams: List<IceCream>): IceCream { val result = IceCream() for(iceCream in iceCreams) { // secret algorithm } return result } 229
  136. class IceCream(var flavor: String = "Vanilla",var cone: Boolean = true)

    fun findBestIceCream(iceCreams: List<IceCream>): IceCream { val result = IceCream() for(iceCream in iceCreams) { // secret algorithm } return result } 230
  137. class IceCream(var flavor: String = "Vanilla",var cone: Boolean = true)

    fun findBestIceCream(iceCreams: List<IceCream>): IceCream { val result = IceCream() for(iceCream in iceCreams) { // secret algorithm } return result } 231
  138. class IceCream(var flavor: String = "Vanilla",var cone: Boolean = true)

    fun findBestIceCream(iceCreams: List<IceCream>): IceCream { val result = IceCream() for(iceCream in iceCreams) { // secret algorithm } return result } 232
  139. class IceCream(var flavor: String = "Vanilla",var cone: Boolean = true)

    fun findBestIceCream(iceCreams: List<IceCream>): IceCream { val result = IceCream() var score = 0 for(iceCream in iceCreams) { // secret algorithm } return result } 233
  140. class IceCream(var flavor: String = "Vanilla",var cone: Boolean = true)

    fun findBestIceCream(iceCreams: List<IceCream>): Pair<IceCream, Int> { val result = IceCream() var score = 0 for(iceCream in iceCreams) { // secret algorithm } return result to score } 234
  141. 235

  142. • groups of a variable number of items. • The

    Kotlin Standard Library provides implementations for basic collection types: sets, lists, and maps. • Each type have two options: ◦ A read-only interface. ◦ Mutable interface with write operations. 236
  143. val list = listOf(1, 5, 3, 4) val mutableList =

    mutableListOf("an", "d", "ro", "id") 238
  144. val list = listOf(1, 5, 2, 4) var sum =

    0 for (it in list){ sum = sum+it } println(sum) //12 239
  145. val mutableList = mutableListOf("an", "d", "ro", "id") mutableList.add("academy") It’s good

    style to use listOf, but mutableListOf is there when you need it. 248
  146. val droidList = listOf("an", "d", "ro", "id") val result =

    mutableListOf<String>() for (i in droidList.size - 1 downTo 0) { result.add(droidList[i]) } println(result) //[id, ro, d, an] 252
  147. val droidList = listOf("an", "d", "ro", "id") val result =

    mutableListOf<String>() for (i in droidList.size - 1 downTo 0) { result.add(droidList[i]) } println(result) //[id, ro, d, an] 253
  148. val droidList = listOf("an", "d", "ro", "id") val result =

    mutableListOf<String>() for (i in droidList.size - 1 downTo 0) { result.add(droidList[i]) } println(result) //[id, ro, d, an] 254
  149. val droidList = listOf("an", "d", "ro", "id") val result =

    mutableListOf<String>() for (i in droidList.size - 1 downTo 0) { result.add(droidList[i]) } println(result) //[id, ro, d, an] 255
  150. val droidList = listOf("an", "d", "ro", "id") val result =

    mutableListOf<String>() for (i in droidList.size - 1 downTo 0) { result.add(droidList[i]) } println(result) //[id, ro, d, an] 256
  151. val droidList = listOf("an", "d", "ro", "id") val result =

    mutableListOf<String>() for (i in droidList.size - 1 downTo 0) { result.add(droidList[i]) } println(result) //[id, ro, d, an] 257
  152. val droidList = listOf("an", "d", "ro", "id") val result =

    mutableListOf<String>() for (i in droidList.size - 1 downTo 0) { result.add(droidList[i]) } println(result) //[id, ro, d, an] 258
  153. 263

  154. 264

  155. val languagesMap = mapOf( "USA" to "English", "Spain" to "Spanish",

    "Politics" to "Bull*hit" ) languagesMap.get("USA") 269
  156. val languagesMap = mapOf( "USA" to "English", "Spain" to "Spanish",

    "Politics" to "Bull*hit" ) languagesMap.get("USA") languagesMap["USA"] 270
  157. val languagesMap = mapOf( "USA" to "English", "Spain" to "Spanish",

    "Politics" to "Bull*hit" ) languagesMap.get("USA") languagesMap["USA"] languagesMap.getOrDefault("USA", "Hebrew") 271
  158. val languagesMap = mapOf( "USA" to "English", "Spain" to "Spanish",

    "Politics" to "Bull*hit" ) languagesMap.get("USA") languagesMap["USA"] languagesMap.getOrDefault("USA", "Hebrew") languagesMap.getOrElse("USA") { "Greek" } 272
  159. val languagesMap = mapOf( "USA" to "English", "Spain" to "Spanish",

    "Politics" to "Bull*hit" ) languagesMap.get("USA") languagesMap["USA"] languagesMap.getOrDefault("USA", "Hebrew") languagesMap.getOrElse("USA") { "Greek" } 273
  160. val languagesMap = mapOf( // -> ImmutableMap "USA" to "English",

    "Spain" to "Spanish", "Politics" to "Bull*hit" ) 276
  161. val languagesMap = mutableMapOf( "USA" to "English", "Spain" to "Spanish",

    "Politics" to "Bull*hit" ) languagesMap.put("China", "Mandarin") 278
  162. val languagesMap = mutableMapOf( "USA" to "English", "Spain" to "Spanish",

    "Politics" to "Bull*hit" ) languagesMap.put("China", "Mandarin") languagesMap["China"] = "Mandarin" 279
  163. val languagesMap = mutableMapOf( "USA" to "English", "Spain" to "Spanish",

    "Politics" to "Bull*hit" ) languagesMap.put("China", "Mandarin") languagesMap["China"] = "Mandarin" languagesMap.remove("China") 280
  164. // Let’s create a basic book class,with a title,author and

    year. class Book(val title: String, val author: String, val year: Int) 282
  165. // Create a method that returns both the title and

    the author as a Pair. class Book(val title: String, val author: String, val year: Int){ fun getTitleAndAuthor(): Pair<String,String>{ return Pair(title, author) } } 283
  166. // Create a method that returns the title, author and

    year as a Triple. class Book(val title: String, val author: String, val year: Int){ fun getTitleAndAuthor(): Pair<String,String>{ return Pair(title, author) } fun getTitleAndAuthorAndYear(): Triple<String,String, Int>{ return Triple(title, author, year) } } 284
  167. // Create a book instance. fun main() { val book

    = Book("Orlando", "Virginia Woolf", 1928) } 285
  168. // Print out the information about the book in a

    sentence fun main() { val book = Book("Orlando", "Virginia Woolf", 1928) val (title, author, year) = book.getTitleAndAuthorAndYear() println("Here is your book $title written by $author in $year.") } 286
  169. // Print out the information about the book in a

    sentence fun main() { val book = Book("Orlando", "Virginia Woolf", 1928) val (title, author, year) = book.getTitleAndAuthorAndYear() println("Here is your book $title written by $author in $year.") } 287
  170. 288

  171. 289

  172. 292

  173. • const val - The value is always determined at

    compile time • val - The value that is assigned can be determined during programing execution. 296
  174. class IceCream(val flavor: String = "Vanilla", val cone: Boolean =

    true){ ... } const val DEFAULT_FLAVOR: String = "Vanilla" 300
  175. class IceCream(val flavor: String = DEFAULT_FLAVOR, val cone: Boolean =

    true){ ... } const val DEFAULT_FLAVOR: String = "Vanilla" 301
  176. • Top level • Inside an object object Constants {

    const val two = 2 } const val 306
  177. • Top level • Inside an object • Inside a

    class inside a companion object const val 307
  178. • Top level • Inside an object • Inside a

    class inside a companion object class MyClass{ companion object{ const val myConst = 42 } } const val 308
  179. 309

  180. • Companion objects - initialized from the static constructor of

    the containing class. • objects - initialized lazily on the first access to that object. 310
  181. • Companion objects - initialized from the static constructor of

    the containing class. • objects - initialized lazily on the first access to that object. 311
  182. class IceCream(val flavor: String = DEFAULT_FLAVOR, val cone: Boolean =

    true) { ... } const val DEFAULT_FLAVOR: String = "Vanilla" 312
  183. class IceCream(val flavor: String = DEFAULT_FLAVOR, val cone: Boolean =

    true) { ... companion object { const val DEFAULT_FLAVOR: String = "Vanilla" } } 313
  184. class IceCream(val flavor: String = DEFAULT_FLAVOR, val cone: Boolean =

    true) { ... companion object { const val DEFAULT_FLAVOR: String = "Vanilla" } } 314
  185. class IceCream(val flavor: String = DEFAULT_FLAVOR, val cone: Boolean =

    true) { ... companion object { const val DEFAULT_FLAVOR: String = "Vanilla" } } object Flavors { const val VANILLA: String = "Vanilla" } 315
  186. class IceCream(val flavor: String = DEFAULT_FLAVOR, val cone: Boolean =

    true) { ... companion object { const val DEFAULT_FLAVOR: String = "Vanilla" } } object Flavors { const val VANILLA: String = "Vanilla" } 316
  187. class IceCream(val flavor: String = DEFAULT_FLAVOR, val cone: Boolean =

    true) { ... companion object { const val DEFAULT_FLAVOR: String = Flavors.VANILLA } } object Flavors { const val VANILLA: String = "Vanilla" } 317
  188. 318

  189. fun swap(list: MutableList<Int>, index1: Int, index2: Int) { val tmp

    = list[index1] list[index1] = list[index2] list[index2] = tmp } 322
  190. Kotlin provides the ability to extend a class with new

    functionality without having to inherit from the class or use a design patterns such as Decorator. Kotlin provides this ability using two methods. • Extension function • Extension property 331
  191. fun swap(list: MutableList<Int>, index1: Int, index2: Int) { val tmp

    = list[index1] list[index1] = list[index2] list[index2] = tmp } 332
  192. fun swap(list: MutableList<Int>, index1: Int, index2: Int) { val tmp

    = list[index1] list[index1] = list[index2] list[index2] = tmp } 333
  193. fun swap(index1: Int, index2: Int) { val tmp = list[index1]

    list[index1] = list[index2] list[index2] = tmp } 334
  194. fun MutableList<Int> swap(index1: Int, index2: Int) { val tmp =

    list[index1] list[index1] = list[index2] list[index2] = tmp } 335
  195. fun MutableList<Int>.swap(index1: Int, index2: Int) { val tmp = list[index1]

    list[index1] = list[index2] list[index2] = tmp } 336
  196. fun MutableList<Int>.swap(index1: Int, index2: Int) { val tmp = list[index1]

    list[index1] = list[index2] list[index2] = tmp } The class/type we want to extend 337
  197. fun MutableList<Int>.swap(index1: Int, index2: Int) { val tmp = list[index1]

    list[index1] = list[index2] list[index2] = tmp } The function we add 338
  198. fun MutableList<Int>.swap(index1: Int, index2: Int) { val tmp = list[index1]

    list[index1] = list[index2] list[index2] = tmp } 339
  199. fun MutableList<Int>.swap(index1: Int, index2: Int) { val tmp = list[index1]

    list[index1] = list[index2] list[index2] = tmp } Compilation error: unknown variable "list" 340
  200. fun MutableList<Int>.swap(index1: Int, index2: Int) { val tmp = list[index1]

    list[index1] = list[index2] list[index2] = tmp } 341
  201. fun MutableList<Int>.swap(index1: Int, index2: Int) { val tmp = this[index1]

    this[index1] = this[index2] this[index2] = tmp } 342
  202. fun MutableList<Int>.swap(index1: Int, index2: Int) { val tmp = this[index1]

    this[index1] = this[index2] this[index2] = tmp } 'this' corresponds to the list (receiver) 343
  203. 359

  204. fun IceCream.withChocolate(): IceCream { topping = Toppings.Chocolate return this }

    fun IceCream.asSunday(): SundayIceCream = SundayIceCream(this) 368
  205. class IceCreamShop { fun main(iceCream: IceCream) { iceCream.asSunday().withChocolate().addOreos() } fun

    IceCream.withChocolate(): IceCream { /** code */ } fun IceCream.asSunday(): SundayIceCream = /** code */ } 373
  206. class IceCreamShop { fun main(iceCream: IceCream) { iceCream.asSunday().withChocolate().addOreos() } fun

    IceCream.withChocolate(): IceCream { /** code */ } fun IceCream.asSunday(): SundayIceCream = /** code */ } 374
  207. class IceCreamShop { fun main(iceCream: IceCream) { iceCream.asSunday().withChocolate().addOreos() } fun

    IceCream.withChocolate(): IceCream { /** code */ } fun IceCream.asSunday(): SundayIceCream = /** code */ } 375
  208. class House { fun main(iceCream: IceCream) { iceCream.asSunday().withChocolate().addOreos() } }

    Compilation error: "asSunday" is not a function in IceCream class 378
  209. class House { fun main(iceCream: IceCream) { val shop =

    IceCreamShop() shop.asSunday().withChocolate().addOreos() } } Compilation error: "asSunday" is not a function in IceCreamShop class 379
  210. 380

  211. package com.android.academy fun IceCream.withChocolate(): IceCream { /** code */ }

    fun IceCream.asSunday(): SundayIceCream = /** code */ 382
  212. 384

  213. fun main() { val iceCream = IceCream() val topping =

    Toppings.Chocolate iceCream.to(topping) // -> Pair(iceCream, Chocolate) } 386
  214. fun main() { val iceCream = IceCream() val topping =

    Toppings.Chocolate iceCream to topping // -> Pair(iceCream, Chocolate) } 387
  215. fun main() { val iceCream = IceCream() val topping =

    Toppings.Chocolate iceCream to topping // -> Pair(iceCream, Chocolate) } 393
  216. 394

  217. var <E> MutableList<E>.last: E get() = this[size] set(value) { this[size]

    = value } val <E> List<E>.last: E get() = this[size] 399
  218. fun main() { val names = mutableListOf("Gil", "Eden", "Hadas") println(names.last)

    // -> "Hadas" names.last = "Yonatan" println(names) // -> ["Gil", "Eden", "Yonatan"] } 403
  219. public void checkParameterIsNotNull(Object value, String param) { if (value ==

    null) { throwParameterIsNullException(param); } } 406
  220. public static Object getLast(@NotNull List $last) { Intrinsics.checkParameterIsNotNull($last, "$last"); return

    $last.get($last.size()); } public static void setLast(@NotNull List $last, Object value) { Intrinsics.checkParameterIsNotNull($last, "$last"); $last.set($last.size(), value); } 408
  221. 409