Advancedkotlin 8
Advancedkotlin 8
1/1 2/31
Interfaces Example
We want to manage the NPCs for a game:
interface NPC {
I Declare abstract functions and functions implementations var location: Point
fun move()
I Can have abstract properties é Cannot store state fun draw()
}
fun updateScreen() {
for (npc in NPCs) {
npc.move()
npc.draw()
}
}
}
3/31 4/31
// ..
val manager = ManageNPCs()
manager.addNPC(Vampire("Dracula", Point(0, 10)))
5/31 6/31
interface StringProcessor {
fun transform(s: String): String
8
< of an interface }
I Used when you need an object
: of a slightly different class fun main () {
val duplicator = object : StringProcessor {
and you don’t want to write a new class
override fun transform(s: String): String {
I They are written as the object keyword followed by a colon, return s + s
the interface or parent class, and the body }
}
7/31 8/31
Object for Singletons Example
object Identifiers {
private var counter = 0
I It allows the definition of attributes accessed through the class companion object {
name, no need to use an instance const val INITIAL_LIFE = 10
I Typical use: defining constants, factory methods, etc const val FIGHT_STRENGTH = 20
}
}
11/31 12/31
Generics Example
13/31 14/31
I When used, the type parameter can be omitted if it is inferred fun updateScreen() { fun updateScreen() {
for (npc in NPCs) { for (npc in NPCs)
from the context:
npc.move() with (npc) {
val list = mutableListOf(1, 2, 3) npc.draw() move()
} draw()
} }
}
15/31 16/31
Scope Functions (2) apply
17/31 18/31
run with
I Similar to apply but returns the result of the lambda I Similar to run but the object is received as a parameter
I This I This
val currentPosition = vampire.run { val currentPosition = with (vampire) {
move() move()
draw() draw()
position position
} }
I is equivalent to I is equivalent to
vampire.move() vampire.move()
vampire.draw() vampire.draw()
val currentPosition = vampire.position val currentPosition = vampire.position
19/31 20/31
also let
I Similar to apply but the object is accessed through it
I Similar to also but the result is the value of the lambda
I This
I This
return Vampire("Dracula", Point(2,3)).also {
it.move() val currentPosition = vampire.let {
it.draw() it.move()
println("The name of the vampire is ${it.name}") println("The name of the vampire is ${it.name}")
} it.position
}
I is equivalent to
I is equivalent to
val vampire = Vampire("Dracula", Point(2,3))
vampire.move() vampire.move()
vampire.draw() println("The name of the vampire is ${vampire.name}")
println("The name of the vampire is ${vampire.name}") val currentPosition = vampire.position
return vampire
21/31 22/31
23/31 24/31
The Builder Class The Builder Class (2)
And we add a function for each of the elements that can be added:
We create a class to incrementally build all the parameters:
fun setDayLight(dayLight: Double): ScreenBuilder {
class ScreenBuilder { this.dayLight = dayLight
private var dayLight: Double = 0.0 return this
private var lightSources = ArrayList<LightSource>() }
private var NPCs = ArrayList<NPC>()
Or, using apply:
private var buildings = ArrayList<Building>()
fun setDayLight(dayLight: Double) =
apply { this.dayLight = dayLight }
25/31 26/31
fun addLightSource(lightSource: LightSource) = And a final function to actually build the screen
apply { lightSources.add(lightSource) }
fun createScreen() = Screen(dayLight,
fun addNPC(npc: NPC) = lightSources,
apply { NPCs.add(npc)} NPCs,
buildings)
fun addBuilding(building: Building) =
apply { buildings.add(building) }
27/31 28/31
29/31 30/31
Further Information
31/31