Kotlin miniguide #15 Collections

Create and filter a read only list:


var comics = listOf(Comics("Akira", "Japan" ), Comics ("Nausicaa", "Japan" ), Comics ("Spiderman", "Usa" ))

var titles = comics.filter ( it == "Japan")

.map(m ->m.title)

//titles will contain Akira and Nausicaa

class Comics (title : String, nation : String )

For adding or removing elements, we must use mutableListOf

A nice page about collections

Kotlin miniguide #14 High order functions

In Kotlin, functions can be passed as arguments to other functions, returned from functions, stored in variables.

In the code below a function add is declared as a lambda and passed as argument to the function calc:


val add ={a: Int, b: Int ->a+ b}

fun calc(i1:Int, i2: Int, action : (p1: Int, p2: Int) -> Int) {

var result = action (i1, i2)

}

//usage

calc(add)

In the code below a function add is declared as an anonymous function and passed as argument to the function calc:


val add =fun(a: Int, b: Int) =a+ b

fun calc(i1:Int, i2: Int, action : (p1: Int, p2: Int) -> Int) {

var result = action (i1, i2)

}

//usage

calc(add)

Returning a function that accepts a string and returns nothing:


fun displaMsg(msg : String) : (String) -> Unit {

return { s -> println ("$msg is $s" ) }

}

val d = displayMsg("error")

d("401")

//output is "error is 401"

Kotlin miniguide #13 Data classes

For classes that contain only data, Kotlin provides an implementation of

  • equals
  • getHashCode
  • toString
  • copy

Consider the following examples


class Person (name : String)

Person a = Person ("Tom")

Person b = Person ("Tom")

println(a == b)

this print false because equals compares the objects references.

If instead we use a data class:


data class Person (name : String)

Person a = Person ("Tom")

Person b = Person ("Tom")

println(a == b)

this print true because equals is called on each member, and in this case the two instances have the same name.

It is possible to copy an instance of a data class changing some of its properties:


class Person (name : String, age : Int)

Person a = Person ("Tom", 23)

Person b = a.copy(age = 35)

Kotlin miniguide #12 Sealed classes

When used in combination with the when expression, sealed classes are like enum for classes:


sealed class Port

val name : String

get() = when (this) { //custom getter

is USB ->"this is USB"

is COM ->"this is COM"

}

class USB : Port()

class COM : Port()

USB u = USB

println (u.name) //this prints "this is USB"

Sealed classes are abstract, can have abstract members and define the classes that can inherit from them (USB and COM can inherit from Port)

Kotlin miniguide #11 Classes and constructors

In Kotlin classes are:

  • Public by default
  • Final by default

To let the coder inherit from a class we have to use the keyword open. The same applies to methods:


open class Employee {

open fun doSomething() { // can be overridden

}

}

Construction parameters are provided in the class definition. This is the primary constructor. (Internally, Kotlin provides a getter and/or a setter wheter the parameter is a val or a var)


open class Employee(val name : String) {

}

Secondary constructor:


open class Employee(val name : String) {

constructor(name: String, id : Int) : this(name)

}

Constructors and inheritance :


class Tester(name : String) : Employee(name) {



}

More about classes here

Kotlin miniguide #10 Interfaces

In Kotlin interfaces are very similar to Java interfaces, but we can also provide a default implementation for an interface member:


interface IEmployee{

var name : String //abstract property

fun doWork(){

//some default implementation

}

fun doBreak() //abstract

}

Default implementation allows us to add functionality to interfaces without breaking existing code, because default implementation is not required to be implemented:


class Tester (override var name : String) IEmployee {

   override fun doBreak () {... }

}

We can inherit from interfaces that have a member with the same signature:


interface ITester{

   fun doWork () {...}

}

class Tester (override var name : String) : ITester, IEmployee{

  override fun doBreak() {

  }

  override fun doWork() {

      super<ITester>.doWork()

     super<IEmployee>.doWork()

  }

}