# Kotlin-Tutorial: Die ersten Schritte mit der neuen Programmiersprache

Erst seit 2016 mit der Version 1.0 verfügbar, dennoch bereits hoch angesehen: Kotlin, eine Alternative zu Java. Die objektbasierte Programmiersprache stammt von JetBrains, einem tschechischen Unternehmen für Software-Entwicklung. Sie überzeugt viele durch ihren **schlanken Charakter** und deshalb, weil sie nicht so oft Laufzeitfehler produziert – vor allem nicht die gefürchteten *NullPointerExceptions*. Besonders bei der Entwicklung von Android-Apps ist Kotlin sehr beliebt. Aber auch als Ausgangspunkt für JavaScript-Anwendungen erfreut sich die junge Programmiersprache enormer Beliebtheit.

Kotlin ist **eng an Java angelehnt**: Zwar sind die beiden Programmiersprachen nicht miteinander kompatibel, dennoch wird Kotlin in Bytecode transformiert, der wiederum von einer Java Virtual Machine (JVM) gelesen werden kann.

## Anleitung für Kotlin – mit Beispielen

Um mit Kotlin zu starten, kann der [Compiler von der offiziellen Website heruntergeladen werden](https://kotlinlang.org/docs/tutorials/command-line.html "Tutorial zur Installation des Kotlin-Compilers"). Einfacher geht es mit einer Entwicklungsumgebung (IDE): IntelliJ IDEA (auch von JetBrains), Eclipse (mit entsprechendem Plug-in), NetBeans und Android Studio können beispielsweise mit Kotlin umgehen.

---

### Tipp

Die Hersteller von Kotlin [halten online eine Sandbox bereit](https://play.kotlinlang.org/ "Kotlin Playground"), in der Sie alle Beispiele ausprobieren können.

---

### Pakete (Packages)

Zu Beginn eines Projekts importieren Sie die Pakete, die Sie zur Realisierung Ihres Vorhabens benötigen. Außerdem definieren Sie das Package, an dem Sie gerade arbeiten. Packages **enthalten Klassen und Funktionen**.

```none
package test.bar
import foo.bar
import footoo.bar as footoo
```

Um Probleme bei gleichen Namen zu vermeiden, können Sie Packages in Kotlin mit *as* umbenennen. Die **Namensgebung der Packages** muss nicht der Verzeichnisstruktur folgen, in der diese zu finden sind. Der Übersicht wegen empfiehlt sich aber dennoch dieses Vorgehen.

---

### Hinweis

Kotlin lädt die wichtigsten Packages automatisch in jedes Projekt.

---

Im Gegensatz zu Java können Sie bei Kotlin auch **einzelne Funktionen aus anderen Paketen importieren**. Hierfür gibt man den korrekten Pfad an:

```none
import foo.bar.myFunction
```

Anschließend kann die Funktion ganz normal verwendet werden.

---

### Tipp

Codezeilen müssen in Kotlin nicht durch eine Markierung – z. B. ein Semikolon – abgeschlossen werden.

---

### Variablen

Kotlin kennt **zwei verschiedene Arten von Variablen**: Solche, die nur gelesen werden können und festgelegt sind, werden mit *val* eingeleitet. Andere, deren Wert man im Laufe des Programms verändern kann, leiten Sie mit *var* ein.

```none
val name = "Clara Oswald"
var age = 22
```

Im Gegensatz zum feststehenden Namen kann das Alter angepasst werden, etwa in einer Funktion.

---

### Hinweis

In diesem Beispiel hat Kotlin den Typ des Werts der Variablen selbst festgelegt. Es ist auch möglich, diese Basic Types konkret auszuzeichnen.

---

### Basistypen (Basic Types)

Kotlin arbeitet mit bestimmten Typen für Variablen und Klassen. Bei jedem Typ handelt es sich um ein Objekt, und damit unterscheidet sich Kotlin etwas von Java. Während die ältere Programmiersprache primitive Typen erst in einen [Wrapper](https://www.ionos.at/digitalguide/websites/web-entwicklung/was-ist-ein-wrapper/ "Was ist ein Wrapper?") packen muss, damit sie sich wie Objekte verhalten, ist das bei Kotlin nicht nötig. Hier sind wirklich alle Typen bereits Objekte.

#### Zahlen (Numbers)

In Kotlin können Sie Zahlen ohne eine bestimmte Markierung einsetzen: Der Compiler versteht, dass es sich um Zahlenwerte halten soll. Kommas werden durch Punkte realisiert. Wer möchte, kann auch hexadezimale Zahlen verwenden. Zur besseren Lesbarkeit lassen sich Tausendertrennzeichen mit Unterstrichen darstellen. Kotlin kennt **verschiedene Arten von Zahlen**, die alle eine unterschiedliche maximale Größe annehmen können:

- Long: 64 Bit
- Int: 32 Bit
- Short: 16 Bit
- Byte: 8 Bit
- Double: 64 Bit
- Float: 32 Bit

Bei Double und Float handelt es sich um **Gleitkommazahlen**, die sich in komplexen Berechnungen anders verhalten als die Festkommazahlen. Wie alle Typen können Sie Zahlen konkret in Ihrem Code auszeichnen.

```none
val myNumber: Long = 40
```

Es ist möglich, dass Sie eine Zahl eines bestimmten Typus zu einem anderen konvertieren.

```none
val myInt = 600
val myLong= myInt.toLong()
```

Der Befehl *toLong* konvertiert den Int-Wert in einen Long-Wert. Analog funktioniert der Befehl auch abgewandelt für die anderen Typen von Numbers.

#### String

Bei einem String handelt es sich um Wörter oder ganze Sätze, also um Zeichenketten. Um diese in Kotlin zu verwenden, setzen Sie das Geschriebene in **doppelte Anführungszeichen**. Möchten Sie mehrere Zeilen Text einbauen, sind drei doppelte Anführungszeichen je zu Beginn und zum Ende nötig (Raw String).

```none
val myString = "Das ist ein einzeiliger String."
val myLongString = """Dies ist ein String,
der über mehrere Zeilen geht."""
```

Wie in vielen anderen Programmiersprachen ist in Kotlin die Verwendung von **Escape Characters** möglich: Durch einen Backslash markieren Sie ein Zeichen, das nicht zum eigentlichen String gehört, sondern als Steuerzeichen behandelt werden soll. Umgekehrt lassen sich durch den Backslash auch Zeichen in den String einfügen, die eigentlich in Kotlin eine andere Bedeutung haben. Folgende Escape Characters sind möglich:

- \\t: Tab
- \\b: Backspace
- \\n: Neue Zeile
- \\r: Carriage Return (Wagenrücklauf)
- \\': Einfaches Anführungszeichen
- \\": Doppeltes Anführungszeichen
- \\\\: Backslash
- \\$: Dollarzeichen

Das Dollarzeichen dient Ihnen in Strings dazu, **Platzhalter** einzusetzen. Diese kann man in einem vorherigen Schritt als Variable festlegen. So wird der Platzhalter dann in der Ausgabe durch einen tatsächlichen Wert ersetzt.

```none
val author = "Sandra"
val myString = "Dieser Text stammt von $author"
```

#### Zeichen (Characters)

Für einzelne Zeichen stellt Kotlin neben Strings auch den speziellen Datentyp Character zur Verfügung. Statt diese allerdings in doppelte Anführungszeichen zu setzen, verwendet man **einfache Anführungszeichen**.

```none
var model = 'A'
```

#### Boolean

Der Basic Type Boolean gibt einen Wahrheitswert wieder, der **entweder wahr (*true*) oder falsch (*false*)** sein kann.

### Arrays

In Kotlin ist ein Array eine **Sammlung von Daten**. Ein Array bilden Sie mit *arrayOf()* oder *Array()*. Die erste Funktion gestaltet sich simpel:

```none
val myArray1 = arrayOf(0, 1, 2, 3, 4, 5)
```

So erzeugt man ein Array mit den Ziffern von 1 bis 5. In diesen Sammlungen können aber auch **andere Typen** wie Strings und Booleans untergebracht werden – sogar gemischt. Möchte man das Array auf einen Typ beschränken, gibt man dies in der Funktion mit an.

```none
val myArray2 = arrayOf<int>(10, 20, 30)</int>
val myArray3 = booleanArrayOf(true, true, false)
```

Der Kotlin-Constructor *Array()* gestaltet sich komplexer: Hier müssen Sie auch die Länge und eine Lambda-Funktion angeben.

```none
val myArray4 = Array(6, { i -> i })
```

Der Constructor erzeugt ein Array mit sechs Stellen und beginnt bei null: 0, 1, 2, 3, 4, 5.

---

### Hinweis

Mehr zu Constructors und Lambdas erfahren Sie weiter unten im Text.

---

Jeder Eintrag in einem Array wird indiziert und kann über diesen **Index** aufgerufen werden. Dabei verwendet man eckige Klammern und gibt in diesen die Stelle an, die der Eintrag in der Auflistung innehat.

```none
fun main() {
	val myArray5 = arrayOf("Jan", "Maria", "Samuel")
	println(myArray5[2])
}
```

---

### Hinweis

Die Funktion wird in diesem Fall "Samuel" ausgeben, denn die Zählung beginnt mit 0.

---

### Operatoren

Wie man es aus vielen anderen Programmiersprachen kennt, arbeitet auch Kotlin mit verschiedenen Operatoren, die Sie in Ihren Quellcode einbauen können. Dazu gehören **mathematische Operatoren** (*+*, *-*, *\**, */*, *%*), **Vergleichsoperatoren** (*&lt;*, *&gt;*, *&lt;=*, *&gt;=*, *==*, *!=*) und **logische Operatoren** (*&amp;&amp;*, *||*, *!*). Eng mit den Operatoren verwandt sind sogenannte **Keywords**: Begriffe, die eine feste Bedeutung in Kotlin haben und nicht uminterpretiert werden können.

---

### Tipp

Eine [vollständige Liste aller Keywords und Operatoren](https://kotlinlang.org/docs/reference/keyword-reference.html "Eintrag in der offiziellen Dokumentation von Kotlin") finden Sie in der offiziellen Dokumentation von Kotlin.

---

### Ranges

In Kotlin beschreibt eine Range einen Typ, der von einem bestimmten Punkt bis zu einem weiteren reicht. Um eine Range zu erzeugen, wendet man den Operator *..* an oder nutzt die Funktionen *rangeTo()* bzw. *downTo()*. Die Variante mit zwei Punkten hintereinander kann hochzählen. Mit den beiden Funktionen hingegen definieren Sie in eine Richtung.

```none
val range1 = 1..5
val range2 = 1.rangeTo(5)
val range3 = 5.downTo(1)
```

In diesen einfachen Versionen erzeugen Sie eine Range mit Einer-Schritten. Um die **Schrittgröße** anzupassen, verwenden Sie zusätzlich die *step*-Funktion.

```none
val range4 = 0..10 step(2)
```

Um **einzelne Daten in der Range anzusprechen**, verwenden Sie den *in*-Operator. So können Sie beispielsweise eine Abfrage oder auch eine Schleife erzeugen. Um zu überprüfen, ob ein Wert nicht Teil der Range ist, nutzt man den Operator *!in*.

```none
val range5 = 0..10
fun main() {
	for (n in range5) {
		println(n)
	}
	if (7 in range5) {
		println("yes")
	}
	if (12 !in range5) {
		println("no")
	}
}
```

---

### Hinweis

Mehr zu Funktionen (fun), Schleifen (for) und Bedingungen (if) erfahren Sie weiter unten im Text.

---

### Funktionen (Functions)

Kotlin-Functions werden immer **mit dem Befehl *fun*** erstellt. Im Anschluss definieren Sie den Namen der Funktion, welche Argumente diese enthält und schließlich, was sie macht.

```none
fun div(a: Int, b: Int): Int {
	return a/b
}
fun main() {
	println(div(100, 2))
}
```

Wir definieren zuerst die Funktion *div* (für Division) mit zwei Int-Parametern *a* und *b*. Die Funktion soll uns das Ergebnis aus der Division von a durch b geben, ebenfalls in Form einer Int-Variablen. In der *main*-Funktion schließlich rufen wir die zuvor definierte Funktion auf, übergeben ihr konkrete Werte und lassen das Ergebnis durch *println* (print line) in der Konsole anzeigen. Kotlin führt den Inhalt von *main()* automatisch aus. Diese Funktion stellt den Einstiegspunkt in ein Kotlin-Programm dar.

---

### Fakt

Außerhalb von Funktionen akzeptiert Kotlin keine Befehle. Nur Deklarationen sind dort erlaubt.

---

In Kotlin lassen sich Functions, die nur eine Zeile Code umfassen, **vereinfacht darstellen**. Statt geschweifte Klammern zu öffnen, eine neue, eingeschobene Zeile zu schreiben und die Klammer wieder zu schließen, setzt man ein Gleichheitszeichen ein. Dabei wird zusätzlich auf den Befehl *return* verzichtet.

```none
fun div(a: Int, b: Int): Int = a/b
fun main() = println(div(100, 2))
```

Um einen Fehler durch fehlende Parameter zu vermeiden, können Sie beim Definieren der Funktion Standardwerte angeben. Lässt man beim Aufrufen der Funktion die entsprechenden Parameter frei, kommen die **Default-Werte** zum Einsatz.

```none
fun div(a: Int = 10, b: Int = 5): Int = a/b
fun main() = println(div())
```

### Lambdas

Bei einer Lambda-Funktion (oder anonymen Funktion) handelt es sich um eine Funktion, die weder zu einer Klasse noch zu einem Objekt gehört. Lambdas werden **direkt in anderen Funktionen oder Variablen untergebracht**. Man ruft sie auf, ohne das Keyword *fun* zu verwenden. Lambdas lassen sich im Prinzip wie Variablen des Typs *val* einsetzen und werden auch so erzeugt.

```none
fun main() {
	val myMessage = { println("Hello world!") }
	myMessage()
}
```

Lambda-Expressions in Kotlin müssen immer in geschweifte Klammern gesetzt werden. Lambdas können auch Funktionsargumente verarbeiten. Diese sind durch einen **Pfeil** gekennzeichnet, der die Parameter vom Kern des Ausdrucks trennt.

```none
fun main() {
    val div = {a: Int, b: Int -> a/b}
    println(div(6,2))
}
```

### Klassen (Classes)

Genau wie in Java sind Klassen in Kotlin **Sammlungen von Daten und Funktionen**. Um eine Klasse zu definieren, setzt man einfach das Stichwort *class* ein. Anschließend kann man die neue Klasse mit Informationen füllen.

```none
class Tardis {
	var year: Int
	var place: String
	constructor(year: Int, place: String) {
		this.year = year
		this.place = place
	}
}
```

In Kotlin ist der Constructor eine Funktion, die man für die Erstellung von Objekten benötigt. Dafür kennt die Programmiersprache **Primary und Secondary Constructors**. Primary Constructors sind eine praktische Kurzschreibweise, während Secondary Constructors der Schreibweise in vielen anderen objektorientierten Sprachen ähneln, darunter Java. Diese zweite Variante sehen Sie in obigem Beispiel.

Es gibt aber auch die Möglichkeit, den Secondary Constructor auszulassen und stattdessen einen Primary Constructor einsetzen. Diesen schreiben Sie direkt in die Kopfzeile der Klasse und geben dabei auch die Parameter der Klasse mit an. Dies reduziert die Anzahl der Codezeilen deutlich.

```none
class Tardis constructor(var year: Int, var place: String)
```

Wenn Sie keine zusätzlichen Angaben in Bezug auf die Sichtbarkeit der Klasse machen möchten (public, private, protected), können Sie auch ganz auf die Nennung des Keywords verzichten.

```none
class Tardis (var year: Int, var place: String)
```

Alle drei Codebeispiele erzeugen das gleiche Ergebnis.

Diese Klasse können Sie nun in Ihrem weiteren Quelltext einsetzen und mit konkreten Werten füttern.

```none
val tardis1 = Tardis(2133, "Dunlop Station")
val tardis2 = Tardis(1885, "Northhampton")
```

Wie in den meisten objektorientierten Sprachen üblich, können Sie auf die Eigenschaften und Methoden eines Objekts direkt zugreifen, indem Sie einen Punkt und den Namen der Eigenschaft oder Methode hinter den des Objekts setzen.

```none
class Tardis (var year: Int, var place: String)
val tardis1 = Tardis(2133, "Dunlop Station")
val tardis2 = Tardis(1885, "Northhampton")
fun main() {
    println(tardis1.year)
}
```

Eine Besonderheit in Kotlin stellt die **Data Class** dar. Diese Klassenart ist dazu gedacht, nur Daten zu speichern. Prinzipiell reicht hierfür eine Codezeile aus.

```none
data class User (var username: String, var name: String, var age: Int)
```

Diese Klasse kann direkt eingesetzt werden.

```none
data class User (var username: String, var name: String, var age: Int)
fun main() {
    val user1 = User ("River Song", "Melody Pond", 200)
    println("Username: " + user1.username)
    println("Name: " + user1.name)
    println("Age: " + user1.age)
}
```

### Objekte (Objects)

Objekte sind in Kotlin Instanzen, die so nur ein einziges Mal definiert sein können ([Singleton](https://www.ionos.at/digitalguide/websites/web-entwicklung/was-ist-das-singleton-pattern/ "Was ist das Singleton Pattern?")). Sie **enthalten in der Regel Variablen und Funktionen**. Man kreiert ein Objekt – ähnlich wie eine Klasse – prinzipiell mit nur einer Zeile Code. Dann ist das Objekt allerdings leer. Inhalt geben Sie dem Objekt in dessen Körper.

```none
object myObject {
	fun sum(a: Int, b: Int): Int {
		return a+b
	}
}
```

### Schleifen (Loops)

In Kotlin stehen Ihnen drei verschiedene Schleifenarten zur Verfügung: while, do..while und for. Diese verhalten sich wie ihre Äquivalente in anderen Programmiersprachen. Eine ***while*-Schleife** läuft so lang, bis eine festgelegte Bedingung eintritt.

```none
fun main() {
    var n = 1
    while (n <= 10) {
        println(n++)
    }
}
```

Die ***do..while*-Schleife** verhält sich ganz ähnlich zur Variante mit *while*. Der Unterschied liegt darin, dass der Inhalt der Schleife mindestens einmal durchlaufen wird, da die Überprüfung erst am Ende stattfindet.

```none
fun main() {
    var n = 1
    do {
        n++
    }	
    while (n < 1)
    println(n)
}
```

Die ***for*-Schleife** läuft so lang, wie eine Bedingung wahr bleibt.

```none
val myRange = 0..10
fun main() {
	for (n in myRange) {
		print("$n ")
	}
}
```

### Bedingungen (Conditions)

Kotlin kennt drei verschiedene Möglichkeiten, um bedingte Anweisungen bzw. Verzweigungen umzusetzen: if, if..else und when. Die Abfrage **if** lässt den Computer eine Aufgabe erledigen, falls die Bedingung zutrifft.

```none
val whoCompanion = arrayOf("Bill Potts", "Clara Oswald", "Amy Pond", "Martha Jones", "Donna Noble", "Rose Tyler")
fun main() {
    if ("Rose Tyler" in whoCompanion) {
        print("yes")
    }
}
```

Mit ***else*** fügen Sie eine Aktion hinzu, die ausgeführt werden soll, wenn die Bedingung nicht zutrifft.

```none
val whoCompanions9 = arrayOf("Rose Tyler")
val whoCompanions10 = arrayOf("Martha Jones", "Donna Noble", "Rose Tyler")
val whoCompanions11 = arrayOf("Clara Oswald", "Amy Pond")
val whoCompanions12 = arrayOf("Bill Potts", "Clara Oswald")
fun main() {
    var whoCompanion = "Clara Oswald"
    if (whoCompanion in whoCompanions9) {
        print("yes")
    }
    else {
        print("no")
    }
}
```

Der Ausdruck ***when*** schließlich ist eine Besonderheit von Kotlin: Abhängig von verschiedenen Zuständen werden unterschiedliche Aktionen durchgeführt. Damit ähnelt der *when*-Ausdruck dem, was in anderen Programmiersprachen *switch* löst; er arbeitet aber präziser.

Im Körper von *when* bringen Sie die unterschiedlichen Überprüfungsfälle unter. Diese stehen immer in Zusammenhang mit einer definierten Variablen.

```none
var age = 17
fun main() {
    when {
     	age > 18 -> println("Du bist zu alt!")
     	age == 18 -> println("Schon erwachsen!")
     	age == 17 -> println("Herzlich willkommen!")
     	age <= 16 -> println("Du bist zu jung!")
    }
}
```

Das Argument kann allerdings auch direkt an *when* übergeben werden und muss dann nicht jedes Mal erneut im Körper genannt werden. Darüber hinaus kann **eine einzelne Bedingung auch mehrere Aktionen auslösen**. Dafür erstellen Sie mit geschweiften Klammern einen neuen Body. Um unerwartete Fälle auszuschließen, hilft Ihnen *else*.

```none
fun multi(a: Int, b: Int, c: Int): Int {
    return a*b*c
}
fun main() {
    val d = "yes"
    when (d) {
        "no" -> println("Keine Berechnung")
        "yes" -> {
            println("Starte Berechnung") 
            println(multi(5, 2, 100))
            println("Berechnung beendet")
        }
    else -> println("Falsche Eingabe")    
    }
}
```

### Nullability

Ein großer Unmutsfaktor bei der Programmierung mit Java ist der **Fehler *NullPointerException***. Dieser tritt auf, wenn man auf ein Objekt verweist, dessen Wert *null* ist. Kotlin umgeht dieses Problem, indem es gar nicht erst zulässt, dass Variablen den Wert *null* annehmen. Sollte der Fall eintreten, erscheint schon beim Kompilieren der Hinweis: „Null can not be a value of a non-null type String“ – oder eine entsprechend andere Warnung.

Nun gibt es aber Momente, in denen möchte man den *null*-Wert bewusst einsetzen. Dafür verwendet Kotlin den **Safe Call Operator**: *?.*

```none
fun main() {
	var password: String? = null
	print(password)
}
```

Hiermit erlauben Sie Kotlin explizit, dass *null* akzeptabel ist. Das Programm wird anschließend *null* ausgeben. Möchten Sie allerdings eine bestimmte Eigenschaft der Variable ansprechen, müssen Sie den Safe Call Operator erneut einsetzen.

```none
fun main() {
	var password: String? = null
	print(password?.length)
}
```

Auch dieser Code wird wieder *null* produzieren, aber eben keinen Error – das Programm läuft. Etwas eleganter ist es, wenn Sie einen Alternativwert angeben. Dafür verwenden Sie den sogenannten **Elvis-Operator**: *?:* – so benannt, weil man die Zeichenfolge als Smiley mit Haartolle lesen kann.

```none
fun main() {
    val firstName = null
    val lastName = "Pond"
	val name: String = firstName?: "Vorname fehlt" + " " + lastName?: "Nachname fehlt"
	print(name)
}
```

In diesem Beispiel werden Hinweise angezeigt, wenn eine Variable den Wert *null* annimmt.


This is a markdown version of: [https://www.ionos.at/digitalguide/websites/web-entwicklung/kotlin-tutorial/](https://www.ionos.at/digitalguide/websites/web-entwicklung/kotlin-tutorial/) for AI/LLM consumption.