Kotlin
As explaines by freeCodeCamp.org and https://kotlinlang.org/docs/
Variables and Constants
val width: Int = 100 //constant
val width = 100 //constant
var name = "Test" //variable
var greeting: String? = null //nillable
Control structures
var greeting: String? = null //nillable
if (greeting != null){
print(greeting)
} else{
print("Hi")
}
var greeting: String? = null //nillable
when(greeting){
null -> print("Hi")
else -> print(greeting)
}
val gretingToPrint = if(greeting != null) greeting else "Hi"
print(gretingToPrint)
val gretingToPrint = when(greeting){
null -> "Hi"
else -> greeting
}
print(gretingToPrint)
Functions
fun getGreeting(name: String?): String {
return "Hello Kotlin"
}
fun sayHello(): Unit { // basically void
printl(getGreeting)
}
fun sayHello() { // still void
printl(getGreeting)
}
fun getGreeting(name: String?): String? {
retrun null
}
fun getGreeting(): = "Hello World" // single expression function
fun sayHello(name: String?):{
val msg = "Hello "+name
print(msg)
}
fun sayHello(name: String?):{
print("Hello $name") // a string template
}
fun sayHello(greeting: String, name: String?) = print("$greeting $name")
☝️ Toplevel functions/free functions exist outside of classes.
fun sayHello(greeting: String, names: List<String>)}{
names.forEach{ item ->
print("$greeting $item")
}
}
names = listOf("A", "B")
sayHello("Hi", names) //parameter names must be set
vararg
fun sayHello(greeting: String, vararg names: String}{
names.forEach{ item ->
print("$greeting $item")
}
}
names = listOf("A", "B")
sayHello("Hi") //works
sayHello("Hi", "A", "B", "C") //works
spread operator
names = arrayOf("A", "B")
sayHello("Hi", *names) //spread operator
named arguments
func greetPerson(greeting: String, name: String) = println("$greeting $name")
greetPerson("Hi", "Hans")
greetPerson(greeting = "Hi", name = "Hans")
default parameters
fun sayHello(greeting: String = "Hello", vararg names: String = "Kotlin"}{
names.forEach{ item ->
print("$greeting $item")
}
}
sayHello(name = "Hans")
sayHello()
sayHello(greeting: “Hi”, ar )
Types
https://kotlinlang.org/docs/
Byte
Short
Int
Long
Float
Double
UByte
UShort
UInt
ULong
Boolean
Char
String
Array
Complex Types
Collections and Iteration
Array
List
Map
val ar = arrayOf("Val1", "Val2")
print(ar.size)
print(ar[0])
print(ar.get(0))
for (a in ar) {
print(a)
}
ar.forEach {
print(it) //it is the default name
}
ar.forEach { variableName ->
print(variableName)s
}
ar.forEachIndexed { idx,variableName ->
print(" $idx $variableName")
}
val ar = listOf("Val1", "Val2")
print(ar.size)
print(ar[0])
print(ar.get(0))
ar.forEach {
print(it) //it is the default name
}
val map = mapOf( 1 to "a", 2 to "b", 3 to "c")
map.forEach{ key,value ->
print("$key -> $value")
}
☝️ Mutable and inmutable collection types.
val ar = listOf("Val1", "Val2") //not mutable by default
val ar = mutuableListOf("Val1", "Val2")
ar.add("Bla")
val map = mutableMapOf( 1 to "a", 2 to "b", 3 to "c")
ar.put(4 to "d")
val ar = listOf("Val1", "Val2") //not mutable by
fun sayHello(greeting:String, names:List<String>)}{
names.forEach{ item ->
print("$greeting $item")
}
}
sayHello("Hi", ar )
Classes
class Person {
}
equals
class Person
equals
class Person constructor()
equals
class Person()
val person = Person() //default constructor
Constructors
class Person(_firstName: String, _lastName: String)
val person = Person("Hans", "Peter")
class Person(_firstName: String, _lastName: String){
val firstName: String
val lastName: String
init{ // init block, multiple are possible
firstname = _firstName
lastname = _lastName
}
}
val person = Person("Hans", "Peter")
class Person(_firstName: String, _lastName: String){
val firstName: String = _firstName
val lastName: String = _lastName
}
val person = Person("Hans", "Peter")
print(person.firstName)
Property access syntax, no getter/setters needed.
class Person(val firstName: String, val lastName: String){
}
val person = Person("Hans", "Peter")
print(person.firstName)
Secondary constructor
class Person(val firstName: String, val lastName: String){
constructor(): this("Default", "Name"){
print("secondary constructor")
}
}
val person = Person()
print(person.firstName)
init vs constructor execution order
class Person(val firstName: String, val lastName: String){
init{
print("Init 1")
}
constructor(): this("Default", "Name"){
print("secondary constructor")
}
init{
print("Init 2")
}
}
val person = Person("A", "B") // init 1 and init 2
val person = Person() // init 1, init 2, secondary constructor
class Person(val firstName: String = "Peter", val lastName: String = "Parker"){
}
val person = Person("A", "B")
val person = Person()
Class-Properties
above read-only properties
class Person(val firstName: String = "Peter", val lastName: String = "Parker"){
var nickName: String? = null
}
val person = Person()
person.nickName = "Bla" // Mutable
deafult set/get methods can be overwritten
class Person(val firstName: String = "Peter", val lastName: String = "Parker"){
var nickName: String? = null
set(value) {
field = value
print("The new nickname is $value")
}
get(){
print("Returning $field")
return field
}
}
Class-methods
class Person(val firstName: String = "Peter", val lastName: String = "Parker"){
var nickName: String? = null
set(value) {
field = value
print("The new nickname is $value")
}
get(){
print("Returning $field")
return field
}
fun printInfo(){
val nickNameToPrint = if(nickname != null) nickName else "no Nickname"
print("$firstName $nickNameToPrint $lastName")
}
}
class Person(val firstName: String = "Peter", val lastName: String = "Parker"){
var nickName: String? = null
set(value) {
field = value
print("The new nickname is $value")
}
get(){
print("Returning $field")
return field
}
fun printInfo(){
val nickNameToPrint = nickName ?: " no nickname" // elvis operator
print("$firstName $nickNameToPrint $lastName")
}
}
Visibility modifiers
public
by defaultinternal
public for modulprivate
{private|public|internal} class Person(val firstName: String = "Peter", val lastName: String = "Parker"){
{public|private|protected} var nickName: String? = null
set(value) {
field = value
print("The new nickname is $value")
}
get(){
print("Returning $field")
return field
}
{public|private|protected} fun printInfo(){
val nickNameToPrint = nickName ?: " no nickname" // elvis operator
print("$firstName $nickNameToPrint $lastName")
}
}
Interfaces
interface PersonInfoProvider{
}
equals
interface PersonInfoProvider
class BasicInfoProvider: PersonInfoProvider {
}
Function signature
interface PersonInfoProvider{
fun printInfo(person: Person)
}
class BasicInfoProvider: PersonInfoProvider {
override fun printInfo(person: Person){
person.printInfo()
}
}
val provider - BasicInfoProvider()
provider.printInfo(Person())
☝️interfaces can have default implementations
interface PersonInfoProvider{
fun printInfo(person: Person){// default implementation
person.printInfo()
}
}
class BasicInfoProvider: PersonInfoProvider {
}
val provider - BasicInfoProvider()
provider.printInfo(Person())
☝️ interfaces can have properties which can be overwritten
interface PersonInfoProvider{
val providerInfo: String
fun printInfo(person: Person){
print(providerInfo)
person.printInfo()
}
}
class BasicInfoProvider: PersonInfoProvider {
override val providerInfo: String
get() = "BasicInfoProvider"
override fun printInfo(person: Person){
super.printInfo()
print("Additional logic")
}
}
val provider - BasicInfoProvider()
provider.printInfo(Person())
Implement multiple interfaces
interface SessionInfoProvider{
fun getSessionId(): String
}
class BasicInfoProvider: PersonInfoProvier, SessionInfoProvider{}
Check interface type with
is
and!is
fun checkTypes(infoProvider: PersonInfoProvider){
if (infoProvider is SessionInfoProvider){
print("Also SessionInfoProvider")
}
}
Cast types with
as
fun checkTypes(infoProvider: PersonInfoProvider){
if (infoProvider is SessionInfoProvider){
(infoProvider as SessionInfoProvider).method()
}
}