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

Kotlin, how to dive in without drowning

Kotlin, how to dive in without drowning

présentation de Kotlin au FinistDev en mars 2018

Marc Poppleton

March 12, 2018
Tweet

More Decks by Marc Poppleton

Other Decks in Programming

Transcript

  1. KOTLIN IN A NUTSHELL • Functional & Object Oriented •

    Statically typed • Java interoperability source : openstreetmap.org Остров Котлин
  2. CLEANER package org.westeros; public class Main { public static void

    main(String[] args) { System.out.println("Bend the knee " + args[0]); } } java -jar demo.jar "John Snow" Bend the knee John Snow
  3. CLEANER package org.westeros fun main(args: Array<String>) { println("Bend the knee

    " + args[0]) } kotlinc main.kt -include-runtime -d demo.jar
 java -jar demo.jar "John Snow" Bend the knee John Snow
  4. CLEANER package org.westeros fun main(args: Array<String>) { println(text(args[0)) } private

    fun text(name:String):String { return "Bend the knee " + name }
  5. ARGUMENTS package org.westeros; public class Main { public static void

    main(String[] args) { System.out.println("Bend the knee " + methodWithAllArguments("John","Snow","Stark")); } public static String methodWithAllArguments(String surname, String name, String house){ return surname + " " + name + " of house " + house; } public static String methodWithTwoArguments(String surname, String name){ return methodWithAllArguments(surname,name,"Stark"); } public static String methodWithOneArguments(String surname){ return methodWithTwoArguments(surname,"Snow"); } }
  6. ARGUMENTS package org.westeros fun main(args: Array<String>) { println("Bend the knee

    " + methodWithAllArguments(house="Stark", surname="John", name="Snow")) } fun methodWithAllArguments(surname: String, name: String = "Snow", house: String = "Stark"): String { return "$surname $name of house $house" } java -jar demo.jar Bend the knee John Snow of house Stark
  7. ARGUMENTS package org.westeros fun main(args: Array<String>) { println("Bend the knee

    " + methodWithAllArguments(surname="John")) } fun methodWithAllArguments(surname: String, name: String = "Snow", house: String = "Stark"): String { return "$surname $name of house $house" } java -jar demo.jar Bend the knee John Snow of house Stark
  8. fun methodWithAllArguments(surname: String, name: String = "Snow", house: String =

    "Stark"): String = "$surname $name of house $house" ARGUMENTS
  9. NPE

  10. NULL CHECK package org.westeros; public class Main { public static

    void main(String[] args) { System.out.println("I have " + boast(3)); } public static String boast(Integer count){ return count.toString() + " dragons"; } } java -jar demo.jar I have 3 dragons
  11. NULL CHECK package org.westeros; public class Main { public static

    void main(String[] args) { System.out.println("I have " + boast(null)); //Cersei : Bugfix } public static String boast(Integer count){ return count.toString() + " dragons"; } } Exception in thread "main" java.lang.NullPointerException at org.westeros.Main.boast(Main.java:9)
  12. NULL CHECK package org.westeros fun main(args: Array<String>) { println("I have

    " + boast(null)) } fun boast(count:Int): String = "$count dragons" main.kt:4:31: error: null can not be a value of a non-null type kotlin.Int println("I have " + boast(null))
  13. NULL CHECK package org.westeros data class Person(val surname:String, val name:String,

    val house:String ) fun main(args: Array<String>) { var john = Person("John","Snow","Stark") greet(john) } fun greet(person:Person){ println("Welcome ${person.surname} ${person.name} of house ${person.house}") } java -jar demo.jar Welcome John Snow of house Stark
  14. NULL CHECK package org.westeros data class Person(val surname:String, val name:String,

    val house:String ) fun main(args: Array<String>) { var john = Person("John","Snow","Stark") greet(john) } fun greet(person:Person){ println("Welcome ${person.surname} ${person.name} of house ${person.house}") } java -jar demo.jar Welcome John Snow of house Stark
  15. NULL CHECK package org.westeros data class Person(val surname:String, val name:String,

    val house:String ) fun main(args: Array<String>) { var john = Person("John","Snow","Stark") greet(john) } fun greet(person:Person){ println("Welcome ${person.surname} ${person.name} of house ${person.house}") } java -jar demo.jar Welcome John Snow of house Stark
  16. NULL CHECK package org.westeros data class Person(val surname:String, val name:String,

    val house:String ) fun main(args: Array<String>) { var gendry = Person("Gendry") greet(gendry) } fun greet(person:Person){ println("Welcome ${person.surname} ${person.name} of house ${person.house}") } main.kt:9:33: error: no value passed for parameter name, house var gendry = Person("Gendry")
  17. CALLING ELVIS package org.westeros data class Person(val surname:String?, val name:String?

    = null, val house:String? = null ) fun main(args: Array<String>) { var gendry = Person("Gendry",house="Baratheon") greet(gendry) } fun greet(person:Person){ when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } java -jar demo.jar Welcome Gendry of house Baratheon
  18. CALLING ELVIS package org.westeros data class Person(val surname:String? = null,

    val name:String? = null, val house:String? = null ) fun main(args: Array<String>) { var john = Person("John",name="Snow", house="Stark") var gendry = Person("Gendry",house="Baratheon") var arya = Person() greet(john) greet(gendry) greet(arya) } fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } } java -jar demo.jar
 Welcome John Snow of house Stark
 Welcome Gendry of house Baratheon
 Welcome servant of The Many-Faced God
  19. LAMBDAS package org.westeros data class Person(val surname:String? = null, val

    name:String? = null, val house:String? = null ) fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) people.map { x  greet(x)} } fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  20. LAMBDAS package org.westeros data class Person(val surname:String? = null, val

    name:String? = null, val house:String? = null ) fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) people.map { x  greet(x)} } fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  21. LAMBDAS package org.westeros data class Person(val surname:String? = null, val

    name:String? = null, val house:String? = null ) fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) people.map { greet(it) } } fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  22. COLLECTIONS package org.westeros; import java.util.ArrayList; public class Main { public

    static void main(String[] args) { ArrayList<Person> people = new ArrayList (); people.add(new Person("John","Snow","Stark")); people.add(new Person("Gendry",null,"Baratheon")); people.add(new Person()); people.stream().forEach(x greet(x)); } public static void greet(Person person){ if(person.hasNoName()){ System.out.println("Welcome servant of The Many-Faced God"); }else{ if(null  person.getHouse()){ System.out.println(String.format("Welcome %s %s",person.getSurname(),person.getName())); }else{ System.out.println(String.format("Welcome %s %s of house %s",person.getSurname(),person.getName(),person.getHouse())); } } } }
  23. COLLECTIONS package org.westeros; import com.sun.istack.internal.Nullable; public class Person { private

    String name; private String surname; private String house; public Person(){} public Person(@Nullable String surname, @Nullable String name, @Nullable String house){ setSurname(surname); setName(name); setHouse(house); } public String getName() { if (name != null) { return name; }else{ return ""; } } public void setName(String name) { this.name = name; } public String getSurname() { if (surname != null) { return surname; }else{
  24. COLLECTIONS package org.westeros; import java.util.ArrayList; import org.westeros.utils.PeopleCollections; public class Main

    { public static void main(String[] args) { ArrayList<Person> people = new ArrayList (); people.add(new Person("John","Snow","Stark")); people.add(new Person("Gendry",null,"Baratheon")); people.add(new Person()); PeopleCollections.sortByHouse(people); people.stream().forEach(x greet(x)); } public static void greet(Person person){ if(person.hasNoName()){ System.out.println("Welcome servant of The Many-Faced God"); }else{ if(null  person.getHouse()){ System.out.println(String.format("Welcome %s %s",person.getSurname(),person.getName())); }else{ System.out.println(String.format("Welcome %s %s of house %s",person.getSurname(),person.getName(),person.getHouse())); } } } }
  25. COLLECTIONS package org.westeros.utils; import org.westeros.Person; import java.util.Comparator; import java.util.List; import

    java.util.Collections; public class PeopleCollections { public static void sortByHouse(List<Person> list) { Collections.sort(list, new Comparator<Person>() { public int compare(Person s1, Person s2) { if (s1.getHouse()  null){ return 0; } if ((s1.getHouse().equals("Lannister"))) { return -1; } if ((s1.getHouse().equals("Stark"))) { return -1; } if ((s1.getHouse().equals("Targaryen"))) { return -1; } if ((s1.getHouse().equals("Baratheon"))) { return -1; } if ((s1.getHouse().equals("Arryn"))) { return 1; } if ((s1.getHouse().equals("Frey"))) { return 1; } if ((s1.getHouse().equals("Greyjoy"))) { return 1; } if ((s1.getHouse().equals("Dorne"))) { return 1; } return 0; } }); } }
  26. package org.westeros.utils; import org.westeros.Person; import java.util.Comparator; import java.util.List; import java.util.Collections;

    public class PeopleCollections { public static void sortByHouse(List<Person> list) { Collections.sort(list, new Comparator<Person>() { public int compare(Person s1, Person s2) { if (s1.getHouse() == null){ return 0; } if ((s1.getHouse().equals("Lannister"))) { return -1; package org.westeros; import com.sun.istack.internal.Nullable; public class Person { private String name; private String surname; private String house; public Person(){} public Person(@Nullable String surname, @Nullable String name, @Nullable String house){ setSurname(surname); COLLECTIONS java -jar demo.jar
 Welcome Gendry of house Baratheon
 Welcome John Snow of house Stark
 Welcome servant of The Many-Faced God package org.westeros; import java.util.ArrayList; import org.westeros.utils.PeopleCollections; public class Main { public static void main(String[] args) { ArrayList<Person> people = new ArrayList<>(); people.add(new Person("John","Snow","Stark")); people.add(new Person("Gendry",null,"Baratheon")); people.add(new Person()); PeopleCollections.sortByHouse(people);
  27. COLLECTIONS package org.westeros data class Person(val surname:String? = null,val name:String?

    = null,val house:String? = null) : Comparable<Person>{ override fun compareTo(other: Person) = when(house) { null  0 "Lannister","Stark","Baratheon","Targaryen"  -1 else  1 } } fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) people.sorted().map { greet(it) } } fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  28. COLLECTIONS package org.westeros data class Person(val surname:String? = null,val name:String?

    = null,val house:String? = null) : Comparable<Person>{ override fun compareTo(other: Person) = when(house) { null  0 "Lannister","Stark","Baratheon","Targaryen"  -1 else  1 } } fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) people.sorted().map { greet(it) } } fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  29. COLLECTIONS package org.westeros data class Person(val surname:String? = null,val name:String?

    = null,val house:String? = null) : Comparable<Person>{ override fun compareTo(other: Person) = when(house) { null  0 "Lannister","Stark","Baratheon","Targaryen"  -1 else  1 } } fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) people.sorted().map { greet(it) } } fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  30. EXTENSIONS package org.westeros; import java.util.ArrayList; import org.westeros.utils.PeopleCollections; public class Main

    { public static void main(String[] args) { ArrayList<Person> people = new ArrayList (); people.add(new Person("John","Snow","Stark")); people.add(new Person("Gendry",null,"Baratheon")); people.add(new Person()); PeopleCollections.sortByHouse(people); people.stream().forEach(x greet(x)); } public static void greet(Person person){ if(person.hasNoName()){ System.out.println("Welcome servant of The Many-Faced God"); }else{ if(null  person.getHouse()){ System.out.println(String.format("Welcome %s %s",person.getSurname(),person.getName())); }else{ System.out.println(String.format("Welcome %s %s of house %s",person.getSurname(),person.getName(),person.getHouse())); } } } }
  31. EXTENSIONS package org.westeros data class Person(val surname:String? = null,val name:String?

    = null,val house:String? = null) : Comparable<Person>{ override fun compareTo(other: Person) = when(house) { null  0 "Lannister","Stark","Baratheon","Targaryen"  -1 else  1 } } fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) } fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  32. EXTENSIONS package org.westeros data class Person(val surname:String? = null,val name:String?

    = null,val house:String? = null) : Comparable<Person>{ override fun compareTo(other: Person) = when(house) { null  0 "Lannister","Stark","Baratheon","Targaryen"  -1 else  1 } } fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) } fun List<Person>.greet(){ this.sorted().map { greet(it) } } fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  33. EXTENSIONS package org.westeros data class Person(val surname:String? = null,val name:String?

    = null,val house:String? = null) : Comparable<Person>{ override fun compareTo(other: Person) = when(house) { null  0 "Lannister","Stark","Baratheon","Targaryen"  -1 else  1 } } fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) people.greet() } fun List<Person>.greet(){ this.sorted().map { greet(it) } } fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  34. EXTENSIONS package org.westeros data class Person(val surname:String? = null,val name:String?

    = null,val house:String? = null) : Comparable<Person>{ override fun compareTo(other: Person) = when(house) { null  0 "Lannister","Stark","Baratheon","Targaryen"  -1 else  1 } } fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) people.greet() } fun List<Person>.greet(){ this.sorted().map { greet(it) } } fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  35. EXTENSIONS package org.westeros data class Person(val surname:String? = null,val name:String?

    = null,val house:String? = null, val bastard:Boolean? = false) : Comparable<Person>{ override fun compareTo(other: Person) = when(house) { null  0 "Lannister","Stark","Baratheon","Targaryen"  -1 else  1 } } fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) people.greet() } fun List<Person>.greet(){ this.sorted().map { greet(it) } } fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  36. EXTENSIONS package org.westeros data class Person(val surname:String? = null,val name:String?

    = null,val house:String? = null, val bastard:Boolean? = false) : Comparable<Person>{ override fun compareTo(other: Person) = when(house) { null  0 "Lannister","Stark","Baratheon","Targaryen"  -1 else  1 } } fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) people.greet() } fun List<Person>.greet(){ this.sorted().map { greet(it) } } val List<Person>.bastardsCount: Int get() = this.filter { it.bastard  true }.count() fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  37. EXTENSIONS package org.westeros data class Person(val surname:String? = null,val name:String?

    = null,val house:String? = null, val bastard:Boolean? = false) : Comparable<Person>{ override fun compareTo(other: Person) = when(house) { null  0 "Lannister","Stark","Baratheon","Targaryen"  -1 else  1 } } fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) people.greet() println("We have ${people.bastardsCount} bastards with us.") } fun List<Person>.greet(){ this.sorted().map { greet(it) } } val List<Person>.bastardsCount: Int get() = this.filter { it.bastard  true }.count() fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  38. SEALED CLASS package org.westeros data class Person(val surname:String? = null,val

    name:String? = null,val house:String? = null, val bastard:Boolean? = false) : Comparable<Person>{ override fun compareTo(other: Person) = when(house) { null  0 "Lannister","Stark","Baratheon","Targaryen"  -1 else  1 } } fun main(args: Array<String>) { val people = listOf<Person>( Person("John",name="Snow", house="Stark"), Person("Gendry",house="Baratheon"), Person() ) people.greet() println("We have ${people.bastardsCount} bastards with us.") } fun List<Person>.greet(){ this.sorted().map { greet(it) } } val List<Person>.bastardsCount: Int get() = this.filter { it.bastard  true }.count() fun greet(person:Person){ when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } }
  39. SEALED CLASS package org.westeros sealed class Human() : Comparable<Human> data

    class Andal(val surname:String? = null, val name:String? = null, val house:String? = null, val bastard:Boolean? = false) : Human(){ override fun compareTo(other: Human) = when(house) { null  0 "Lannister","Stark","Baratheon"  -1 else  1 } }
  40. SEALED CLASS package org.westeros sealed class Human() : Comparable<Human> data

    class Andal(val surname:String? = null,val name:String? = null,val house:String? = null,val bastard:Boolean? = false) : Human(){ override fun compareTo(other: Human) = when(house) { null  0 "Lannister","Stark","Baratheon"  -1 else  1 } } data class Dornish(val surname:String? = null,val name:String? = null,val house:String? = null,val nickname:String? = null) : Human() { override fun compareTo(other: Human) = -1 } data class Dothraki(val surname:String,val name:String):Human(){ override fun compareTo(other: Human) = 0 } data class Valyrian(val surname:String? = null,val name:String? = null, val nickname: String?=null):Human(){ override fun compareTo(other: Human) = -1 } data class Ironborn(val surname:String? = null,val name:String? = null):Human(){ override fun compareTo(other: Human) = -1 } data class Freefolk(val surname:String? = null):Human(){ override fun compareTo(other: Human) = 0 }
  41. SEALED CLASS fun greet(person:Human) = when(person){ is Andal  when(person.surname){

    null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house $ {person.house}") } } is Freefolk  println("Welcome ${person.surname}") is Dothraki  println("Athchomar Chomakea ${person.surname} ${person.name}") is Dornish  println("Greetings ${person.surname} ${person.name}, ${person.nickname}") is Valyrian  println("Greetings ${person.surname} ${person.name}, ${person.nickname}") }
  42. TYPE CAST & CHECK fun greet(person:Human) = when(person){ is Andal

     when(person.surname){ null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house $ {person.house}") } } is Freefolk  println("Welcome ${person.surname}") is Dothraki  println("Athchomar Chomakea ${person.surname} ${person.name}") is Dornish  println("Greetings ${person.surname} ${person.name}, ${person.nickname}") is Valyrian  println("Greetings ${person.surname} ${person.name}, ${person.nickname}") }
  43. SEALED CLASS fun greet(person:Human) = when(person){ is Andal  when(person.surname){

    null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house $ {person.house}") } } is Freefolk  println("Welcome ${person.surname}") is Dothraki  println("Athchomar Chomakea ${person.surname} ${person.name}") is Dornish  println("Greetings ${person.surname} ${person.name}, ${person.nickname}") is Valyrian  println("Greetings ${person.surname} ${person.name}, ${person.nickname}") } main.kt:53:27: error: 'when' expression must be exhaustive, add necessary 'else' branch fun greet(person:Human) = when(person){
  44. SEALED CLASS fun greet(person:Human) = when(person){ is Andal  when(person.surname){

    null  println("Welcome servant of The Many-Faced God") else  when(person.house){ null  println("Welcome ${person?.surname} ${person?.name ?:""}") else  println("Welcome ${person?.surname} ${person?.name ?:""} of house ${person.house}") } } is Ironborn  println("Let ${person.surname} ${person.name } your servant be born again from the sea, as you were. Bless him with salt, bless him with stone, bless him with steel.") is Freefolk  println("Welcome ${person.surname}") is Dothraki  println("Athchomar Chomakea ${person.surname} ${person.name}") is Dornish  println("Greetings ${person.surname} ${person.name}, $ {person.nickname}") is Valyrian  println("Greetings ${person.surname} ${person.name}, $ {person.nickname}")
  45. SEALED CLASS fun main(args: Array<String>) { val people = listOf(

    Andal(bastard = true,surname = "John",name="Snow", house="Stark"), Andal("Gendry",house="Baratheon",bastard = true), Andal(), // Arya in disguise Ironborn("Balon","Greyjoy"), Freefolk("Ygritte"), Dothraki("Kahl","Drogo"), Dornish(surname="Oberyn",name="Martell",nickname= "Red Viper of Dorne"), Valyrian("Daenerys","Targaryen", nickname = "the First of Her Name, The Unburnt, Queen of the Andals," + " the Rhoynar and the First Men, Queen of Meereen," + " Khaleesi of the Great Grass Sea, Protector of the Realm," + " Lady Regnant of the Seven Kingdoms, Breaker of Chains and Mother of Dragons") ) people.greet() }
  46. SEALED CLASS fun main(args: Array<String>) { val people = listOf(

    Andal(bastard = true,surname = "John",name="Snow", house="Stark"), Andal("Gendry",house="Baratheon",bastard = true), Andal(), // Arya in disguise Ironborn("Balon","Greyjoy"), Freefolk("Ygritte"), Dothraki("Kahl","Drogo"), Dornish(surname="Oberyn",name="Martell",nickname= "Red Viper of Dorne"), Valyrian("Daenerys","Targaryen", nickname = "the First of Her Name, The Unburnt, Queen of the Andals," + " the Rhoynar and the First Men, Queen of Meereen," + " Khaleesi of the Great Grass Sea, Protector of the Realm," + " Lady Regnant of the Seven Kingdoms, Breaker of Chains and Mother of Dragons") ) people.greet() }
  47. SINGLETON package org.westeros sealed class Human() : Comparable<Human> data class

    Andal(val surname:String? = null,val name:String? = null,val house:String? = null,val bastard:Boolean? = false) : Human(){ override fun compareTo(other: Human) = when(house) { null  0 "Lannister","Stark","Baratheon"  -1 else  1 } } data class Dornish(val surname:String? = null,val name:String? = null,val house:String? = null,val nickname:String? = null) : Human() { override fun compareTo(other: Human) = -1 } data class Dothraki(val surname:String,val name:String):Human(){ override fun compareTo(other: Human) = 0 } data class Valyrian(val surname:String? = null,val name:String? = null, val nickname: String?=null):Human(){ override fun compareTo(other: Human) = -1 } data class Ironborn(val surname:String? = null,val name:String? = null):Human(){ override fun compareTo(other: Human) = -1 } data class Freefolk(val surname:String? = null):Human(){ override fun compareTo(other: Human) = 0 } object NotAHuman:Human(){ override fun compareTo(other: Human) = 1 }
  48. SEALED CLASS fun main(args: Array<String>) { val people = listOf(

    Andal(bastard = true,surname = "John",name="Snow", house="Stark"), Andal("Gendry",house="Baratheon",bastard = true), Andal(), // Arya in disguise Ironborn("Balon","Greyjoy"), Freefolk("Ygritte"), Dothraki("Kahl","Drogo"), Dornish(surname="Oberyn",name="Martell",nickname= "Red Viper of Dorne"), Valyrian("Daenerys","Targaryen", nickname = "the First of Her Name, The Unburnt, Queen of the Andals," + " the Rhoynar and the First Men, Queen of Meereen," + " Khaleesi of the Great Grass Sea, Protector of the Realm," + " Lady Regnant of the Seven Kingdoms, Breaker of Chains and Mother of Dragons”),
 NotAHuman ) people.greet() }
  49. SEALED CLASS Greetings Daenerys Targaryen, the First of Her Name,

    The Unburnt, Queen of the Andals, the Rhoynar and the First Men, Queen of Meereen, Khaleesi of the Great Grass Sea, Protector of the Realm, Lady Regnant of the Seven Kingdoms, Breaker of Chains and Mother of Dragons Greetings Oberyn Martell, Red Viper of Dorne Let Balon Greyjoy your servant be born again from the sea, as you were. Bless him with salt, bless him with stone, bless him with steel. Welcome Gendry of house Baratheon Welcome John Snow of house Stark Welcome servant of The Many-Faced God Welcome Ygritte Athchomar Chomakea Kahl Drogo HOLD THE DOOR! HOLD THE DOOR! HOOODOOOR! HOOODOOOOR!
  50. NESTED CLASS class Apple{ val color = "red" class Worm{

    val name = "Sprotch" fun wave() = "Hello, my name is $name" } } (…) println(Apple().color) // red print(Apple.Worm().wave()) // Hello, my name is Sprotch print(Apple.Worm().name) // Sprotch
  51. NESTED CLASS class Apple{ val color = "red" class Worm{

    val name = "Sprotch" fun wave() = "Hello, my name is $name" fun fact() = "The apple is $color" } } (…) println(Apple().color) // red print(Apple.Worm().wave()) // Hello, my name is Sprotch print(Apple.Worm().name) // Sprotch print(Apple.Worm().fact())
  52. INNER CLASS class Apple{ val color = "red" inner class

    Worm{ val name = "Sprotch" fun wave() = "Hello, my name is $name" fun fact() = "The apple is $color" } } (…) println(Apple().color) // red print(Apple.Worm().wave()) // Hello, my name is Sprotch print(Apple.Worm().name) // Sprotch print(Apple.Worm().fact()) // The apple is red
  53. THE BASICS package org.westeros.kotlindemo import android.support.v7.app.AppCompatActivity import android.os.Bundle class MainActivity

    : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } } <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="org.westeros.kotlindemo.MainActivity"> <TextView android:id="@+id/tv_greetings" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"/> </android.support.constraint.ConstraintLayout>
  54. THE BASICS package org.westeros.kotlindemo import android.support.v7.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.*

    class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } }
  55. THE BASICS package org.westeros.kotlindemo import android.support.v7.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.*

    class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) tv_greetings.text = "Welcome to Westeros!" } }
  56. THE BASICS package org.westeros.kotlindemo import android.support.v7.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.*

    class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) tv_greetings.setText(R.string.greetings) } }
  57. THE BASICS <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"

    android:layout_height="match_parent" tools:context="org.westeros.kotlindemo.MainActivity"> <TextView android:id="@+id/tv_greetings" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent"/> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintStart_toStartOf="@+id/tv_greetings" app:layout_constraintTop_toBottomOf="@+id/tv_greetings" app:layout_constraintEnd_toStartOf="@+id/tv_greetings" app:layout_constraintBottom_toBottomOf="parent"/> </android.support.constraint.ConstraintLayout>
  58. THE BASICS package org.westeros.kotlindemo import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.widget.Toast

    import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) tv_greetings.setText(R.string.greetings) button.setOnClickListener { view -> Toast.makeText(view.context, R.string.button_action, Toast.LENGTH_SHORT).show() } } }
  59. THE BASICS package org.westeros.kotlindemo import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.widget.Toast

    import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) tv_greetings.setText(R.string.greetings) button.setOnClickListener { Toast.makeText(it.context, R.string.button_action,Toast.LENGTH_SHORT).show() } } }
  60. ANKO package org.westeros.kotlindemo import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.widget.Toast import

    kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) tv_greetings.setText(R.string.greetings) button.setOnClickListener { Toast.makeText(it.context, R.string.button_action,Toast.LENGTH_SHORT).show() } } }
  61. ANKO package org.westeros.kotlindemo import android.support.v7.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.* import

    org.jetbrains.anko.toast class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) tv_greetings.setText(R.string.greetings) button.setOnClickListener { toast(R.string.button_action)} } }
  62. ADAPTERS import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import

    org.jetbrains.anko.find class MainActivity : AppCompatActivity() { data class Event(val date:String, val title:String, val location:String? = "") private val items = listOf( Event(title="Accueil Café",date="Jeudi 9h00 - 9h30"), Event("Jeudi 9h30 - 9h50","Introduction","Grand Amphi"), Event("Jeudi 9h50 - 10h05","La criée","Grand Amphi"), Event("Jeudi 10h05 - 10h15","Pause") ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val eventsList = find<RecyclerView>(R.id.events_list) eventsList.layoutManager = LinearLayoutManager(this) eventsList.adapter = EventListAdapter(items) } }
  63. ADAPTERS package com.orange.kotlindemo import android.support.v7.widget.RecyclerView import android.view.LayoutInflater import android.view.View import

    android.view.ViewGroup import kotlinx.android.synthetic.main.event_layout.view.* class EventListAdapter(private val items: List<MainActivity.Event >) : RecyclerView.Adapter<EventListAdapter.ViewHolder>() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):ViewHolder{ val view = LayoutInflater.from(parent.context).inflate(R.layout.event_layout, parent, false) return ViewHolder(view) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.bindEvent(items[position]) } override fun getItemCount(): Int = items.size class ViewHolder(val view: View) : RecyclerView.ViewHolder(view){ fun bindEvent(event: MainActivity.Event){ with(event){ itemView.tv_time.text = time itemView.tv_title.text = title when(room){ null -> itemView.tv_room.visibility = View.GONE else -> itemView.tv_room.text = room } } } } }