Erstellt von Frank Rahn
{Abstrakt}
Seit 1992 arbeite ich als freiberuflicher unabhängiger Softwarearchitekt und -consultant.
Seitdem beschäftige ich mich mit dem Entwurf und der Realisierung von Anwendungen und verfüge über umfangreiche Erfahrungen in der Integration von Anwendungen.
Gute Programmierkenntnisse in Java 7!
Da beide Programmiersprachen auf der JVM aufbauen, werden nur die Unterschiede dargestellt.
In der Präsentation Changelog Java Versions habe ich alle Änderungen aus Sicht eines Entwicklers aufgeführt.
package de.rahn.kotlin.java;
public class Application {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
fun main(args: Array<String>): Unit {
println("Hello World!");
}
fun main(args: Array<String>) {
println("Hello World!");
}
fun main(args: Array<String>) {
println("Hello World!")
}
fun main() {
println("Hello World!")
}
fun main() = println("Hello World!")
package de.rahn.kotlin.java;
public class Application {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
Kurze Einführung in die Syntax von Kotlin
class NamedValue(val name: String, var value: Int,) {
fun print() {
println("$name = ${value + 1}")
}
}
fun start(name: String, value: Int,) {
val namedValue = NamedValue(name, value,)
namedValue.print()
namedValue.value = 10
namedValue.print()
}
fun main() = start("index", 5,)
Kurze Einführung in die Syntax von Kotlin
class NamedValue(val name: String, var value: Int,) {
fun print() {
println("$name = ${value + 1}")
}
}
fun start(name: String, value: Int,) {
val namedValue = NamedValue(name, value,)
namedValue.print()
namedValue.value = 10
namedValue.print()
val array = arrayOf(
"Frank Rahn",
"Martin Rahn",
"Gerd Rahn",
"Anita Rahn",
"Alfred Rahn",
"Ruth Rahn",
)
array.forEach { element -> println(element) }
}
fun main() = start("index", 5,)
package de.rahn.kotlin.java;
import de.rahn.kotlin.lang.TheKotlinClass;
public class TheJavaClass {
private final String name;
private final int value;
public TheJavaClass(String name, int value) {
this.name = name;
this.value = value;
System.out.println("Java: Konstruktor");
}
public void print() {
System.out.println("Java: " + name + " = " + value);
}
public static void main(String[] args) {
System.out.println("Java: Start");
TheKotlinClass theKotlinClass = new TheKotlinClass("index", 4711);
System.out.println("Java: Kotlin-Class = " + theKotlinClass);
theKotlinClass.print();
System.out.println("Java: Finish");
}
}
package de.rahn.kotlin.lang
import de.rahn.kotlin.java.TheJavaClass
class TheKotlinClass(val name: String, val value: Int) {
fun print() {
println("Kotlin: Start with $name = $value")
val theJavaClass = TheJavaClass(name, value)
println("Kotlin: Java-Class = $theJavaClass")
theJavaClass.print()
println("Kotlin: Finish")
}
}
package de.rahn.kotlin.lang
fun variables() {
var width: Int = 3840
val height = 2160
println("4K-UHD: Breite = $width, Höhe = $height")
}
fun main() = variables()
package de.rahn.kotlin.lang
fun variables() {
var width: Int = 3840
val height = 2160
println("4K-UHD: Breite = $width, Höhe = $height")
}
fun main() = variables()
package de.rahn.kotlin.lang
const val PI: Double = 3.14159
fun variables() {
var width: Int = 3840
val height = 2160
println("4K-UHD: Breite = $width, Höhe = $height")
println("Kreiszahl: $PI")
}
fun main() = variables()
package de.rahn.kotlin.lang
fun destructuringDeclarations() {
val pair = Pair("index", 4711)
println("First = ${pair.first}, Second = ${pair.second}")
val (first, second) = pair
println("First = $first, Second = $second")
println("First = ${pair.component1()}, Second = ${pair.component2()}")
val map = mapOf(pair)
for ((key, value) in map) {
println("Key = $key, Value = $value")
}
}
fun main() = destructuringDeclarations()
package de.rahn.kotlin.lang
fun destructuringDeclarations() {
val pair = Pair("index", 4711)
println("First = ${pair.first}, Second = ${pair.second}")
val (first, second) = pair
println("First = $first, Second = $second")
println("First = ${pair.component1()}, Second = ${pair.component2()}")
val map = mapOf(pair)
for ((key, value) in map) {
println("Key = $key, Value = $value")
}
for ((_, value) in map) {
println("Value = $value")
}
}
fun main() = destructuringDeclarations()
REPL: Read-eval-print Loop
$ kotlinc-jvm
Welcome to Kotlin version 1.4.10 (JRE 11.0.9+11)
Type :help for help, :quit for quit
>>> val s = "Hello World!"
>>> println(s)
Hello World!
>>> 1 + 2
res2: kotlin.Int = 3
>>> println(res2)
3
>>> :quit
package de.rahn.kotlin.lang
fun nullSafety(name: String?) {
println(name?.length)
println(name?.length ?: "x")
name?.let {
println(name.length)
}
println(name!!.length)
}
fun main() = nullSafety("Rahn") // nullSafety(null)
4
4
4
4
null
x
Exception in thread "main" java.lang.NullPointerException
at de.rahn.kotlin.lang.NullSafetyKt.nullSafety(NullSafety.kt:11)
package de.rahn.kotlin.lang
fun safeCast(value: Any?) {
val i: Int? = value as? Int
println("Int = $i")
val s: String? = value as? String
println("String = $s")
}
fun main() = safeCast("aa")
Int = null
String = aa
package de.rahn.kotlin.lang
fun safeCast(value: Any?) {
val i: Int = value as? Int ?: -1
println("Int = $i")
val s: String = value as? String ?: return
println("String = $s")
}
fun main() = safeCast(true)
Int = -1
package de.rahn.kotlin.lang
fun variables() {
var text: String = "Hallo World!"
println("Bitte das 7. Zeichen: '${text[6]}' aus '$text'")
var character: Char = text.get(6)
println(character)
text = buildString {
append("Values: ")
for (i in 1..10) {
append("$i, ")
}
}
println(text)
}
fun main() = variables()
package de.rahn.kotlin.lang
fun strings() {
val text = """
Lorem ipsum dolor sit amet,
consetetur sadipscing elitr,
sed diam nonumy eirmod tempor
WHERE path = "C:\windows\temp"
"""
println(text)
}
fun main() = strings()
......Lorem ipsum dolor sit amet, ......consetetur sadipscing elitr, ......sed diam nonumy eirmod tempor ......WHERE path = "C:\windows\temp" ....
package de.rahn.kotlin.lang
fun strings() {
val text = """
Lorem ipsum dolor sit amet,
consetetur sadipscing elitr,
sed diam nonumy eirmod tempor
WHERE path = "C:\windows\temp"
""".trimIndent()
println(text)
}
fun main() = strings()
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor WHERE path = "C:\windows\temp"
$ kotlinc-jvm
Welcome to Kotlin version 1.4.0 (JRE 11.0.8+10)
Type :help for help, :quit for quit
>>> val greetings = "Hello World!"
>>> println(greetings[10])
d
>>> println(greetings.get(10))
d
>>> println(greetings.compareTo("asdf"))
-25
>>> println(greetings.equals("Hello World!"))
true
>>> println(greetings.equals("hello world!", ignoreCase = true))
true
>>> println(greetings == "Hello World!")
true
>>> println(greetings === "Hello World!")
true
>>> println(greetings.subSequence(1, 3))
el
>>> println(greetings.substring(1, 3))
el
>>> println(greetings.substring(1..2))
el
>>> println(greetings.chunked(5))
[Hello, Worl, d!]
>>> println(greetings.capitalize())
Hello World!
>>> println(greetings.toUpperCase().decapitalize())
hELLO WORLD!
>>> println(greetings.replace(" ", ""))
HelloWorld!
>>> println(greetings.split(" "))
[Hello, World!]
>>> println(greetings.count())
12
>>> for (c in greetings) println(c)
H
e
l
l
o
W
o
r
l
d
!
>>> println(greetings.contains("Wor"))
true
>>> println(greetings.startsWith("Hello"))
true
>>> println(greetings.endsWith("World!"))
true
>>> println(greetings.indexOf("World"))
6
>>> println("%s: %02d mit %6.3f".format("Ergebnis", 2, 2.1))
Ergebnis: 02 mit 2,100
>>> :quit
$
Typ | Bytes | Minimum | Maximum |
---|---|---|---|
Byte | 1 | -128 (-27) | 127 (27 - 1) |
Short | 2 | -32768 (-215) | 32767 (215 - 1) |
Int | 4 | -231 | 231 - 1 |
Long | 8 | -263 | 263 - 1 |
val byteValue: Byte = 10
val shortValue: Short = 4711
val intValue = 4711
val longValue = 4711L
Typ | Bytes | Dezimalstellen |
---|---|---|
Float | 4 | 6-7 |
Double | 8 | 15-16 |
val floatValue = 3.14f
val doubleValue = 3.14
val doubleValue = 3.14e10
package de.rahn.kotlin.lang
fun variables() {
}
fun main() = variables()
package de.rahn.kotlin.lang
import kotlin.math.PI as PI_KOTLIN
import java.lang.Math.PI as PI_JAVA
fun variables() {
println("Kreiszahl: $PI_KOTLIN")
}
fun main() = variables()
package de.rahn.kotlin.lang
fun max(a: Int, b: Int): Int {
var max: Int
if (a > b) {
max = a
} else {
max = b
}
return max
}
fun controlFlow() {
println("max(4, 5) = ${max(4, 5)}")
}
fun main() = controlFlow()
package de.rahn.kotlin.lang
fun max(a: Int, b: Int): Int {
val max = if (a > b) {
a
} else {
b
}
return max
}
fun controlFlow() {
println("max(4, 5) = ${max(4, 5)}")
}
fun main() = controlFlow()
package de.rahn.kotlin.lang
fun max(a: Int, b: Int): Int {
return if (a > b) {
a
} else {
b
}
}
fun controlFlow() {
println("max(4, 5) = ${max(4, 5)}")
}
fun main() = controlFlow()
package de.rahn.kotlin.lang
fun max(a: Int, b: Int): Int = if (a > b) {
a
} else {
b
}
fun controlFlow() {
println("max(4, 5) = ${max(4, 5)}")
}
fun main() = controlFlow()
package de.rahn.kotlin.lang
fun max(a: Int, b: Int) = if (a > b) {
a
} else {
b
}
fun controlFlow() {
println("max(4, 5) = ${max(4, 5)}")
}
fun main() = controlFlow()
Den ternären Operation gibt es unter Kotlin nicht!
i > 0 ? "true" : "false"
Er wird durch die folgende Anweisung ersetzt.
if (i > 0) "true" else "false"
Diese Anweisung ist ausführlicher,
aber klarer.
package de.rahn.kotlin.lang
import de.rahn.kotlin.lang.classes.Circle
import de.rahn.kotlin.lang.classes.Shape
fun smartCasts() {
val shape1: Shape = Circle(radius = 1.0)
if (shape1 is Circle) {
println(shape1.radius)
}
val shape2: Shape? = null
if (shape2 is Shape) {
println(shape2.area())
}
}
fun printStringLength(x: Any) {
if (x !is String) {
return;
}
println(x.length)
}
fun main() = smartCasts()
When ersetzt die Switch von Java.
package de.rahn.kotlin.lang
enum class Status {
OK, ERROR
}
fun controlFlowWhen(y: Any) {
val b = when (y) {
is String -> true
else -> false
}
val x = 42
when (x) {
1 -> println("x ist 1")
2 -> println("x ist 2")
3, 4 -> println("x ist 3 oder 4")
in 5..10 -> println("x ist zwischen 5 und 10")
else -> println("x ist irgend etwas anderes")
}
val status = Status.OK
when (status) {
Status.OK -> println("Super")
Status.ERROR -> println("Nicht gut")
else -> return
}
when {
x < 42 -> println("-1")
x == 0 -> println("0")
x > 42 -> println("1")
else -> throw IllegalArgumentException("Mist")
}
when (val z = max(4, 5)) {
in 5..100 -> println(z - 5)
}
}
fun main() = controlFlowWhen("")
$ kotlinc-jvm
Welcome to Kotlin version 1.4.0 (JRE 11.0.8+10)
Type :help for help, :quit for quit
>>> for (i in 1..3) println(i)
1
2
3
>>> for (i in 1..3 step 2) println(i)
1
3
>>> for (i in 3 downTo 1) println(i)
3
2
1
>>> for (i in 3 downTo 1 step 2) println(i)
3
1
>>> for (i in 1 until 3) println(i)
1
2
>>> for (i in 1 until 3 step 2) println(i)
1
>>> val string = "ABC"
>>> for (c in string) println(c)
A
B
C
>>> for (i in string.indices) println(string[i])
A
B
C
>>> for ((index, value) in string.withIndex()) {
... println("Buchstabe $index ist $value")
... }
Buchstabe 0 ist A
Buchstabe 1 ist B
Buchstabe 2 ist C
>>> val array = arrayOf("Frank", "Martin", "Gerd", "Anita")
>>> for (item in array) println(item)
Frank
Martin
Gerd
Anita
>>> val map = mapOf("Köln" to "0221", "Bonn" to "0228")
>>> for ((city, areaCode) in map) println("Vorwahl von $city ist $areaCode")
Vorwahl von Köln ist 0221
Vorwahl von Bonn ist 0228
>>>
package de.rahn.kotlin.lang
fun controlFlowWhile() {
var x = 3
println("Start $x")
while (x > 0) {
x--
println(x)
}
println("Mitte $x")
do {
val y = ++x
println(x)
} while (y < 3)
println("Ende $x")
}
fun main() = controlFlowWhile()
package de.rahn.kotlin.lang
fun controlFlowBreakContinue() {
loop@ while (true) {
for (x in 1..10_000) {
when (x) {
4711 -> break@loop
6666 -> continue@loop
}
print("$x ")
}
}
println()
}
fun main() = controlFlowBreakContinue()
$ kotlinc-jvm
Welcome to Kotlin version 1.4.10 (JRE 11.0.9.1+1)
Type :help for help, :quit for quit
>>> repeat(3) { println(it) }
0
1
2
>>>
Prozedurale Programmierung
Die Top-level Funktionen können von überall aufgerufen werden
package de.rahn.kotlin.lang
fun power(base: Double, exp: Int,): Double {
var result = 1.0
for (i in 1..exp) {
result *= base
}
return result
}
fun functions() {
println(power(2.0, 8,))
}
fun main() = functions()
package de.rahn.kotlin.lang
fun square(x: Int) = x * x
fun fibonacci(n: Int): Int = when (n) {
0 -> 0
1 -> 1
else -> fibonacci(n - 1) + fibonacci(n - 2)
}
fun fakultaet(n: Int): Double = when (n) {
0 -> 1.0
else -> n * fakultaet(n - 1)
}
fun functionsSingleExpression() {
println("Doppelt ${doppelt(10)}")
println("Fibonacci ${fibonacci(10)}")
println("Fakultät ${fakultaet(10)}")
}
fun main() = functionsSingleExpression()
package de.rahn.kotlin.lang
import kotlin.math.abs
fun sin(x: Double): Double {
var result = 0.0
for (n in 0..100) {
val z = (power(-1.0, n) * power(x, 2 * n + 1)) / fakultaet(2 * n + 1)
result += z
println("n: $n -> result=$result (z=$z)")
if (abs(z) < 0.000_000_000_001) {
break
}
}
return result
}
fun functionsExplicitReturn() {
println("sin(1.0) = ${sin(1.0)}")
}
fun main() = functionsExplicitReturn()
Java: void
package de.rahn.kotlin.lang
fun functionsUnitReturning(): Unit {
println("Hello World!")
}
fun main() = functionsUnitReturning()
Java: void
package de.rahn.kotlin.lang
fun functionsUnitReturning() {
println("Hello World!")
}
fun main() = functionsUnitReturning()
package de.rahn.kotlin.lang
fun fail(reason: String): Nothing =
throw IllegalStateException("An operation is not implemented: $reason");
fun functionsNothingReturning(message: String): String {
fail(message)
return message;
}
fun main() {
functionsNothingReturning("Bla Blubber")
}
package de.rahn.kotlin.lang
fun <T> genList(a: T): List<T> = listOf(a)
fun functionsGenerics() {
println(genList(1))
println(genList("Test"))
}
fun main() = functionsGenerics()
Verwendet Tail-recursion/call oder Endrekursion
package de.rahn.kotlin.lang
import kotlin.math.abs
const val EPS = 1E-12
tailrec fun sin(x: Double, n: Int = 0, result: Double = 0.0): Double {
val m = 2 * n + 1
val z = (power(-1.0, n) * power(x, m)) / fakultaet(m)
val result2 = result + z
println("n: $n -> result=$result2 (z=$z)")
if (abs(z) < EPS) {
return result2;
}
return sin(x, n + 1, result2)
}
fun functionsTailRecursion() {
println("sin(1.0) = ${sin(1.0)}")
}
fun main() = functionsTailRecursion()
package de.rahn.kotlin.lang
fun sum(sum: Int, i: Int, reihe: Int): Int {
val vielfaches = i % reihe == 0
if (vielfaches) {
print("$i, ")
return sum + i
}
return sum
}
fun x(reihe: Int, until: Int = 100): Int {
var sum = 0
for (i in 0..until) {
sum = sum(sum, i, reihe)
}
println("Sum: $sum")
return sum
}
fun functionsDefaultNamedArgs() {
x(7)
x(reihe = 7)
x(3, until = 60)
}
fun main() = functionsDefaultNamedArgs()
package de.rahn.kotlin.lang
fun asList(vararg args: String): List<String> {
val result = mutableListOf<String>()
for (arg in args) {
result.add(arg)
}
return result
}
fun functionsVariableArgs() {
println(asList())
println(asList("aa", "bb", "cc"))
val liste = arrayOf("aa", "bb")
println(asList(*liste, "cc"))
}
fun main() = functionsVariableArgs()
package de.rahn.kotlin.lang
fun functionsLocal() {
var y = 42
fun f(x: Int): Int {
return x + y++
}
println(f(4711))
println(y)
}
fun main() = functionsLocal()
package de.rahn.kotlin.lang
class FunctionsMember {
fun function(x: Int) {
println(x)
}
}
fun functionsMember(){
FunctionsMember().function(4711)
}
fun main() = functionsMember()
Mehr zu den Member Functions bei den Klassen
package de.rahn.kotlin.lang
class FunctionsMember {
fun function(x: Int) {
privateFunction(x)
}
private fun privateFunction(x: Int) {
println(x)
}
}
fun functionsMember(){
FunctionsMember().function(4711)
}
fun main() = functionsMember()
Mehr zu den Member Functions bei den Klassen
Funktionale Programmierung
package de.rahn.kotlin.lang
fun functionsLambdas() {
val add: (Int, Int) -> Int = { a, b -> a + b }
println(add(42, 4711))
}
fun main() = functionsLambdas()
package de.rahn.kotlin.lang
fun functionsLambdas() {
val add = { a: Int, b: Int -> a + b }
println(add(42, 4711))
}
fun main() = functionsLambdas()
package de.rahn.kotlin.lang
fun higherOrderFunctionArgs(f: (a: Int, b: Int) -> Int) {
println(f(42, 4711))
}
fun higherOrderFunctionReturn(): (Int, Int) -> Int {
return { a: Int, b: Int -> a + b }
}
fun functionsHigherOrder() {
higherOrderFunctionArgs(higherOrderFunctionReturn())
higherOrderFunctionArgs({ a: Int, b: Int -> a + b })
higherOrderFunctionArgs {
a: Int, b: Int -> a + b
}
higherOrderFunctionArgs {
a, b -> a + b
}
}
fun main() = functionsHigherOrder()
$ kotlinc-jvm
Welcome to Kotlin version 1.4.10 (JRE 11.0.9.1+1)
Type :help for help, :quit for quit
>>> val array = arrayOf("Frank", "Martin", "Gerd")
>>> array.forEach({ s: String -> println(s.reversed()) })
knarF
nitraM
dreG
>>> array.forEach() { s: String -> println(s.reversed()) }
knarF
nitraM
dreG
>>> array.forEach() { s -> println(s.reversed()) }
knarF
nitraM
dreG
>>> array.forEach() { println(it.reversed()) }
knarF
nitraM
dreG
>>> array.forEach { println(it.reversed()) }
knarF
nitraM
dreG
>>> array.forEach(::println)
Frank
Martin
Gerd
>>>
package de.rahn.kotlin.lang
typealias Lambda = (Int, Int) -> Int
fun higherOrderFunctionArgs(f: Lambda) {
println(f(42, 4711))
}
fun higherOrderFunctionReturn(): Lambda {
return { a: Int, b: Int -> a + b }
}
fun functionsHigherOrder() {
higherOrderFunctionArgs(higherOrderFunctionReturn())
higherOrderFunctionArgs({ a: Int, b: Int -> a + b })
higherOrderFunctionArgs {
a: Int, b: Int -> a + b
}
higherOrderFunctionArgs {
a, b -> a + b
}
}
fun main() = functionsHigherOrder()
package de.rahn.kotlin.lang
fun anonymousFunction() {
val add = fun(a: Int, b: Int): Int { return a + b }
println(add(1, 3))
arrayOf("Frank", "Martin", "Gerd").forEach(
fun(element: String) { println(element) }
)
}
fun main() = anonymousFunction()
In Kotlin …
inline fun inlined(lambda: () -> Unit) {
println("Starting ...")
lambda()
println("Finished!")
}
fun main() {
inlined { println("Hello, World!") }
}
Im Bytecode …
fun main() {
println("Starting ...")
println("Hello, World!")
println("Finished!")
}
package de.rahn.kotlin.lang
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock
inline fun <T> lockTemplate(lock: Lock, body: () -> T): T {
lock.lock()
try {
return body()
} finally {
lock.unlock()
}
}
fun functionsInline() {
val s: String = lockTemplate(ReentrantLock()) {
"Synchronized call"
}
println(s)
}
fun main() = functionsInline()
package de.rahn.kotlin.lang
import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock
inline fun <T> lockTemplate2(noinline lock: () -> Lock, body: () -> T): T {
val lockObj = lock()
lockObj.lock()
try {
return body()
} finally {
lockObj.unlock()
}
}
fun functionsInline() {
val s: String = lockTemplate2({ ReentrantLock() }) {
"Synchronized call"
}
println(s)
}
fun main() = functionsInline()
package de.rahn.kotlin.lang
inline fun inlined2(x: Int, lambda: (Int) -> String): String {
return lambda(x)
}
fun nonLocalReturn(): Boolean {
val b = inlined2(-1) {
if (it > 0) {
return false
}
"Ok"
}
return b == "Ok"
}
fun main() = println(nonLocalReturn())
package de.rahn.kotlin.lang
inline fun inlined2(x: Int, lambda: (Int) -> String): String {
return lambda(x)
}
fun nonLocalReturn(): Boolean {
val b = inlined2(5) {
if (it > 0) {
return false
}
"Ok"
}
return b == "Ok"
}
fun main() = println(nonLocalReturn())
Non-locale returns sind hier nicht erlaubt
package de.rahn.kotlin.lang
interface Button {
fun pushMe(): String
}
inline fun controller(crossinline body: () -> String): Button {
return object : Button {
override fun pushMe() = body()
}
}
fun functionsInlineCrossinline() {
val button = controller { "pushed" }
println(button.pushMe())
}
fun main() = functionsInlineCrossinline()
break
und continue
Objektorientierte Programmierung
Eine leere Klasse …
package de.rahn.kotlin.lang.classes
class Person
fun person() {
val person = Person()
println(person)
}
fun main() = person()
… mit Body
package de.rahn.kotlin.lang.classes
class Person {
}
fun person() {
val person = Person()
println(person)
}
fun main() = person()
… mit einem primären Konstruktor
package de.rahn.kotlin.lang.classes
class Person public constructor(name: String) {
}
fun person() {
val person = Person("Müller")
println(person)
}
fun main() = person()
… ohne Modifier
package de.rahn.kotlin.lang.classes
class Person constructor(name: String) {
}
fun person() {
val person = Person("Müller")
println(person)
}
fun main() = person()
… kürzer (Normale Schreibweise)
package de.rahn.kotlin.lang.classes
class Person(name: String) {
}
fun person() {
val person = Person("Müller")
println(person)
}
fun main() = person()
… mit einem Property (Attribut, Field, …)
package de.rahn.kotlin.lang.classes
class Person(name: String) {
val lastName = name
}
fun person() {
val person = Person("Müller")
println(person.lastName)
}
fun main() = person()
… müssen immer initialisiert werden
package de.rahn.kotlin.lang.classes
class Person(name: String) {
val lastName = name
var age = -1
}
fun person() {
val person = Person("Müller")
println("${person.lastName} (${person.age})")
}
fun main() = person()
… setzen eines Properties
package de.rahn.kotlin.lang.classes
class Person(name: String) {
val lastName = name
var age = -1
}
fun person() {
val person = Person("Müller")
person.age = 10
println("${person.lastName} (${person.age})")
}
fun main() = person()
… mit sekundärem Konstruktor
package de.rahn.kotlin.lang.classes
class Person(name: String) {
val lastName = name
var age = -1
constructor(name: String, age: Int) : this(name) {
this.age = age
}
}
fun person() {
val person = Person("Müller", 20)
println("${person.lastName} (${person.age})")
}
fun main() = person()
… mit Initializer-blocks
package de.rahn.kotlin.lang.classes
class Person(name: String) {
init {
println("Init block No. 1: name=$name")
}
val lastName = name
init {
println("Init block No. 2: lastName=$lastName")
}
var age = 0
init {
age = -1
println("Init block No. 3: age=$age")
}
constructor(name: String, age: Int) : this(name) {
println("Secondary Constructor")
this.age = age
}
init {
println("Init block No. 4: age=$age")
}
}
fun person() {
val person = Person("Müller", 20)
println("Function person: ${person.lastName} (${person.age})")
}
fun main() = person()
… mit Initializer-blocks
Die Ausgabe in der Konsole
Init block No. 1: name=Müller Init block No. 2: lastName=Müller Init block No. 3: age=-1 Init block No. 4: age=-1 Secondary Constructor Function person: Müller (20)
… mit Property Definition im Konstruktor
package de.rahn.kotlin.lang.classes
class Person2(val lastName: String,) {
var age = -1
}
fun person2() {
val person = Person2("Müller")
person.age = 20
println("${person.lastName} (${person.age})")
}
fun main() = person2()
… ohne primären Konstruktor
package de.rahn.kotlin.lang.classes
class Person3 {
val lastName: String
var age: Int
constructor(lastName: String, age: Int) {
this.lastName = lastName
this.age = age
}
constructor() {
lastName = "Mustermann"
age = 30
}
}
fun person3() {
var person = Person3()
println("${person.lastName} (${person.age})")
person = Person3("Müller", 20)
println("${person.lastName} (${person.age})")
}
fun main() = person3()
… mit einem Setter
package de.rahn.kotlin.lang.classes
class Person2(val lastName: String,) {
var age = -1
set(value) {
if (value >= 18) {
age = value
}
}
}
fun person2() {
val person = Person2("Müller")
person.age = 20
println("${person.lastName} (${person.age})")
}
fun main() = person2()
Exception in thread "main" java.lang.StackOverflowError at de.rahn.kotlin.lang.classes.Person2.setAge(Person2.kt:7)
… mit einem Setter
package de.rahn.kotlin.lang.classes
class Person2(val lastName: String,) {
var age = -1
set(value) {
if (value >= 18) {
this.age = value
}
}
}
fun person2() {
val person = Person2("Müller")
person.age = 20
println("${person.lastName} (${person.age})")
}
fun main() = person2()
… mit einem Setter
package de.rahn.kotlin.lang.classes
class Person2(val lastName: String,) {
var age = -1
set(value) {
if (value >= 18) {
field = value
}
}
}
fun person2() {
val person = Person2("Müller")
person.age = 20
println("${person.lastName} (${person.age})")
}
fun main() = person2()
… mit einem Setter
package de.rahn.kotlin.lang.classes
class Person2(val lastName: String, age: Int) {
var age = -1
set(value) {
if (value >= 18) {
field = value
}
}
init {
this.age = age
}
}
fun person2() {
val person = Person2("Müller", 12)
println("${person.lastName} (${person.age})")
}
fun main() = person2()
… mit einem Getter
package de.rahn.kotlin.lang.classes
class Person2(val lastName: String,) {
var age = -1
get() = field
set(value) {
if (value >= 18) {
field = value
}
}
}
fun person2() {
val person = Person2("Müller")
person.age = 20
println("${person.lastName} (${person.age})")
}
fun main() = person2()
… Sichtbarkeit verändert (Modifiers)
package de.rahn.kotlin.lang.classes
class Person2(val lastName: String,) {
var age = -1
get() = field
private set(value) {
if (value >= 18) {
field = value
}
}
}
fun person2() {
val person = Person2("Müller")
println("${person.lastName} (${person.age})")
}
fun main() = person2()
… Sichtbarkeit verändert (Modifiers)
package de.rahn.kotlin.lang.classes
class Person2(val lastName: String,) {
var age = -1
private set
private var salary = 0
}
… Sichtbarkeit verändert (Modifiers)
package de.rahn.kotlin.lang.classes
class Person2(val lastName: String,) {
var age = -1
internal set
private var salary = 0
}
… mit Inline-Property
package de.rahn.kotlin.lang.classes
class Person2(val lastName: String,) {
var age = -1
inline set
inline var salary = 0
}
… mit Computed-Property
package de.rahn.kotlin.lang.classes
class Person2(val lastName: String) {
var age = -1
get() = field
internal set(value) {
if (value >= 18) {
field = value
}
}
val isValidAge: Boolean
get() = age >= 18
}
fun person2() {
val person = Person2("Müller")
if (!person.isValidAge) {
person.age = 20
}
println("${person.lastName} (${person.age})")
}
fun main() = person2()
… mit Annotated-Property
package de.rahn.kotlin.lang.classes
import org.springframework.beans.factory.annotation.Autowired
class Person2(val lastName: String) {
var age = -1
get() = field
internal set(value) {
if (value >= 18) {
field = value
}
}
val isValidAge: Boolean
get() = age >= 18
var dependencyInjection: Any? = null
@Autowired set
}
fun person2() {
val person = Person2("Müller")
if (!person.isValidAge) {
person.age = 20
}
println("${person.lastName} (${person.age})")
}
fun main() = person2()
… mit Lateinit-Property
package de.rahn.kotlin.lang.classes
class Person4(val lastName: String) {
private lateinit var status: String
val getStatus: String
get() {
if (!::status.isInitialized) {
status = "Ok"
}
return status
}
}
fun person4() {
val person = Person4("Müller")
println("${person.lastName} (${person.getStatus})")
}
fun main() = person4()
Die Member Functions wurden bei dem Operationsraum einer Funktion schon grundsätzlich beschrieben
package de.rahn.kotlin.lang
class FunctionsMemberInfix {
infix fun greetings(message: String) {
println(message)
}
}
fun functionsMemberInfix() {
val o = FunctionsMemberInfix()
o.greetings("Hello World!")
o greetings "Hello World!"
}
fun main() = functionsMemberInfix()
package de.rahn.kotlin.lang
fun Int.mod(x: Int) = this % x
fun Int.toString() = "Mist"
fun functionsMemberExtension() {
println(17.mod(3))
println(18.toString())
}
fun main() = functionsMemberExtension()
2 18
package de.rahn.kotlin.lang
infix fun Int.mod(x: Int) = this % x
fun Int.toString() = "Mist"
fun functionsMemberExtension() {
println(17 mod 3)
println(18.toString())
}
fun main() = functionsMemberExtension()
2 18
package de.rahn.kotlin.lang
class FunctionsMemberExtensionMember {
fun Int.print() {
println(this@FunctionsMemberExtensionMember.toString())
println(toString())
}
fun doIt(x: Int) {
x.print()
}
}
fun functionsMemberExtensionMember(){
FunctionsMemberExtensionMember().doIt(4711)
}
fun main() = functionsMemberExtensionMember()
de.rahn.kotlin.lang.FunctionsMemberExtensionMember@2f7c7260 4711
Funktion | Objektzugriff | Returnwert |
---|---|---|
obj.let {…} |
it |
Lambda Returnwert |
obj.run {…} |
this |
|
with(obj) {…} |
||
obj.apply {…} |
obj |
|
obj.also {…} |
it |
Funktion | Objektzugriff | Returnwert |
---|---|---|
run {…} |
- | Lambda Returnwert |
obj.takeIf {…} |
it |
obj or null |
obj.takeUnless {…} |
package de.rahn.kotlin.lang
fun functionsScopeLet() {
val b = "test".let {
it.isEmpty()
}
println("b: $b")
val myString: String? = "Hello World!"
myString?.let {
println("Länge myString: ${it.length}")
it.reversed()
}.let {
println("it: $it")
}
}
fun main() = functionsScopeLet()
package de.rahn.kotlin.lang
fun functionsScopeRun() {
val b = "test".run {
isEmpty()
}
println("b: $b")
val myString: String? = "Hello World!"
myString?.run {
println("Länge myString: $length")
reversed()
}.run {
println("this: $this")
}
val zahl = run {
4711
}
println("zahl: $zahl")
run {
val zahl = 100
println("$zahl: $b")
}
println("$zahl: $b")
}
fun main() = functionsScopeRun()
package de.rahn.kotlin.lang
fun functionsScopeWith() {
class User {
var name = ""
private var age = -1
}
val name = with(User()) {
name = "Frank Rahn"
println("user = $name")
name
}
println("user = $name")
}
fun main() = functionsScopeWith()
package de.rahn.kotlin.lang
fun functionsScopeApply() {
class User {
var name = ""
}
val user = User().apply {
name = "Frank Rahn"
}
println("user = ${user.name}")
}
fun main() = functionsScopeApply()
package de.rahn.kotlin.lang.classes
import org.slf4j.LoggerFactory
class User(name: String) {
private val LOGGER = LoggerFactory.getLogger(javaClass)
var name = name.apply { LOGGER.info(this) }
}
fun user() {
val user = User("Frank Rahn").apply {
name = "Martin Rahn"
}
println(user.name)
}
fun main() = user()
package de.rahn.kotlin.lang
fun functionsScopeAlso() {
class User {
var name = ""
}
val user = User().also {
it.name = "Frank Rahn"
}
println("user = ${user.name}")
}
fun main() = functionsScopeAlso()
package de.rahn.kotlin.lang
fun functionsScopeTakeIf() {
class User(val name: String)
val user = User("Frank Rahn").takeIf {
it.name.length == 7
}
println("user = $user")
}
fun main() = functionsScopeTakeIf()
package de.rahn.kotlin.lang
fun functionsScopeTakeIf() {
class User(val name: String)
val user = User("Frank Rahn").takeIf {
it.name.length == 7
}
println("user = $user")
}
fun main() = functionsScopeTakeIf()
Objektorientierte Programmierung
Die Klasse Hund soll ein Säugetier sein
package de.rahn.kotlin.lang.classes
class Saeugetier(val art: String = "Mammalia") {
val saeugtNachwuchs: Boolean
get() = true
}
class Hund(val art: String = "Canidae")
Die Klasse Hund soll ein Säugetier sein
package de.rahn.kotlin.lang.classes
open class Saeugetier(val art: String = "Mammalia") {
val saeugtNachwuchs: Boolean
get() = true
}
class Hund(val art: String = "Canidae")
Die Klasse Hund ist ein Säugetier
package de.rahn.kotlin.lang.classes
open class Saeugetier(val art: String = "Mammalia") {
val saeugtNachwuchs: Boolean
get() = true
}
class Hund(art: String = "Canidae") : Saeugetier(art)
Ein Säugetier ist ein Wirbeltier bzw. Chordatier
package de.rahn.kotlin.lang.classes
abstract class Chordatier(val art: String = "Chordata") {
val hatHerz: Boolean
get() = true
}
open class Wirbeltier(art: String = "Vertebrata")
: Chordatier(art) {
val hatWirbelsaeule: Boolean
get() = true
}
open class Saeugetier(art: String = "Mammalia")
: Wirbeltier(art) {
val saeugtNachwuchs: Boolean
get() = true
}
class Hund(art: String = "Canidae") : Saeugetier(art)
Überschreiben und abstrakte Member Funktion
package de.rahn.kotlin.lang.classes
abstract class Chordatier(val art: String = "Chordata") {
val hatHerz: Boolean
get() = true
open fun sterben() {
println("Röchel... Tot")
}
abstract fun essen()
}
open class Wirbeltier(art: String = "Vertebrata")
: Chordatier(art) {
val hatWirbelsaeule: Boolean
get() = true
override fun essen() {
TODO("Not yet implemented")
}
}
open class Saeugetier(art: String = "Mammalia")
: Wirbeltier(art) {
val saeugtNachwuchs: Boolean
get() = true
}
class Hund(art: String = "Canidae") : Saeugetier(art) {
override fun sterben() {
println("Jaulen... Tot")
}
}
package de.rahn.kotlin.lang.classes
interface Essen {
fun essen()
}
interface Sterben {
fun sterben() {
println("Röchel... Tot")
}
}
package de.rahn.kotlin.lang.classes
abstract class Chordatier(val art: String = "Chordata")
: Sterben, Essen {
val hatHerz: Boolean
get() = true
}
open class Wirbeltier(art: String = "Vertebrata")
: Chordatier(art) {
val hatWirbelsaeule: Boolean
get() = true
override fun essen() {
TODO("Not yet implemented")
}
}
class Hund(art: String = "Canidae") : Saeugetier(art) {
override fun sterben() {
println("Jaulen... Tot")
}
}
Vererbung von Interfaces und
Auflösen von Override Konflikten
package de.rahn.kotlin.lang.classes
interface Info {
fun infos(): Array<String>
}
interface Essen : Info {
fun essen()
override fun infos(): Array<String> {
return arrayOf("Muss essen")
}
}
interface Sterben : Info {
fun sterben() {
println("Röchel... Tot")
}
override fun infos(): Array<String> {
return arrayOf("Kann sterben")
}
}
abstract class Chordatier(val art: String = "Chordata")
: Sterben, Essen {
val hatHerz: Boolean
get() = true
override fun infos(): Array<String> {
return super<Sterben>.infos() +
super<Essen>.infos() +
"Hat ein Herz"
}
}
open class Wirbeltier(art: String = "Vertebrata")
: Chordatier(art) {
val hatWirbelsaeule: Boolean
get() = true
override fun essen() {
TODO("Not yet implemented")
}
override fun infos(): Array<String> {
return super.infos() +
"Hat eine Wirbelsäule"
}
}
open class Saeugetier(art: String = "Mammalia")
: Wirbeltier(art) {
val saeugtNachwuchs: Boolean
get() = true
override fun infos(): Array<String> {
return super.infos() +
"Säugt sein Nachwuchs"
}
}
Die Infos für die Klasse Hund ausgeben
package de.rahn.kotlin.lang.classes
fun tier() {
val hund = Hund()
println("Informationen über das Tier Hund:")
hund.infos().forEach {
info -> println("- $info")
}
}
fun main() = tier()
Die Ausgabe
Informationen über das Tier Hund: - Kann sterben - Muss essen - Hat ein Herz - Hat eine Wirbelsäule - Säugt sein Nachwuchs
Objektorientierte Programmierung
package de.rahn.kotlin.lang
fun objectAdHoc1(): Any {
val i = object {
val name = "Rahn"
val firstName = "Frank"
}
println("${i.firstName} ${i.name}")
return i
}
fun objectAdHoc() {
val a = objectAdHoc1()
println(a)
}
fun main() = objectAdHoc()
package de.rahn.kotlin.lang
fun objectAdHoc1(): Any {
val i = object {
val name = "Rahn"
val firstName = "Frank"
fun print() {
println("$firstName $name")
}
}
println("${i.firstName} ${i.name}")
i.print()
return i
}
fun objectAdHoc() {
val a = objectAdHoc1()
println(a)
}
fun main() = objectAdHoc()
package de.rahn.kotlin.lang.classes
class Person5(val name: String) {
private fun internPerson() = object {
val name = this@Person5.name
}
fun name(): String {
return internPerson().name
}
}
fun person5() {
val p = Person5("Frank Rahn")
println("Person=${p.name()}")
}
fun main() = person5()
package de.rahn.kotlin.lang
interface Named {
fun name(): String
}
fun newNamed(name: String): Named {
return object : Named {
override fun name(): String {
return name
}
}
}
fun objectsInterface() {
val named = newNamed("Frank Rahn")
println(named.name())
}
fun main() = objectsInterface()
package de.rahn.kotlin.lang
object ConfigurationSingleton {
private val start = System.currentTimeMillis()
val logLevel = "debug"
fun duration(): Long {
return System.currentTimeMillis() - start
}
}
fun objectsSingleton() {
println(ConfigurationSingleton.duration())
println(ConfigurationSingleton.logLevel)
Thread.sleep(1000)
println(ConfigurationSingleton.duration())
}
fun main() = objectsSingleton()
package de.rahn.kotlin.lang
class ObjectsCompanionObject {
companion object {}
}
fun objectsCompanionObject() {
println(ObjectsCompanionObject.Companion)
}
fun main() = objectsCompanionObject()
package de.rahn.kotlin.lang
class ObjectsCompanionObject {
companion object {}
}
fun objectsCompanionObject() {
println(ObjectsCompanionObject)
println(ObjectsCompanionObject.Companion)
}
fun main() = objectsCompanionObject()
package de.rahn.kotlin.lang
class ObjectsCompanionObject {
companion object Factory {}
}
fun objectsCompanionObject() {
println(ObjectsCompanionObject)
println(ObjectsCompanionObject.Factory)
}
fun main() = objectsCompanionObject()
package de.rahn.kotlin.lang
class ObjectsCompanionObject {
companion object Factory {
fun create(): ObjectsCompanionObject = ObjectsCompanionObject()
}
}
fun objectsCompanionObject() {
println(ObjectsCompanionObject)
println(ObjectsCompanionObject.Factory)
val instance = ObjectsCompanionObject.Factory.create()
println(instance)
}
fun main() = objectsCompanionObject()
package de.rahn.kotlin.lang
class ObjectsCompanionObject {
companion object Factory {
fun create(): ObjectsCompanionObject = ObjectsCompanionObject()
}
}
fun objectsCompanionObject() {
println(ObjectsCompanionObject)
println(ObjectsCompanionObject.Factory)
val instance = ObjectsCompanionObject.create()
println(instance)
}
fun main() = objectsCompanionObject()
package de.rahn.kotlin.lang
interface Factory<T> {
fun create(): T
}
class ObjectsCompanionObject {
companion object : Factory<ObjectsCompanionObject> {
override fun create(): ObjectsCompanionObject = ObjectsCompanionObject()
}
}
fun objectsCompanionObject() {
val obj: Factory<ObjectsCompanionObject> = ObjectsCompanionObject
println(obj)
}
fun main() = objectsCompanionObject()
package de.rahn.kotlin.lang
interface Factory<T> {
fun create(): T
}
class ObjectsCompanionObject {
companion object : Factory<ObjectsCompanionObject> {
override fun create(): ObjectsCompanionObject = ObjectsCompanionObject()
}
object Constants {
val defaultInstanz = create()
}
}
fun objectsCompanionObject() {
val obj: Factory<ObjectsCompanionObject> = ObjectsCompanionObject
println(obj)
println(ObjectsCompanionObject.Constants.defaultInstanz)
}
fun main() = objectsCompanionObject()
Dieses Werk ist unter der Creative-Commons-Lizenz vom Typ Namensnennung - Keine Bearbeitungen 4.0 International lizenziert.
Um eine Kopie dieser Lizenz einzusehen, besuchen Sie https://creativecommons.org/licenses/by-nd/4.0/deed.de oder schreiben Sie einen Brief an Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.