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

3. Object-Oriented Programming in Kotlin [kotlin-workshop]

3. Object-Oriented Programming in Kotlin [kotlin-workshop]

Part of https://github.com/jetBrains/kotlin-workshop.

Covers:
- Constructor syntax
- Properties
- Class modifiers (enum, data, inner, sealed)
- Objects, companion objects
- Constants
- Annotations

C6997ce411091d4a51ea3caa2109c0b0?s=128

Svetlana Isakova

November 01, 2017
Tweet

Transcript

  1. Object-oriented programming in Kotlin

  2. Feels the same …with some improvements

  3. final, open, abstract public, private, internal The defaults are different

  4. final, open, abstract public, private, /*package-private*/ The defaults are different

    internal explicit: non-final visible in a module
  5. Different constructor syntax

  6. Concise primary constructor class Person(val name: String, val age: Int)

  7. Full primary constructor syntax (1) class Person(name: String) { init

    { } } constructor parameter constructor body
  8. Full primary constructor syntax (2) class Person(name: String) { val

    name: String init { this.name = name } } constructor parameter constructor body
  9. val/var on parameter creates a property class Person(name: String) {

    val name: String init { this.name = name } } class Person(val name: String) is the same as:
  10. Secondary constructor class Rectangle(val height: Int, val width: Int) {

    constructor(side: Int) : this(side, side) { … } } secondary constructor primary constructor
  11. Properties, not fields

  12. property = field + accessor(s) read-only property = field +

    getter mutable property = field + getter + setter Property ( val / var )
  13. 
 class Contact( val name: String, var address: String )

    contact.getAddress(); contact.setAddress("..."); contact.address contact.address = "..."
  14. property = field? + accessor(s) read-only property = field? +

    getter mutable property = field? + getter + setter Property ( val / var )
  15. class Rectangle(val height: Int, val width: Int) { val isSquare:

    Boolean get() { return height == width } } Backing field might be absent
  16. class StateLogger { var state = false set(value) { println("state

    has changed") field = value } } You can use field inside accessors (only)
  17. val foo: Int val is read-only property (not immutable) get()

    = Random().nextInt()
  18. Classes

  19. Class modifiers enum, data, inner, sealed

  20. Enum class import Color.* fun getDescription(color: Color) = when (color)

    { BLUE -> "cold" ORANGE -> "mild" RED -> "hot" } enum class Color { BLUE, ORANGE, RED } represents enumeration
  21. Data modifier data class Contact(val name: String, val address: String)

    generates useful methods: equals, hashCode, copy, toString, and some others contact.copy(address = "new address")
  22. Equals & reference equality val set1 = setOf(1, 2, 3)

    val set2 = setOf(1, 2, 3) set1 == set2 set1 === set2 checks reference equality calls equals true false
  23. Sealed modifier sealed class Expr class Num(val value: Int) :

    Expr() class Sum(val left: Expr, val right: Expr) : Expr() restricts class hierarchy: all subclasses must be located in the same file fun eval(e: Expr): Int = when (e) { is Num -> e.value is Sum -> eval(e.left) + eval(e.right) }
  24. Inner modifier adds reference to the outer class class A

    { class B inner class C { …this@A… } }
  25. interface Repository { fun getById(id: Int): Customer fun getAll(): List<Customer>

    } interface Logger { fun logAll() } class Controller( repository: Repository, logger: Logger ) : Repository by repository, Logger by logger fun use(controller: Controller) { controller.logAll() } Class delegation
  26. Objects & companion objects

  27. object = singleton object KSingleton { fun foo() {} }

  28. Object = singleton public class JSingleton { public final static

    JSingleton INSTANCE = new JSingleton(); private JSingleton() { } public void foo() {} } object KSingleton { fun foo() {} }
  29. Using Kotlin object from Java public class UsingKotlinObjectFromJava { public

    static void main(String[] args) { JSingleton.INSTANCE.foo(); KSingleton.INSTANCE.foo(); } }
  30. companion object class A { companion object { fun foo()

    = 1 } } fun main(args: Array<String>) { A.foo() } special object inside a class
  31. companion object can implement an interface interface Factory<T> { fun

    create(): T } class A { private constructor() companion object : Factory<A> { override fun create(): A { return A() } }
  32. No static keyword Declare “static” members: - at the top-level

    - inside objects - inside companion objects
  33. @JvmStatic class C {
 companion object {
 @JvmStatic fun foo()

    {}
 fun bar() {}
 }
 } // Java
 C.foo();
 C.bar(); C.Companion.foo(); C.Companion.bar();
  34. @JvmStatic object Obj {
 @JvmStatic fun foo() {}
 fun bar()

    {}
 } // Java Obj.foo();
 Obj.bar();
 Obj.INSTANCE.foo(); Obj.INSTANCE.bar();
  35. Constants • const (for primitive types and String) • @JvmField

  36. Compile-time constants for primitive types and String const val answer

    = 42 the value is inlined
  37. @JvmField @JvmField val property = MyClass() // the same as

    // Java public static final MyClass property = new MyClass(); exposes a Kotlin property as a field in Java
  38. @JvmField makes a property static if used inside object class

    A { @JvmField val property = MyClass() } object B { @JvmField val property = MyClass() } regular field generated static field generated
  39. Annotations

  40. Annotation syntax @file:JvmName("FooUtils") use-site target annotation name annotation arguments

  41. Why use-site target? @Rule var folder @property:Rule @field:Rule @getter:Rule @setter:Rule

    might be:
  42. @JvmName // Data.kt fun foo() {
 } public final class

    DataKt {
 public static void foo() {
 }
 } @file:JvmName("FooUtils") fun foo() {
 } public final class FooUtils {
 public static final void foo() {
 }
 }
  43. @JvmName fun List<String>.filterValid(): List<String>
 fun List<Int>.filterValid(): List<Int> Error: platform declaration

    clash: declarations have the same JVM signature (filterValid(Ljava/util/List;)Ljava/util/List;)
  44. @JvmName fun List<String>.filterValid(): List<String>
 @JvmName("filterValidInt")
 fun List<Int>.filterValid(): List<Int>

  45. @JvmOverloads 
 fun f(a: String, b: Int = 0, c:

    String = "abc") {
 // ...
 } // Java
 void f(String a, int b, String c) { }

  46. @JvmOverloads @JvmOverloads
 fun f(a: String, b: Int = 0, c:

    String = "abc") {
 // ...
 } // Java
 void f(String a, int b, String c) { }
 void f(String a, int b) { }
 void f(String a) { }
  47. @Throws @Throws(IOException::class)
 fun foo() {
 throw IOException()
 }

  48. Checked exceptions // Java
 try {
 DemoKt.foo();
 }
 catch (IOException

    e) {
 // ...
 } fun foo() { throw IOException() } Error: Exception java.io.IOException is never thrown in body of corresponding try statement
  49. Checked exceptions // Java
 try {
 DemoKt.foo();
 }
 catch (IOException

    e) {
 // ...
 } @Throws(IOException::class) fun foo() { throw IOException() }
  50. Copyright © 2017 https://github.com/JetBrains/kotlin-workshop