-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path01classesExample.kt
131 lines (111 loc) · 4.27 KB
/
01classesExample.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Classes in Kotlin
fun main() {
val c: Animal = Dog("Dog", 5, 4.5)
// Kotlin supports string interpolation, no formatting required.
println("I can directly access the properties. Name: ${c.name}, Age: ${c.age}, Size ${c.size}")
val animals = listOf(
Dog("Lara", 5, 4.5).apply { ownerName = "Alex" },
Dog("Lotte", 5, 4.5).apply { ownerName = "Kevin" },
Cat("Kevin", 1, 2.0)
)
// public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit
// an anonymous function with one parameter will wrap it to the keyword "it"
animals.forEach {
it.sayHello()
it.introduce()
}
// The data class automatically creates the following functions:
// equals, getHashCode, toString and copy
val addr = AddressData("A", "B", "C", "D", "E")
println(addr.hashCode())
// Companion objects
val factoryDog = Animal.createAnimalOfType<Dog>()
factoryDog?.sayHello()
// Object declarations
ClassRegistrations.registerClassOfType<String>()
ClassRegistrations.classRegistrations.forEach {
println(it)
}
}
// Kotlin is immutable by default.
// If we want to inherit from a class we need to declare it abstract or open
// The difference between var and val is that val is immutable and var is mutable
// For good practice you should use val as much as possible because kotlin lives the principle of immutability
// which is also a big part of most functional languages
abstract class Animal(val name: String, var age: Int, val size: Double) {
abstract fun sayHello()
fun introduce() {
println("My name is $name, my age is $age, my size is $size ${if (hasOwner) "my owner is $ownerName" else ""}")
}
// Properties with backing fields
private var _ownerName: String? = null
var ownerName: String
get() {
if (this._ownerName == null) {
return ""
}
return _ownerName!!
}
set(value) {
if (this._ownerName.isNullOrEmpty()) {
this._ownerName = value
}
}
val hasOwner: Boolean
get() = !this.ownerName.isNullOrEmpty()
// Kotlin does not have static classes like Java does.
// Companion objects are declared within a class to provide methods from a class context.
companion object Factory {
inline fun <reified T : Animal> createAnimalOfType(): Animal? {
return when (T::class) {
Dog::class -> Dog("dog", 1, 1.0)
Cat::class -> Cat("cat", 1, 1.0)
else -> null
}
}
}
}
// The class defines a default constructor and therefore we have to call him
// The colon replaces the word extends and implements for classes and interfaces
// Kotlin supports default values for parameters
class Dog(name: String = "dog", age: Int, size: Double) : Animal(name, age, size) {
override fun sayHello() {
println("Bark")
}
}
class Cat(name: String, age: Int, size: Double) : Animal(name, age, size) {
override fun sayHello() {
println("Dogs are better")
}
}
// Kotlin has a special keyword for classes that only purposes are to hold data.
// Those are called data classes
data class AddressData(
val street: String,
val houseNumber: String,
val zipCode: String,
val city: String,
val country: String
)
// Object declarations are singleton by default.
// Singletons are counted as anti pattern in general but there are cases where they make sense
object ClassRegistrations {
// Kotlin supports late initialization by default
private lateinit var registrations: ArrayList<Any>
// Kotlin got properties with getters and setters
val classRegistrations: ArrayList<Any>
get() {
// Since Kotlin 1.2 this is how you can check whether a lateinit variable is initialized already.
// As it is declared as non nullable, a null check is always true
if (!ClassRegistrations::registrations.isInitialized) {
registrations = arrayListOf()
}
return registrations
}
inline fun <reified T> registerClassOfType() {
val cls = T::class
if (!this.classRegistrations.contains(cls)) {
this.classRegistrations.add(cls)
}
}
}