Kotlin for Android May 24, 2018 y/kotlin-workbook
Objects, Constructors and Control Flow y/kotlin-workbook
classes BASIC SYNTAX y/kotlin-workbook interface Runnable { fun run() } interface RepeatingRunnable : Runnable { fun run(times: Int) { (1..times).forEach { run() } } } open class Greeting : Runnable { override fun run() = println("Hi!") } class RepeatingGreeting : Greeting(), RepeatingRunnable RepeatingGreeting().run(3)
● One primary constructor as part of class declaration ○ Declare property visibility and default values in the parameter list constructors OBJECTS AND FLOW y/kotlin-workbook class Person( val name: String = "John", private var age: Int )
● One primary constructor as part of class declaration ○ Declare property visibility and default values in the parameter list ● Initialization blocks - init constructors OBJECTS AND FLOW y/kotlin-workbook class Person( val name: String = "John", private var age: Int ){ init { // Initialize things here... } }
● One primary constructor as part of class declaration ○ Declare property visibility and default values in the parameter list ● Initialization blocks - init ● Optional secondary constructors ● Property initialization constructors OBJECTS AND FLOW y/kotlin-workbook class Person( val name: String = "John", private var age: Int ){ var hairColor: Color = Color.BLACK init { // Initialize things here... } constructor(age: Int, hairColor: Color): this(age = age){ this.hairColor = hairColor } }
constructors OBJECTS AND FLOW y/kotlin-workbook DEMO
object OBJECTS AND FLOW y/kotlin-workbook ● Used to create anonymous inner classes and singletons ● Can have static methods in the JVM ● Can have static fields in the JVM ● Every class can have a companion object ● Cannot inherit from object ○ object can inherit and extend though
object OBJECTS AND FLOW y/kotlin-workbook object Foo { val BAR = "BAR" fun hi() = "hi" } // kotlin val bar = Foo.BAR val foo = Foo.hi() // java String bar = Foo.INSTANCE.BAR; String foo = Foo.INSTANCE.hi();
object OBJECTS AND FLOW y/kotlin-workbook object Foo { const val BAR = "BAR" @JvmStatic fun hi() = "hi" } // kotlin val bar = Foo.BAR val foo = Foo.hi() // java String bar = Foo.INSTANCE.BAR; String foo = Foo.INSTANCE.hi(); // java improved interop String bar = Foo.BAR; String foo = Foo.hi();
companion object advanced OBJECTS AND FLOW y/kotlin-workbook UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo UserRepo.mock = mock(UserRepo) BizRepo.mock = mock(BizRepo) UserRepo.intance() // returns the mock repo BizRepo.intance() // returns the mock repo UserRepo.mock = null BizRepo.mock = null UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo
companion object advanced OBJECTS AND FLOW y/kotlin-workbook interface Factory<T: Any> { var mock: T? fun instance(): T } UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo UserRepo.mock = mock(UserRepo) BizRepo.mock = mock(BizRepo) UserRepo.intance() // returns the mock repo BizRepo.intance() // returns the mock repo UserRepo.mock = null BizRepo.mock = null UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo
companion object advanced OBJECTS AND FLOW y/kotlin-workbook interface Factory<T: Any> { var mock: T? fun instance(): T } open class Provider<T: Any>(init: () -> T): Factory<T> { override var mock: T? = null private val instance: T by lazy(init) override fun instance() = mock ?: instance } UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo UserRepo.mock = mock(UserRepo) BizRepo.mock = mock(BizRepo) UserRepo.intance() // returns the mock repo BizRepo.intance() // returns the mock repo UserRepo.mock = null BizRepo.mock = null UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo
companion object advanced OBJECTS AND FLOW y/kotlin-workbook interface Factory<T: Any> { var mock: T? fun instance(): T } open class Provider<T: Any>(init: () -> T): Factory<T> { override var mock: T? = null private val instance: T by lazy(init) override fun instance() = mock ?: instance } class UserRepo { companion object : Provider<UserRepo>({ UserRepo() }) } class BizRepo { companion object : Provider<BizRepo>({ BizRepo() }) } UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo UserRepo.mock = mock(UserRepo) BizRepo.mock = mock(BizRepo) UserRepo.intance() // returns the mock repo BizRepo.intance() // returns the mock repo UserRepo.mock = null BizRepo.mock = null UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo
● No goto Control Flow OBJECTS AND FLOW y/kotlin-workbook
Control Flow OBJECTS AND FLOW y/kotlin-workbook fun foo() { listOf(1, 2, 3, 4, 5).forEach { if (it == 3) return print(it) } println(" this is unreachable") } ● No goto ● return, break and continue
Control Flow OBJECTS AND FLOW y/kotlin-workbook fun foo() { listOf(1, 2, 3, 4, 5).forEach { if (it == 3) return print(it) } println(" this is unreachable") } // 12 ● No goto ● return, break and continue
Control Flow OBJECTS AND FLOW y/kotlin-workbook fun foo() { listOf(1, 2, 3, 4, 5).forEach { if (it == 3) return@forEach print(it) } println(" this is reachable") } ● No goto ● return, break and continue can use labels
Control Flow OBJECTS AND FLOW y/kotlin-workbook fun foo() { listOf(1, 2, 3, 4, 5).forEach { if (it == 3) return@forEach print(it) } println(" this is reachable") } // 1245 this is reachable ● No goto ● return, break and continue can use labels
Control Flow OBJECTS AND FLOW y/kotlin-workbook fun foo() { listOf(1, 2, 3, 4, 5).forEach loop@{ if (it == 3) return@loop print(it) } println(" this is reachable") } // 1245 this is reachable ● No goto ● return, break and continue can use labels
Control Flow OBJECTS AND FLOW y/kotlin-workbook fun foo() { listOf(1, 2, 3, 4, 5).run { forEach { if (it == 3) return@run print(it) }} println(" this is reachable") } // 12 this is reachable ● No goto ● return, break and continue can use labels
Control Flow OBJECTS AND FLOW y/kotlin-workbook fun foo() { for (int in listOf(1, 2, 3, 4, 5)) { if (int == 3) break print(int) } println(" this is reachable") } ● No goto ● return, break and continue can use labels ● for loop - no parameterized for(;;)
Control Flow OBJECTS AND FLOW y/kotlin-workbook ● No goto ● return, break and continue can use labels ● for loop - no parametrized for(;;) ● while - same as java
Control Flow OBJECTS AND FLOW y/kotlin-workbook return if (isJvmRuntime) { RuntimeEnvironment.application } else { InstrumentationRegistry.getContext() } ● No goto ● return, break and continue can use labels ● for loop - no parametrized for(;;) ● while - same as java ● if - same as java, can be used as an expression
Control Flow OBJECTS AND FLOW y/kotlin-workbook return when (isJvmRuntime) { true -> RuntimeEnvironment.application else -> InstrumentationRegistry.getContext() } ● No goto ● return, break and continue can use labels ● for loop - no parametrized for(;;) ● while - same as java ● if - same as java, can be used as an expression ● when - replaces switch from java, can be used as expr.
Control Flow OBJECTS AND FLOW y/kotlin-workbook val z = when { x.isOdd() -> "x is odd" y.isEven() -> "y is even" else -> "x is funny, y is cool" } ● No goto ● return, break and continue can use labels ● for loop - no parametrized for(;;) ● while - same as java ● if - same as java, can be used as an expression ● when - replaces switch from java, can be used as expr.
Control Flow OBJECTS AND FLOW y/kotlin-workbook val isJvmRuntime = try { Class.forName("org.robolectric.RuntimeEnvironment") true } catch (notFound: ClassNotFoundException) { false } ● No goto ● return, break and continue can use labels ● for loop - no parametrized for(;;) ● while - same as java ● if - same as java, can be used as an expression ● when - replaces switch from java, can be used as expr. ● try catch - same as java, can be used as an expression
Questions? Next Up: Functions

Kotlin For Android - Constructors and Control Flow (part 2 of 7)

  • 1.
    Kotlin for Android May24, 2018 y/kotlin-workbook
  • 2.
    Objects, Constructors andControl Flow y/kotlin-workbook
  • 3.
    classes BASIC SYNTAX y/kotlin-workbook interface Runnable{ fun run() } interface RepeatingRunnable : Runnable { fun run(times: Int) { (1..times).forEach { run() } } } open class Greeting : Runnable { override fun run() = println("Hi!") } class RepeatingGreeting : Greeting(), RepeatingRunnable RepeatingGreeting().run(3)
  • 4.
    ● One primaryconstructor as part of class declaration ○ Declare property visibility and default values in the parameter list constructors OBJECTS AND FLOW y/kotlin-workbook class Person( val name: String = "John", private var age: Int )
  • 5.
    ● One primaryconstructor as part of class declaration ○ Declare property visibility and default values in the parameter list ● Initialization blocks - init constructors OBJECTS AND FLOW y/kotlin-workbook class Person( val name: String = "John", private var age: Int ){ init { // Initialize things here... } }
  • 6.
    ● One primaryconstructor as part of class declaration ○ Declare property visibility and default values in the parameter list ● Initialization blocks - init ● Optional secondary constructors ● Property initialization constructors OBJECTS AND FLOW y/kotlin-workbook class Person( val name: String = "John", private var age: Int ){ var hairColor: Color = Color.BLACK init { // Initialize things here... } constructor(age: Int, hairColor: Color): this(age = age){ this.hairColor = hairColor } }
  • 7.
  • 8.
    object OBJECTS AND FLOW y/kotlin-workbook ●Used to create anonymous inner classes and singletons ● Can have static methods in the JVM ● Can have static fields in the JVM ● Every class can have a companion object ● Cannot inherit from object ○ object can inherit and extend though
  • 9.
    object OBJECTS AND FLOW y/kotlin-workbook objectFoo { val BAR = "BAR" fun hi() = "hi" } // kotlin val bar = Foo.BAR val foo = Foo.hi() // java String bar = Foo.INSTANCE.BAR; String foo = Foo.INSTANCE.hi();
  • 10.
    object OBJECTS AND FLOW y/kotlin-workbook objectFoo { const val BAR = "BAR" @JvmStatic fun hi() = "hi" } // kotlin val bar = Foo.BAR val foo = Foo.hi() // java String bar = Foo.INSTANCE.BAR; String foo = Foo.INSTANCE.hi(); // java improved interop String bar = Foo.BAR; String foo = Foo.hi();
  • 11.
    companion object advanced OBJECTS ANDFLOW y/kotlin-workbook UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo UserRepo.mock = mock(UserRepo) BizRepo.mock = mock(BizRepo) UserRepo.intance() // returns the mock repo BizRepo.intance() // returns the mock repo UserRepo.mock = null BizRepo.mock = null UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo
  • 12.
    companion object advanced OBJECTS ANDFLOW y/kotlin-workbook interface Factory<T: Any> { var mock: T? fun instance(): T } UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo UserRepo.mock = mock(UserRepo) BizRepo.mock = mock(BizRepo) UserRepo.intance() // returns the mock repo BizRepo.intance() // returns the mock repo UserRepo.mock = null BizRepo.mock = null UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo
  • 13.
    companion object advanced OBJECTS ANDFLOW y/kotlin-workbook interface Factory<T: Any> { var mock: T? fun instance(): T } open class Provider<T: Any>(init: () -> T): Factory<T> { override var mock: T? = null private val instance: T by lazy(init) override fun instance() = mock ?: instance } UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo UserRepo.mock = mock(UserRepo) BizRepo.mock = mock(BizRepo) UserRepo.intance() // returns the mock repo BizRepo.intance() // returns the mock repo UserRepo.mock = null BizRepo.mock = null UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo
  • 14.
    companion object advanced OBJECTS ANDFLOW y/kotlin-workbook interface Factory<T: Any> { var mock: T? fun instance(): T } open class Provider<T: Any>(init: () -> T): Factory<T> { override var mock: T? = null private val instance: T by lazy(init) override fun instance() = mock ?: instance } class UserRepo { companion object : Provider<UserRepo>({ UserRepo() }) } class BizRepo { companion object : Provider<BizRepo>({ BizRepo() }) } UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo UserRepo.mock = mock(UserRepo) BizRepo.mock = mock(BizRepo) UserRepo.intance() // returns the mock repo BizRepo.intance() // returns the mock repo UserRepo.mock = null BizRepo.mock = null UserRepo.intance() // returns the real repo BizRepo.intance() // returns the real repo
  • 15.
    ● No goto ControlFlow OBJECTS AND FLOW y/kotlin-workbook
  • 16.
    Control Flow OBJECTS ANDFLOW y/kotlin-workbook fun foo() { listOf(1, 2, 3, 4, 5).forEach { if (it == 3) return print(it) } println(" this is unreachable") } ● No goto ● return, break and continue
  • 17.
    Control Flow OBJECTS ANDFLOW y/kotlin-workbook fun foo() { listOf(1, 2, 3, 4, 5).forEach { if (it == 3) return print(it) } println(" this is unreachable") } // 12 ● No goto ● return, break and continue
  • 18.
    Control Flow OBJECTS ANDFLOW y/kotlin-workbook fun foo() { listOf(1, 2, 3, 4, 5).forEach { if (it == 3) return@forEach print(it) } println(" this is reachable") } ● No goto ● return, break and continue can use labels
  • 19.
    Control Flow OBJECTS ANDFLOW y/kotlin-workbook fun foo() { listOf(1, 2, 3, 4, 5).forEach { if (it == 3) return@forEach print(it) } println(" this is reachable") } // 1245 this is reachable ● No goto ● return, break and continue can use labels
  • 20.
    Control Flow OBJECTS ANDFLOW y/kotlin-workbook fun foo() { listOf(1, 2, 3, 4, 5).forEach loop@{ if (it == 3) return@loop print(it) } println(" this is reachable") } // 1245 this is reachable ● No goto ● return, break and continue can use labels
  • 21.
    Control Flow OBJECTS ANDFLOW y/kotlin-workbook fun foo() { listOf(1, 2, 3, 4, 5).run { forEach { if (it == 3) return@run print(it) }} println(" this is reachable") } // 12 this is reachable ● No goto ● return, break and continue can use labels
  • 22.
    Control Flow OBJECTS ANDFLOW y/kotlin-workbook fun foo() { for (int in listOf(1, 2, 3, 4, 5)) { if (int == 3) break print(int) } println(" this is reachable") } ● No goto ● return, break and continue can use labels ● for loop - no parameterized for(;;)
  • 23.
    Control Flow OBJECTS ANDFLOW y/kotlin-workbook ● No goto ● return, break and continue can use labels ● for loop - no parametrized for(;;) ● while - same as java
  • 24.
    Control Flow OBJECTS ANDFLOW y/kotlin-workbook return if (isJvmRuntime) { RuntimeEnvironment.application } else { InstrumentationRegistry.getContext() } ● No goto ● return, break and continue can use labels ● for loop - no parametrized for(;;) ● while - same as java ● if - same as java, can be used as an expression
  • 25.
    Control Flow OBJECTS ANDFLOW y/kotlin-workbook return when (isJvmRuntime) { true -> RuntimeEnvironment.application else -> InstrumentationRegistry.getContext() } ● No goto ● return, break and continue can use labels ● for loop - no parametrized for(;;) ● while - same as java ● if - same as java, can be used as an expression ● when - replaces switch from java, can be used as expr.
  • 26.
    Control Flow OBJECTS ANDFLOW y/kotlin-workbook val z = when { x.isOdd() -> "x is odd" y.isEven() -> "y is even" else -> "x is funny, y is cool" } ● No goto ● return, break and continue can use labels ● for loop - no parametrized for(;;) ● while - same as java ● if - same as java, can be used as an expression ● when - replaces switch from java, can be used as expr.
  • 27.
    Control Flow OBJECTS ANDFLOW y/kotlin-workbook val isJvmRuntime = try { Class.forName("org.robolectric.RuntimeEnvironment") true } catch (notFound: ClassNotFoundException) { false } ● No goto ● return, break and continue can use labels ● for loop - no parametrized for(;;) ● while - same as java ● if - same as java, can be used as an expression ● when - replaces switch from java, can be used as expr. ● try catch - same as java, can be used as an expression
  • 28.

Editor's Notes

  • #4 Continue where we left off - deep dive on constructors
  • #6 Any number of init blocks Nonnull properties outside the primary constructor must be initialized by the end of the block
  • #7 Secondary constructors must delegate to primary constructor if declared
  • #8 Deep dive on constructors
  • #9 Anonymous inner class is an object expression, singleton is an object declaration Is as close to having static as kotlin allows still instance members of real objects
  • #10 Kotlin looks just like you remember with java statics Not super friendly interop
  • #12 Return real repo only if mock is not set Painful to do in Java without inheritance, must implement for both
  • #13 Talk about generics Most permissive generic is Any?
  • #19 Called local return, uses an implicit label This return is equivalent to a continue, and only 3 will not be printed
  • #20 Called local return, uses an implicit label This return is equivalent to a continue, and only 3 will not be printed
  • #21 Can explicitly declare the labels Same as above slide
  • #23 Can use .withIndex() and destructure: for ((index, value) in array.withIndex())
  • #26 Compiles down to if/else blocks Only need else in expression and if you use enums/sealed class it isn’t needed No fall through
  • #27 Not parameterized evaluates each and evaluates first true Can use blocks of code
  • #28  ALMOST END OF SLIDES - NEXT SLIDE IS LAST - Q&A STARTS