Obsah

Kotlin - základy

Úvod

Kotlin je moderný programovací jazyk. Vytvorila ho firma JetBrains. Vysokú podporu má od Google a preto je využitý v platforme Android. Je však natoľko univerzálny a má takú podporu knižníc, že je využitý i pre multiplatformové nasadenie pre iOS, web frontend (JavaScript), Linux, Windows a aj servery (Ktor), kde beží pod JVM (Java, napríklad Apache Tomcat).

Vyznačuje sa stručnosťou (oproti Java). Je možné v jednom projekte kombinovať Java aj Kotlin. Bezpečnosť voči null ukazateľom je vyriešená (null safety). Lambda funkcie výrzane uľahčujú písanie a stručnosť kódu. Coroutins zjednodušujú prácu s asynchronnými procesmi (vlákna) a preberanie odpovedí z nich.

Základné špecifikácie a príkazy

Označenie premenných

var : variable (dynamický obsah)
val : value (konštantná hodnota)

Typy premenných

Celé čísla

Byte -128..127, 8 bit
Short -32768..32767, 16 bit
Int -2147483648..2147483647, 32 bit
Long -263 .. 263 - 1, 64 bit

Desatinné čísla

Float +-1.4 * 10^−45 .. +-3.4 * 1038, presnosť: 7 čísel
Double +-5.0 * 10^−324 .. +-1.7 * 10308, presnosť: 15 .. 16 čísel

Ďalšie typy

Char 16 bit
Boolean 8 bit
String

Operátory

==, >, <, <=, >=, !=, !

Podmienky

if ()
if() else
if() else if()
when(var) {…} \\ when(val) {val → {…} else → {…}}
when() else

reťazenie podmienok

&&, ||

Cykly

for (i in m..n)
while ()
repeat(n) {}

it : aktuálny riadok cyklu

fun myFc() = sequence<Int> {
	for(i in m..n) {
		yield(i)    // yield() vracia hodnotu, zväčša do .forEach{} volajúcej fc
	}
}

Null safety

var myValue:<ValueType>? : povolenie null
anyCommand(myValue!!) : vypnutie kontroly
myValue?.let { anyCommand } : bezpečné volanie
anyCommand(myValue?.anyMethod ?: defaultValue) : bezpečné volanie s elvis operátorom

Polia

var myArray = arrayOf<ValueType>()
val myArray: Array<ValueType>(val1, … val_n)
var myList: List<ValueType> = listOf() … myList += newValue … myList -= selectedList
Konverzie
val myArray: Array<CharSequence> = myArrayList.toTypedArray() // ArrayLit to Array

Reťazce

časté funkcie:

Matematické funkcie
import kotlin.math.*

Objektové programovanie - OOP

class - Trieda:

Deklarácie

Deklarácia triedy

class MyClass { … }

Deklarácia metódy

[modifikatorPristupu] [menoMetody] ([parametre]) : [navratovyTyp]

Deklarácia vlastnosti

Vytvorenie inštancie

val myValue = MyClass()

Konštruktory

class MyClass(myValue: ValueType) {
  val myVal: ValueType
  init {
    this.myVal = myValue
  }
}
class MyClass(val myValue: ValueType) {
  constructor() : this(defaultValue)
}

Zapúzdrenie

class MyClass(private var myValue) {  // getters and setters
  fun getMyValue(): ValueType {  // getter
    return myValue
  }
  fun setMyValue(myVal valueType) {  // setter
    myValue = myVal
  }
}
class MyClass(myValue: ValueType) {  // private set
  var myValue = myValue
    private set
}
class MyClass(myValue: ValueType) {  // backing properties
  var myValue = myValue
    private set
    get() {
      return expressionResult
    }
}
class MyClass(myValue: ValueType) {  // set value
  var myValue = myValue
  [private] set(value) {
    foo = value
  }
}

Dedičnosť

open calss MyParentClass(protected val myOirginalVale: ValueType) {
  …
}
class MyChildClass(myOirginalVale: ValueType, private var myOtherValue: ValueType) : MyParentClass(myOirginalVale) {
  …
  init {
    this.myOtherValue = myOtherValue
  }
}

Polymorfizmus

stejné meno metódy v dcérskej triede ako v materskej, ale iná funkcia

Companion objects - statika

class MyClass() {
  …
  companion object {
    val myValue = anyValue
    private var myLocalValue = anyValue
    fun myMethod(…): returnValueType { … }
  }
}

Privátny konštruktor

statická trieda - objekt, bude dostupné všade aj bez inštancie

object MyObject {
  init { … }
  val/var/fun …
}

Rozhranie

rozhranie:
interface MyInterface {
  fun anyFunction()
}
základná trieda:
class MyClass: MyInterface {
  override fun anyFunction() {
    …
  }
}
volanie:
val myClass: MyInterface = MyClass()

viacnásobná dedičnosť

ďalšie rozhranie:
interface NextInterface {
  fun nextFunction()
}
ďalšia trieda:

klik na žiarovku → Implement members

class NextClass: MyInterface, NextInterface {
  override fun anyFunction() {
    …
  }
  override fun nextFunction() {
    …
  }
}
volanie:
val nextClass = NextClass()
volanie1:
val myClass: MyInterface = NextClass()

pretypovanie

val myClass: MyInterface = NextClass()
ok volanie:
myClass.anyFunction()
chybné volanie:
myClass.nextFunction()
ok volanie - pretypované:
(myClass as NextClass).nextFunction()
iné:
- if (myClass is MyClass) { … }
- (myClass as MyClass).anyFunction()

Abstraktná trieda

Porovnanie objektov

Preťažovanie operátorov

Enum - výčtový typ

rozširenie enum o metódy:
enum class MyEnum {
  MyStatus1 {
    override fun toString(): String {
      return “anyString1”
    }
  },
  MyStatus2 {
    override fun toString(): String {
      return “anyString2”
    }
  }
}
prípadne:
enum class MyEnum(private val text: String) {  // ! (private val text: String) je konštruktor ktorý vytvára v triede inštanciu
  MyStatus1(“anyString1”),
  MyStatus2(“anyString2”);
  override fun toString(): String {
    return text
  }
}

Set - množina

private var myEnum: Set<MyEnum>
init {
  myEnum(MyEnum.MyStatus1, MyEnum.MyStatus2)
}
myEnum += MyEnum.MyStatusN
myEnum -= MyEnum.MyStatusN
if (myEnum.contains(MyStatus1)) { … }

Konštanty

class MyClass {
  companion object {  // static, use: myClass.MY_CONST_VALUE
    const val MY_CONST_VALUE = anyValue
    // const val je nastavená pri kompilácii, val môže meniť hodnotu napríklad z konštruktoru
  }
}

Equals

if (myClass_instance1 == myClass_instance2) { … }

Klonovanie

plytká kópia - shallow copy:
rozhranie Clonable:
class MyClass(val myVal: typeVal) Clonable { … }  // Clonable je marker-interface
- clone() je protected a definuje sa v triede:
class MyClass(val myVal: typeVal) Clonable {
  public override fun clone(): Any {
    return super.clone()
  }
}
hlboká kópia - deep copy:
public fun clone(): Any {
    val obj1 = super.clone() as Obj1
    obj1.instX = obj1.instX.clone() as Obj2
    return obj1
}

Datová trieda

data class Obj1(val val1: String, …)
data class Obj1(val val1: String, …) {
  constructor(val val1: String) : this(val val1: String, “other string parameter”, …)
}
Linky:

Balíčky - packages

Metóda s premenným počtom parametrov

fun fun1(…, Ivararg vars1: ValType): ValType {
  for (item in vars1) {
    …
  }
  return result
}

Preťažovanie a prekrývanie metód

Preťažovanie metód

Prekrývanie metód

Vnorené triedy

class Obj1 {
  class Obj2 {
  }
}

Východzie parametre

fun fun1(par1: ValType, par2: ValType = anyValue) { ... }

Parametre s menom

funX(par2 = anyValue, par1 = anyValue)

Jednovýrazové funkcie

fun fun1(): ValType = anyValue + anyValue  // príklad pre sčítanie

Pomôcky

Dátum a Čas

Odporúča sa použiť LcalDateTime z Java 8, nie Date, alebo Calendar, alebo Joda-Time

získanie:
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.Month
aplikovanie:
val datumCas = LocalDateTime.of(2016, Month.APRIL, 15, 3, 15)  // dátum a čas
val datum = LocalDate.of(2016, Month.APRIL, 15)  // len dátum
val cas = LocalTime.of(3, 15, 10)  // len čas
val datumCas = LocalDateTime.now()
val datum = LocalDate.now()
val cas = LocalTime.now()
formátovanie:
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
aplikovanie:
val dateTime = LocalDateTime.now()
println(dateTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM)))
println(dateTime.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)))
println(dateTime.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.SHORT)))
println(dateTime.format(DateTimeFormatter.ofPattern("d.M.y H:m:ss")))
prevody z LocalDateTime:

https://www.itnetwork.cz/kotlin/oop/datum-a-cas-v-kotlin-uprava-a-intervaly

toLocalDate()
toLocalTime()
prevody na LocalDateTime:
val zacatek = LocalDate.of(1939, 9, 1)
val datumCas = zacatek.atStartOfDay()
val datumCas2 = zacatek.atTime(0, 0)
úpravy hodnôt:
minusDays(), minusHours(), minusMinutes(), minusMonths(), minusNanos(), minusSeconds(), minusWeeks(), minusYears()
plusDays(), plusHours(), plusMinutes(), plusMonths(), plusNanos(), plusSeconds(), plusWeeks(), plusYears()
Period a Duration:
import java.time.Period

práca s intervalom - minus(), plus() ⇒ Period a Duration Duraton je len interval bez súvisu na kalendár Pariod akceptuje prechody na letný/zimný čas

ChronoUnit:
import java.time.temporal.ChronoUnit

pre prácu s intervalom (pre Duration)

Betwen:

získanie intervalu medzi dvoma dátumami

porovnanie:
compareTo(), isAfter(), isBefore(), isEqual(), isLeapYear(), isSupported(ChronoUnit.X)
ostatné:

Instant : nanosekundy od 1.1.1970 - Instant.now() #thisDteIsBeginOfLinuxEpoch ZoneId : špecifikácia zóny - ZonedDateTime.now(ZoneId.of("America/New_York")) .ofEpochSecond() : linux timestamp = sekundy od 1.1.1970 : LocalDate.ofEpochSecond() toEpochSecond(), toEpochDay() : prevod na sekundy

Systém

Melanie času behu

po ukončení bloku measureTimeMillis {} je vrátený čas jeho trvania v milisekundách:

val runningTime = measureTimeMillis {
  dataOperation()
}
println(runningTime)

Linky

Iné vzdelávacie portály
Užitočné linky

Vzdelávacie linky

Tu sú uvedené linky na Kotlin portfolio vzdelávánie od JetBrains a Google.

Kotlin Docs - Základy (kotlinlang.org)
Kotlin Multiplatform - Začíname s KMP (kotlinlang.org)
Compose Multiplatform - Tvorba UI (jetbrains.com)
Ktor - Dokumentácia Ktor (ktor.io)
Android developers developers (developer.android.com)