https://dzone.com/refcardz/getting-started-with-kotlin?chapter=1
Tag: Kotlin
Kotlin miniguide #17 Generics
Generic function :
fun <T> List<T>.itemAt ( position : Int) : T {
return this[position]
}
Generic class :
class Library <T> ( private books: List<T>) {
val last : T? get () = books.lastOrNull()
}
More examples here
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 #9 operator overloading
In Kotlin we can overload some operators
class Set(val num : Int) {
operator fun plus(s: Set) = Set(this.num+ s.num)
}
And we can use it like this
Set s1 = Set(5) Set s2 = Set(6) Set s3 = s1 + s2
We have a new Set with 11 element.
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()
}
}
Kotlin miniguide #8 infix functions
Kotlin let the coder call a function or a method without using the dot notation:
class Person (age : Int) {
infix isOlderThan(p : Person) : Boolean {
return age > p.age
}
}
Person a = Person (34)
Person b = Person (34)
val ret = a isOlderThan b
The infix functions have only one parameter with no default value