Welcome!
Your Skills?
•Java/Android
•C#
•Groovy
Kotlin
Java C#
Groovy
About Me
Ing. Marco Vasapollo
C. E. O. & Founder @ MetaRing
C. E. O. & Founder @ Aequalitam Foundation
Mail: ceo@metaring.com
Skype: marco.vasapollo
https://www.metaring.com
https://www.aequalitam.org
About Kotlin
•Strongly typed
•Both OOP & Functional
•Lightweight Syntax
•On the top of JVM
Warnings
•Kotlin is NOT Java
•It has its own APIs (for cross-platform reasons)
•Kotlin understands Java because of Plugins
•Plugins convert Kotlin APIs into Java APIs*
*when needed
How it works
HelloWorld.class
kotlin-compiler
HelloWorld.kt
import java.util.List;
import java.util.Date;
import ……
Access to all Java
libraries
org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
• Via command line
• Via official/unofficial IDE plugins (Eclipse, IntelliJ Idea,Visual
Studio Code)
• Via Packages Managers (Maven, Gradle)
Plain Classic Java ByteCode (No Java source needed)
Online IDE
https://try.kotlinlang.org
HelloWorld.kt
fun main(args : Array<String>) {
println(“Hello, world!”)
}
class Greeter(val name : String) {
fun greet() {
println("Hello, $name");
}
}
fun main(args : Array<String>) {
Greeter(args[0]).greet()
}
The simple way The OO Way
VS
Variables
var name : String = “Marco”
var name = “Marco”; //; can be omitted
val name = “Marco” //readonly, like Java final
val name : String
//0, 1, or more instructions later…
name = “Marco”
name = “Giuseppe” //cannot do this, once it’s assigned, value cannot be changed
var name : String? = null; //vars and vals are NullSafe by default, to allow
null you have to insert ‘?’ at the end
If
var a = 11
var b : String
if(a > 10) {
b = “foo”
} else {
b = “bar”
}
var a = 11
var b = if(a > 10) {
“foo”
} else {
“bar”
}
var a = 11
var b = if(a > 10) “foo” else “bar”
In Kotlin, if is an expression, not just a simple construct
Ternary operator does NOT exists, so you cannot do:
var b = a > 10 ? “foo” : “bar”
When
var a = 11
var b = when {
a > 10 -> “foo”
a < 10 -> “bar”
else -> “default case”
}
No need of switch construct. when operator is extremely powerful
var a = 11
var b = when(a) {
10 -> “foo”
11 -> “bar”
else -> “default case”
}
var a = 11
when {
a > 10 -> println(“foo”)
a < 10 -> println(“bar”)
else -> println(“default case”)
}
Nullables
var a : String? = “foo” //Can be null
var b = a.length //Syntax ERROR: a can be null and b is IMPLICITLY NullSafe
var b = if (a != null) a.length else -1 //Correct form
var b = a?.length //Same as above. But this time b is implicitly Int?
var name = bob?.department?.head?.name //Safe calls can be Concatenated
a?.let {println(a.length)} //If a is not null, execute this lambda expression
var b = a?.length ?: -1 //Elvis operator, if value to the left of ?: is null,
then use the one to the right. In this case b is Int
var b = a!!.length //a.length or NullPointerException
Equality
var eq = a === b //referential equality
var eq = a.equals(b) //Structural equality
var eq = a == b //syntactic sugar for a?.equals(b) ?: (b === null)
Strings
var name = “Marco”
var message = “My name is ” + name + “, pleasure to meet you”
message = “My name is ${name}, pleasure to meet you”//$name is correct too
var user = //get user data object from somewhere...
message = “My name is ”${user.name}${‘”’} and my bank account has ${user.cash}${‘$’}”
//Prints: My name is “Marco” and my bank account has 500$
message = “My name is ${user.name}, my bank account has ${user.cash + 300} ${‘$’}”
message = “My bank account has ${user.cash + getOtherSavings(user.id)} ${‘$’}”
Strings
var json =
“{nt”name”:”Marco”,nt”surname”:”Vasapollo”,nt”company”:”MetaRing”
n}”
json = “““
{
“name” : “Marco”,
“surname” : “Vasapollo”,
“company” : “Metaring”,
“age” : ${user.age}
}
”””
Arrays
var array1 = arrayOf("a", "b", "c", “d”) //Array<String> -> String[]
var array2 = arrayOf("a", "b", "c", 5) //Object[]
var array3 = arrayOfNulls<String>(10) //Array<String?>
var array4 = Array<String>(5) { "it = $it" } //for each element, execute this lambda
var list = array1.toList() //READONLY, NOT java.util.List
var mutableList = array1.toMutableList() //or list.toMutableList()
for(i in array1.indices) {//available on lists too
println(i) //prints 0,1,2,3
println(array1[i]) //prints a,b,c,d
}
for(i in array1) {
println(i) //prints a,b,c,d
}
Ranges
for(i in 1..4) print(i) //Prints “1234”
for(i in 1 until 4) print(i) //Prints “123”
for(i in 4 downTo 1) print(i) //Prints "4321"
for(i in 1..4 step 2) print(i) //Prints "13"
for(i in 4 downTo 1 step 2) print(i) //Prints "42“
var array1 = arrayOf("a", "b", "c", “d”)
var result = “c” in array1 //corresponds to array1.contains(“c”)
when("c") {
in array2 -> println(“foo”)
else -> println(“bar”)
}
Functions
fun sayMyName(name : String) { //default modifier is public, also for classes
println(“Your name is $name”)
}
fun foo() = println(“Hello!”) //Inline
fun bar() : Unit = println(“Ciao!”) //Unit is similar to Java void, can be omitted
fun main(args : Array<String>) {
var fooResult = foo() //returns Unit. Unlike Java void, it can be stored in a var
var barResult = bar() //returns Unit
//Unit is a Singleton, there is only a unique instance in all the System, so:
println(fooResult === barResult) //true
println(fooResult == barResult) //true
println(fooResult.equals(barResult)) //true
}
Functions
fun sum1(x : Int, y : Int) : Int {
return x + y
}
fun sum2(x : Int, y : Int) : Int = x + y //Inline, Groovy Style
var sum3 = fun(x : Int, y : Int) : Int = x + y //Anonymous function
var sum4 : (Int, Int) -> Int = { x, y -> x + y} //Type is same as sum3
fun logOperation(x : Int, y : Int, operation : (Int, Int) -> Int) {
println("Operation result between $x and $y is ${operation(x,y)}")
}
fun main(args : Array<String>) {
logOperation(3, 5, ::sum1) //references a function
logOperation(1, 4, sum3) //references an anonymous function
}
Packages
/* File src/Math.kt
* (match between path and package
* declaration is not mandatory) */
package marco.math
fun fantasticAbs() …
fun amazingPow() …
fun luxurySqrt() …
//File MyCode.kt
import marco.math.*
fun foo(args : Array<String>) {
fantasticAbs(...)
amazingPow(...)
luxurySqrt(...)
}
//File MyOtherCode.kt
import marco.math.amazingPow
import marco.math.luxurySqrt as thatCuteFunction
fun bar(args : Array<String>) {
amazingPow(...)
thatCuteFunction(...)
}
Classes
class User class User {} class User() class User() {} //All empty classes
class User(n : String) { //primary Constructor
var name = n
}
class User constructor(n : String) { //keyword constructor is omittable
var name = n
}
class User private constructor(n : String) { //needed when use modifiers or annotations
var name = n
}
class User(var name : String) //name is now a field of the User class
Classes
import java.util.Date
class User(var name : String) {
var minAge = 18
println(“User $name created”) //ERROR, primary constructor can only assign vars
init {
println(“User $name created”) //Use init block to add behavior to primary constructor
}
val creationTime = Date() //To instantiate an object, new keyword isn’t needed
init { //There can be more, non consecutive init blocks, they are executed sequentially
println(“Creation time: $creationTime”)
//Note that creationTime cannot be used in the first init block
}
}
Classes
class User(var name : String) {
constructor(age : Int) : this(“Marco”) { //Secondary constructor
// : this(...) is mandatory if primary constructor is explicitly declared
//primary constructor and init blocks are executed always and before secondary
//secondary constructors inputs like age cannot be used as class fields
//... Behavior of the secondary constructor ...
userAge = age
}
var userAge : Int
}
Inheritance
abstract class GeometricFigure {
abstract fun getArea() : Double
}
open class Rectangle : GeometricFigure { //classes are final by default
val x : Double
val y : Double
constructor(x : Double, y : Double) {
this.x = x
this.y = y
}
override final fun getArea() : Double = x * y
}
class Square(side : Double) : Rectangle(side, side) //super light!
Properties
class Rectangle(var x : Double, var y : Double) {
val area
get() = x * y //getter only, look at val
}
Class fields are Properties by default (Finally!!!!! ç_ç )
class User {
var fiscalCode : String
get
private set //getter is accessible, setter is not
//Properties value is mandatory. Use a default value, constructor input or lateinit
constructor(fiscalCode : String) = this.fiscalCode = fiscalcode
lateinit var name : String //Mandatory init before read!
var surname : String? = null
}
Data Classes
class User( //Common pattern: use default values in primary construction
var name : String = “”,
var surname : String = “”,
var fiscalCode : String = “”)
data class User(var name : String = “”, var surname : String = “”)
//data keyword auto generates a specific behavior for toString and equals, based on
//properties. E.G. toString -> “User(name=Marco, surname=)”
//plus, a useful copy method that can be used to clone instances in another ref
//To init (both non-data and data)
var user = User (
surname = “Rossi”, //order is not important
name = “Mario”)
var copy = user.copy(surname=“Bianchi”) //data only
Operators
class Point(var x = 0, var y = 0) {
operator fun inc() : Point {x++; y++; return this} //point++ on a Point var
operator fun dec() : Point {x--; y--; return this} //point–- on a Point var
operator fun plusAssign(n : Int) {x+=n; y+=n} //point += 5
}
fun main(args : Array<String>) {
var point = Point()
println(point) //Point(x=0, y=0)
point++
println(point) //Point(x=1, y=1)
point+=10 //x = 11, y = 11
}
https://kotlinlang.org/docs/reference/operator-overloading.html
Any
package kotlin
public open class Any {
public open operator fun equals(other: Any?): Boolean
public open fun hashCode(): Int
public open fun toString(): String
val <T : Any> T.javaClass: Class<T>
}
Any is the Kotlin superclass
Delegates
import kotlin.reflect.KProperty
class Foo {
var bar by LoggablePropertyDelegate<String>()
}
class LoggablePropertyDelegate <T> (var value : T? = null) {
operator fun getValue(thisRef: Any?, property: KProperty<*>): T? = value
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
var oldValue = this.value
this.value = value
println("${property.name} in $thisRef has been changed from $oldValue to $value")
}
}
Delegates
interface Base {
fun printInfo()
}
class BaseImpl(val x : Int) : Base {
override fun printInfo() = print(x)
}
class Derived(b : Base) : Base by b
fun main(args: Array<String>) {
val b = BaseImpl(10)
b.printInfo() //prints 10
Derived(b).printInfo() //prints 10
}
https://kotlinlang.org/docs/reference/delegation.html
https://kotlinlang.org/docs/reference/delegated-properties.html
Extension Methods
abstract class Employee(var name : String = "", var surname : String = "")
class Developer(name : String = "", surname : String = "", var language : String =
"Kotlin"): Employee(name, surname)
class Architect(name : String = "", surname : String = ""): Employee(name, surname)
class Manager(name : String = "", surname : String = ""): Employee(name, surname)
//If a want a toJson() Method?
import com.google.gson.Gson;
abstract class Employee(var name : String = "", var surname : String = "") {
fun toJson() = Gson().toJson(this)
}
Extension Methods
import com.google.gson.Gson;
fun Employee.toJson() = Gson().toJson(this) //In a module, or in a class
fun Any.toJson() = Gson().toJson(this) //Better
//Even better, as a readonly property
val Employee.json
get() = Gson().toJson(this)
fun main(args : Array<String>) {
var d = Developer()
println(d.toJson())
}
What If Employee, Developer, Architect and Manager are read-only (in jar, in maven package, etc)?
Android
Android
Android
Android
Android
Android
EXAMPLE
JavaScript
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>1.1.51</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>js</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-js</artifactId>
<version>1.1.51</version>
</dependency>
</dependencies>
JavaScript
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>compile</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-js</artifactId>
<version>${kotlin.version}</version>
<outputDirectory>${project.build.directory}/js/lib</outputDirectory>
<includes>*.js</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
JavaScript
EXAMPLE
Kotlin + jQuery
npm install ts2kt
ts2kt -d headers jquery.d.ts
Download jquery.d.ts from
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/types/jquery/jquery.d.ts
@JsName("$")
public external fun jQuery(selector : String) : JQuery
$(“#dataTable”).asDynamic().datatable()
Of course you have to import your jQuery and lib scripts into html
Kotlin-Native
• Kotlin Source -> Compiler -> Platform Binary (NO VM Needed)
• Code Sharing Between Platforms
• Windows, iOS, Android, Linux, OS X, RaspberryPI
• Still Early Beta (0.3)
git clone https://github.com/JetBrains/kotlin-native.git
cd kotlin-native
.gradlew.bat dependencies-update
.gradlew.bat dist
.gradlew.bat cross_dist
.gradlew.bat backend.native:tests:run <- Optional takes a veeery long time to end
.distbinkotlinc HelloWorld.kt –o HelloWorld -opt
Questions?

Bologna Developer Zone - About Kotlin

  • 1.
  • 2.
  • 3.
  • 4.
    About Me Ing. MarcoVasapollo C. E. O. & Founder @ MetaRing C. E. O. & Founder @ Aequalitam Foundation Mail: ceo@metaring.com Skype: marco.vasapollo https://www.metaring.com https://www.aequalitam.org
  • 5.
    About Kotlin •Strongly typed •BothOOP & Functional •Lightweight Syntax •On the top of JVM
  • 6.
    Warnings •Kotlin is NOTJava •It has its own APIs (for cross-platform reasons) •Kotlin understands Java because of Plugins •Plugins convert Kotlin APIs into Java APIs* *when needed
  • 7.
    How it works HelloWorld.class kotlin-compiler HelloWorld.kt importjava.util.List; import java.util.Date; import …… Access to all Java libraries org.jetbrains.kotlin.cli.jvm.K2JVMCompiler • Via command line • Via official/unofficial IDE plugins (Eclipse, IntelliJ Idea,Visual Studio Code) • Via Packages Managers (Maven, Gradle) Plain Classic Java ByteCode (No Java source needed)
  • 8.
  • 9.
    HelloWorld.kt fun main(args :Array<String>) { println(“Hello, world!”) } class Greeter(val name : String) { fun greet() { println("Hello, $name"); } } fun main(args : Array<String>) { Greeter(args[0]).greet() } The simple way The OO Way VS
  • 10.
    Variables var name :String = “Marco” var name = “Marco”; //; can be omitted val name = “Marco” //readonly, like Java final val name : String //0, 1, or more instructions later… name = “Marco” name = “Giuseppe” //cannot do this, once it’s assigned, value cannot be changed var name : String? = null; //vars and vals are NullSafe by default, to allow null you have to insert ‘?’ at the end
  • 11.
    If var a =11 var b : String if(a > 10) { b = “foo” } else { b = “bar” } var a = 11 var b = if(a > 10) { “foo” } else { “bar” } var a = 11 var b = if(a > 10) “foo” else “bar” In Kotlin, if is an expression, not just a simple construct Ternary operator does NOT exists, so you cannot do: var b = a > 10 ? “foo” : “bar”
  • 12.
    When var a =11 var b = when { a > 10 -> “foo” a < 10 -> “bar” else -> “default case” } No need of switch construct. when operator is extremely powerful var a = 11 var b = when(a) { 10 -> “foo” 11 -> “bar” else -> “default case” } var a = 11 when { a > 10 -> println(“foo”) a < 10 -> println(“bar”) else -> println(“default case”) }
  • 13.
    Nullables var a :String? = “foo” //Can be null var b = a.length //Syntax ERROR: a can be null and b is IMPLICITLY NullSafe var b = if (a != null) a.length else -1 //Correct form var b = a?.length //Same as above. But this time b is implicitly Int? var name = bob?.department?.head?.name //Safe calls can be Concatenated a?.let {println(a.length)} //If a is not null, execute this lambda expression var b = a?.length ?: -1 //Elvis operator, if value to the left of ?: is null, then use the one to the right. In this case b is Int var b = a!!.length //a.length or NullPointerException
  • 14.
    Equality var eq =a === b //referential equality var eq = a.equals(b) //Structural equality var eq = a == b //syntactic sugar for a?.equals(b) ?: (b === null)
  • 15.
    Strings var name =“Marco” var message = “My name is ” + name + “, pleasure to meet you” message = “My name is ${name}, pleasure to meet you”//$name is correct too var user = //get user data object from somewhere... message = “My name is ”${user.name}${‘”’} and my bank account has ${user.cash}${‘$’}” //Prints: My name is “Marco” and my bank account has 500$ message = “My name is ${user.name}, my bank account has ${user.cash + 300} ${‘$’}” message = “My bank account has ${user.cash + getOtherSavings(user.id)} ${‘$’}”
  • 16.
    Strings var json = “{nt”name”:”Marco”,nt”surname”:”Vasapollo”,nt”company”:”MetaRing” n}” json= “““ { “name” : “Marco”, “surname” : “Vasapollo”, “company” : “Metaring”, “age” : ${user.age} } ”””
  • 17.
    Arrays var array1 =arrayOf("a", "b", "c", “d”) //Array<String> -> String[] var array2 = arrayOf("a", "b", "c", 5) //Object[] var array3 = arrayOfNulls<String>(10) //Array<String?> var array4 = Array<String>(5) { "it = $it" } //for each element, execute this lambda var list = array1.toList() //READONLY, NOT java.util.List var mutableList = array1.toMutableList() //or list.toMutableList() for(i in array1.indices) {//available on lists too println(i) //prints 0,1,2,3 println(array1[i]) //prints a,b,c,d } for(i in array1) { println(i) //prints a,b,c,d }
  • 18.
    Ranges for(i in 1..4)print(i) //Prints “1234” for(i in 1 until 4) print(i) //Prints “123” for(i in 4 downTo 1) print(i) //Prints "4321" for(i in 1..4 step 2) print(i) //Prints "13" for(i in 4 downTo 1 step 2) print(i) //Prints "42“ var array1 = arrayOf("a", "b", "c", “d”) var result = “c” in array1 //corresponds to array1.contains(“c”) when("c") { in array2 -> println(“foo”) else -> println(“bar”) }
  • 19.
    Functions fun sayMyName(name :String) { //default modifier is public, also for classes println(“Your name is $name”) } fun foo() = println(“Hello!”) //Inline fun bar() : Unit = println(“Ciao!”) //Unit is similar to Java void, can be omitted fun main(args : Array<String>) { var fooResult = foo() //returns Unit. Unlike Java void, it can be stored in a var var barResult = bar() //returns Unit //Unit is a Singleton, there is only a unique instance in all the System, so: println(fooResult === barResult) //true println(fooResult == barResult) //true println(fooResult.equals(barResult)) //true }
  • 20.
    Functions fun sum1(x :Int, y : Int) : Int { return x + y } fun sum2(x : Int, y : Int) : Int = x + y //Inline, Groovy Style var sum3 = fun(x : Int, y : Int) : Int = x + y //Anonymous function var sum4 : (Int, Int) -> Int = { x, y -> x + y} //Type is same as sum3 fun logOperation(x : Int, y : Int, operation : (Int, Int) -> Int) { println("Operation result between $x and $y is ${operation(x,y)}") } fun main(args : Array<String>) { logOperation(3, 5, ::sum1) //references a function logOperation(1, 4, sum3) //references an anonymous function }
  • 21.
    Packages /* File src/Math.kt *(match between path and package * declaration is not mandatory) */ package marco.math fun fantasticAbs() … fun amazingPow() … fun luxurySqrt() … //File MyCode.kt import marco.math.* fun foo(args : Array<String>) { fantasticAbs(...) amazingPow(...) luxurySqrt(...) } //File MyOtherCode.kt import marco.math.amazingPow import marco.math.luxurySqrt as thatCuteFunction fun bar(args : Array<String>) { amazingPow(...) thatCuteFunction(...) }
  • 22.
    Classes class User classUser {} class User() class User() {} //All empty classes class User(n : String) { //primary Constructor var name = n } class User constructor(n : String) { //keyword constructor is omittable var name = n } class User private constructor(n : String) { //needed when use modifiers or annotations var name = n } class User(var name : String) //name is now a field of the User class
  • 23.
    Classes import java.util.Date class User(varname : String) { var minAge = 18 println(“User $name created”) //ERROR, primary constructor can only assign vars init { println(“User $name created”) //Use init block to add behavior to primary constructor } val creationTime = Date() //To instantiate an object, new keyword isn’t needed init { //There can be more, non consecutive init blocks, they are executed sequentially println(“Creation time: $creationTime”) //Note that creationTime cannot be used in the first init block } }
  • 24.
    Classes class User(var name: String) { constructor(age : Int) : this(“Marco”) { //Secondary constructor // : this(...) is mandatory if primary constructor is explicitly declared //primary constructor and init blocks are executed always and before secondary //secondary constructors inputs like age cannot be used as class fields //... Behavior of the secondary constructor ... userAge = age } var userAge : Int }
  • 25.
    Inheritance abstract class GeometricFigure{ abstract fun getArea() : Double } open class Rectangle : GeometricFigure { //classes are final by default val x : Double val y : Double constructor(x : Double, y : Double) { this.x = x this.y = y } override final fun getArea() : Double = x * y } class Square(side : Double) : Rectangle(side, side) //super light!
  • 26.
    Properties class Rectangle(var x: Double, var y : Double) { val area get() = x * y //getter only, look at val } Class fields are Properties by default (Finally!!!!! ç_ç ) class User { var fiscalCode : String get private set //getter is accessible, setter is not //Properties value is mandatory. Use a default value, constructor input or lateinit constructor(fiscalCode : String) = this.fiscalCode = fiscalcode lateinit var name : String //Mandatory init before read! var surname : String? = null }
  • 27.
    Data Classes class User(//Common pattern: use default values in primary construction var name : String = “”, var surname : String = “”, var fiscalCode : String = “”) data class User(var name : String = “”, var surname : String = “”) //data keyword auto generates a specific behavior for toString and equals, based on //properties. E.G. toString -> “User(name=Marco, surname=)” //plus, a useful copy method that can be used to clone instances in another ref //To init (both non-data and data) var user = User ( surname = “Rossi”, //order is not important name = “Mario”) var copy = user.copy(surname=“Bianchi”) //data only
  • 28.
    Operators class Point(var x= 0, var y = 0) { operator fun inc() : Point {x++; y++; return this} //point++ on a Point var operator fun dec() : Point {x--; y--; return this} //point–- on a Point var operator fun plusAssign(n : Int) {x+=n; y+=n} //point += 5 } fun main(args : Array<String>) { var point = Point() println(point) //Point(x=0, y=0) point++ println(point) //Point(x=1, y=1) point+=10 //x = 11, y = 11 } https://kotlinlang.org/docs/reference/operator-overloading.html
  • 29.
    Any package kotlin public openclass Any { public open operator fun equals(other: Any?): Boolean public open fun hashCode(): Int public open fun toString(): String val <T : Any> T.javaClass: Class<T> } Any is the Kotlin superclass
  • 30.
    Delegates import kotlin.reflect.KProperty class Foo{ var bar by LoggablePropertyDelegate<String>() } class LoggablePropertyDelegate <T> (var value : T? = null) { operator fun getValue(thisRef: Any?, property: KProperty<*>): T? = value operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { var oldValue = this.value this.value = value println("${property.name} in $thisRef has been changed from $oldValue to $value") } }
  • 31.
    Delegates interface Base { funprintInfo() } class BaseImpl(val x : Int) : Base { override fun printInfo() = print(x) } class Derived(b : Base) : Base by b fun main(args: Array<String>) { val b = BaseImpl(10) b.printInfo() //prints 10 Derived(b).printInfo() //prints 10 } https://kotlinlang.org/docs/reference/delegation.html https://kotlinlang.org/docs/reference/delegated-properties.html
  • 32.
    Extension Methods abstract classEmployee(var name : String = "", var surname : String = "") class Developer(name : String = "", surname : String = "", var language : String = "Kotlin"): Employee(name, surname) class Architect(name : String = "", surname : String = ""): Employee(name, surname) class Manager(name : String = "", surname : String = ""): Employee(name, surname) //If a want a toJson() Method? import com.google.gson.Gson; abstract class Employee(var name : String = "", var surname : String = "") { fun toJson() = Gson().toJson(this) }
  • 33.
    Extension Methods import com.google.gson.Gson; funEmployee.toJson() = Gson().toJson(this) //In a module, or in a class fun Any.toJson() = Gson().toJson(this) //Better //Even better, as a readonly property val Employee.json get() = Gson().toJson(this) fun main(args : Array<String>) { var d = Developer() println(d.toJson()) } What If Employee, Developer, Architect and Manager are read-only (in jar, in maven package, etc)?
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
    Kotlin + jQuery npminstall ts2kt ts2kt -d headers jquery.d.ts Download jquery.d.ts from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/types/jquery/jquery.d.ts @JsName("$") public external fun jQuery(selector : String) : JQuery $(“#dataTable”).asDynamic().datatable() Of course you have to import your jQuery and lib scripts into html
  • 44.
    Kotlin-Native • Kotlin Source-> Compiler -> Platform Binary (NO VM Needed) • Code Sharing Between Platforms • Windows, iOS, Android, Linux, OS X, RaspberryPI • Still Early Beta (0.3) git clone https://github.com/JetBrains/kotlin-native.git cd kotlin-native .gradlew.bat dependencies-update .gradlew.bat dist .gradlew.bat cross_dist .gradlew.bat backend.native:tests:run <- Optional takes a veeery long time to end .distbinkotlinc HelloWorld.kt –o HelloWorld -opt
  • 45.