Anda di halaman 1dari 62

Pembahasan

• Data Classes
• Operator overloading
• Flow Control
• Lambdas
• Modifier
• Null safety pada Kotlin
• High-Order Function
Kelas Data
• Kelas data merupakan kelas yang mengurangi
boilerplate pada java untuk membuat POJO, sebuah
kelas yang berdiri sendiri tidak memiliki
ketergantungan dengan class lain yang digunakan
untuk memodelkan sebuah data.
• Kelas ini biasanya akan membutuhkan getters dan
setters untuk mengakses data mereka.
• Mendefinisikan kelas data sangat mudah
menggunakan Kotlin, yaitu dengan menambahkan
kata data diawal kelas.
Kelas Data

data class Cuaca (var tanggal : Date,


var suhu: Float,
var Keterangan : String){
}
Kelas Data: Fungsi Ekstra
• Bersama dengan kelas data, Anda dapat menggunakan
fungsi berikut untuk melengkapi kelas data anda:
1. equals(): Membandingkan properti dari dua objek
untuk memastikan kedua objek adalah sama.
2. hashCode(): Mendapatkan kode hash code dan
menghitun nilai dari setiap porperti objek.
3. copy(): menduplikat objek, dan memodifikasi
porperti objek jika dibutuhkan
4. Seperangkat fungsi yang digunakan untuk
memetakan objek ke dalam variabel
Kelas Data: Fungsi Ekstra
Copy()
• Ketika anda membuat objek konstan, dan anda
diharuskan untuk mengubah nilai properti dari
objek, maka anda akan membutuhkan instance
baru dan mengubah satu atau beberapa
propertinya.
• Cara diatas akan membutuhkan eksta kode yang
membutuhkan pengawasan ekstra.
• Akan tetapi, Jika anda menggunakan metode
copy(), maka akan membuat proses tersebut
menjadi lebih mudah.
Kelas Data: Fungsi Ekstra
data class Cuaca (
var wilayah: String,
var suhu: Float,
var Keterangan : String){
fun PrintData(){
println("$wilayah : $suhu\n$Keterangan")
}
}
fun main() {
val f1 = Cuaca("Medan", 27.5f, "Shiny day")
val f2 = f1.copy(suhu = 30f)
f1.PrintData();
f2.PrintData();
}

Dengan cara ini, anda dapat menduplikat objek cuaca dan


mengubah properti yang anda inginkan, tanpa mengubah
properti pada objek asli.
Kelas Data: Fungsi Ekstra
Memetakan Objek Ke Dalam Variabel

fun main() {
val f1 = Cuaca("Medan", 27.5f, " ")
var (wilayah, suhu, keterangan) = f1
println(wilayah.toString())
}

• Proses ini dikenal dengan nama declaration


destructuring, yang akan memetakan properti dari
objek menjadi variable atau map.
Kelas Data: Fungsi Ekstra
Memetakan Objek Ke Dalam Variabel
• Atau jika anda ingin mengambil properti tertentu,
anda dapat menggunakan cara berikut:
fun main() {
val f1 = Cuaca("Medan", 27.5f, " ")
val wilayah = f1.component1()
val ket = f1.component3()
println(wilayah.toString())
}

• Pengunaan fitur ini akan sangat membantu anda


untuk menyederhanakan kode di berbagai situsasi
Operator Overloading
• Kotlin memiliki sejumlah operator simbolik yang
dapat kita gunakan di kelas mana pun.
• Simbol-simbol ini memetakan suatu fungsi, yang
menyediakan logika sesuai operator yang
digunakan .
• Kelebihan pada kotlin, operator ini dapat
meningkatkan kesederhanaan kode Anda.
• Untuk memberi tahu kompilator bahwa Anda ingin
melalakukan operator overloading, Anda harus
membuat anotasi fungsi dengan operator fun.
Operator overloading
The operator Keyword
• Kotlin, menyediakan seperangkat konvensi untuk
Operator Overloading.
• Sebagai contoh, sediakan sebuah data class:

data class MyData(val umur: Int,


val nama: String) {
}
Operator overloading
The operator Keyword
• Untuk membuat Operator overloading pada kotlin ,
setiap fungsi Operator overloading harus dimulai
dengan keyword operator. Contoh, kita dapat
mengoverloding operator “+” dengan cara:
data class MyData(val umur: Int,
val nama: String) {

operator fun plus(other: MyData) : MyData =


MyData(umur + other.umur,
nama + other.nama)
}
Operator overloading
The operator Keyword
• Dengan cara ini, anda dapat menggunakan
opereator + pada objek dari kelas data anda.

fun main() {
var d1 : MyData = MyData(10,"Adi")
var d2 : MyData = MyData(1," Purnama")
var d3 : MyData = (d1+d2)
println("Nama : ${d3.nama} Umur : ${d3.umur}")
}
Operator overloading
Overloading untuk Unary Operations
• Unary operation digunakan untuk mengoperasikan
satu operand.
Unary operation
Operasi Fungsi Overloading
+a unaryPlus()
-a unaryMinus()
!a not()
a++ inc()
a-- dec()
Operator overloading
Overloading untuk Unary Operations
• Pada kelas MyData, tambahkan
operator fun unaryPlus(): MyData = MyData(umur+1,nama)

• Pada MainActivity tambahkan

fun main() {
var d1 : MyData = MyData(10,"Adi")
var d3 = +d1
println("Nama : ${d3.nama} Umur : ${d3.umur}")
}
Operator overloading
Binary operations
Overloading untuk Operasi Fungsi Overloading
Binary Operations a+b a.plus(b)
a-b a.minus(b)
• Binary operation a*b a.times(b)
digunakan untuk a/b a.div(b)
mengoperasikan dua a%b a.mod(b)
operand. a..b a.rangeTo(b)
a in b b.contains(a)
a !in b !b.contains(a)
a += b a.plusAssign(b)
a -= b a.minusAssign(b)
a *= b a.timesAssign(b)
a /= b a.divAssign(b)
a %= b a.modAssign(b)
Operator overloading
Array-like operations
• Array-like operation digunakan untuk
mengoperasikan data dalam bentuk Array.
Array-Like operations
Operasi Fungsi Overloading
a[i] get(i)
a[i, j] get(i, j)
a[i_1, …, i_n] get(i_1, …, i_n)
a[i] = b set(i, b)
a[i, j] = b set(i, j, b)
a[i_1, …, i_n] = b set(i_1, …, i_n, b)
Operator overloading
Array-like operations
Contoh

data class MyData(val umur: Int,


val nama: String ) {
operator fun plus(other: MyData) : MyData =
MyData(umur + other.umur,
nama + other.nama)
operator fun unaryPlus(): MyData = MyData(umur+1,nama)
}
class AllData(private val allData : List<MyData>){
private var Size : Int = allData.size
get() = allData.size
operator fun get(pos : Int) = allData[pos]
}
Operator overloading
Array-like operations
Contoh

fun main() {
var d1 : MyData = MyData(10,"Adi")
var d2 : MyData = MyData(11,"Firdan")
var alldata = listOf<MyData>(d1,d2);
println("Nama : ${alldata.get(1).nama} " +
"\n Umur : ${alldata.get(1).umur}")
}
Flow Control
• Flow Control bukan masalah baru untuk anda.
• Anda pasti telah sering menggunakan flow control
karena flow control merupakan cara paling berguna
dalam menyelesaikan sebuah masalah
pemrograman dengan cara yang lebih sederhana.
• Pada Kotlin, biasanya anda akan memerlukan lebih
sedikit mekanisme untuk mengontrol aliran kode
Flow Control
Ekspresi IF
• Anda dapat menggunakan ekspresi if, sama seperti
yang anda lakukan pada pemrograman java
var myValue : Int? = null
var myLong = myValue?.toLong() ?: 0L;

if(myLong > 0L){


toast("Value lebih besar dari pada 0")
}
else if(myLong == 0L){
toast("Value sama dengan 0")
}
else{
toast("Value lebih kecil daripada 0")
}
Flow Control
Ekspresi IF
• Pada Kotlin, anda tidak memerlukan operator
Trinary seperti java, karena anda dapat
menggunakan perintah if ini, untuk menginisialiasi
sebuah variable (if dapat mengembalikan sebuah
nilai):

val res = if (myValue != null) 0L else null


Flow Control
Ekspresi When
• Ekspresi When mirip dengan switch/case di Java, tetapi lebih
baik.
• When akan mencocokkan argument dengan semua kemungkinan
pilihan hingga ditemukan kriteria yang tepat, untuk melakukan
baris kode yang berada di sebelah kanan ekspresi.
• Perbedaannya, switch/case hanya dapat digunakan untuk
int,char, string, byte, short ataupun enum.
• Ekspresi When dapat digunakan untuk hampir keseluruhan objek
• When juga memberikan perintah opsional else ketika kriteria
yang diinginkan tidak ditemukan.
Flow Control
Ekspresi When

var x = 0f;
when(x){
0.0f -> println("Nol")
0.1f -> println("Nol Koma Satu")
0.2f -> println("Nol Koma Dua")
else -> {
println("Error Input")
}
}
Flow Control
Ekspresi When
• Ekspresi When juga dapat mengembalikan sebuah
nilai, tetapi tanpa perlu menggunakan keyword
return
• Pada pengembalian nilai ini, perintah else wajib
diberikan
var x = 0;
var stringKata = when(x){
0,1 -> "Binary"
else -> "Error"
}
Flow Control
Ekspresi When
• Ekspresi When juga dapat digunakan untuk
memeriksa instance dari sebuah objek, yaitu
dengan menambahkan keyword is

var stringKata = when(message){


is TextView -> "Objek Text View"
is EditText -> "Objek Edit Text"
is ImageView -> "Objek Image View"
else -> "Error"
}
Flow Control
Ekspresi When
• Ekspresi When juga dapat digunakan untuk
memeriksa dalam range nilai, yaitu dengan
menambahkan keyword in
var x =0;
var stringKata = when(x){
in 0..1 -> "Binary"
in 2..8-> "Octal"
9 -> "Desimal"
in 10..15 -> "Hexadesimal"
else -> "Error"
}
Flow Control
Ekspresi When
• Bahkan ekspresi When juga dapat digunakan untuk
memeriksa lebih dari satu argument

var x : Any = 0f;


when (x) { // 1
1 -> println("One") // 2
"Hello" -> println("Greeting") // 3
is Long -> println("Long") // 4
!is String -> println("Not a string") // 5
else -> println("Unknown") // 6
}
Flow Control
Ekspresi For
• Pada kotlin, ekspresi for berbeda dengan Java
• Pada Kotlin, ekspresi for hanya digunakan untuk iterasi
dengan format iterator (mirip foreach pada C#), dengan
sintaks:
for (item: Int in collections) {
// ...
}

• Contoh:
var collections = arrayOf(0,1,2,3,4,5)
for (item: Int in collections) {
println("$item")
}
Flow Control
Ekspresi While dan do/while
• Untuk ekspresi While dan do/while, tidak berbeda
dengan bahasa Java.
var x = 10;
while (x > 0) {
x--
}
var y = 0
do {
y++
} while (y < 10)
Flow Control
Ekspresi Range
• Eksepresi Range pada kotlin menggunakan operator dalam
bentuk “..” yang mengimplementasikan fungsi rangeTo.
• Ekspresi ini sangat membantu anda untuk
menyederhanakan baris kode anda, sebagai contoh:
if (i >= 0 && i <= 10)
println("$i")
• Anda dapat mengubahnya menjadi
if (i in 0..10)
println("$i")
Flow Control
Ekspresi Range
• Angka pada ekspresi range dapat di iterasi:
for (i in 0..10)
println("$i")

• Bagaimana dengan ekspresi range untuk


perulangan secara decrement?
Flow Control
Ekspresi Range
• Anda dapat menambahkan keyword step, untuk
menentukan besar penjumlahan pada range (default
bertambah 1):
for (i in 0..10 step 2)
println("$i")

• Atau anda dapat menganti operator “..” dengan keyword


until
for (i in 0 until 10)
println("$i")
Lambdas
• Ekspresi lambda adalah cara sederhana untuk
mendefinisikan fungsi.
• Lambdas sangat berguna karena mencegah anda
untuk menulis spesifikasi fungsi dalam kelas atau
interface atau abstrak, dan kemudian
diimplementasikan ke dalam kelas.
• Di Kotlin, lambdas berperilaku sebagai tipe: artinya
dapat dilewatkan sebagai argumen ke fungsi lain,
dapat mengembalikan nilai dari fungsi, disimpan ke
dalam variabel atau properti, dll.
Lambdas
• Pada Kotlin, anda dimungkinkan mengoptimalkan
lambda dengan menggantikan beberapa fungsi
menjadi fungsi tunggal.
• Anda dapat mendefinisikan setOnclickListener()
seperti berikut:

button1.setOnClickListener{ }

• Baris kode menjadi lebih sedikti dibandingkan


dengan kode pada bahasa java dan akan lebih
mudah dipahami.
Lambdas
//Java
Button button = (Button) findViewById(R.id.button_send);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Do something in response to button click
}
});

//Kotlin
button.setOnClickListener {
// Do something in response to button click
}
Lambda
Mendefinisikan Lambda
• Pada Kotlin lambda didefinisikan dengan sintaks:

val lambdaName : Type = { argumentList -> codeBody }

• Bagian dari lambda yang harus memiliki isi adalah bagian


codeBody.
• argumentList dapat diabaikan
• Type dapat ditentukan oleh Kotlin compiler, sehingga dapat
diabaikan.
• Var/Val juga dapat diabaikan, karena anda dapat langsung
dikirimkan sebagai argument.
Lambda
Type Inference
• Kotlin memungkinkan type dari lambda diolah oleh
kompiler, sehingga anda dapat mendefinisikan dengan cara:
var luas = { panjang: Int, lebar :Int -> panjang* lebar}
var hitung = luas(3,2)

• Jika anda ingin mengembalikan nilai dalam bentuk string,


anda dapat melakukannya dengan cara :

var keliling = { panjang: Int, lebar :Int ->


var hasil = 2 * (panjang + lebar)
hasil.toString()
}
println("${keliling(2,3)}")
Lambda
Type Declaration
• Terkadang Kotlin tidak dapat menyimpulkan tipe
data yang akan dikembalikan oleh lambda.
• Anda harus secara eksplisit mendeklarasikan tipe
untuk lambda anda, dengan cara:

var that : (Int) -> Int = { three : Int -> three }


var more : (String, Int) -> String = { str, int -> str + int }
var noReturn : (Int) -> Unit = { num -> println(num) }
Lambda
Nilai Return dari Lambda
• Jika anda memerlukan pengembalian nilai, yang
ditentukan oleh sebuah kondisi, anda dapat
membentuk Lambda dengan menambahkan fungsi dan
perintah return.
val Kelulusan = fun (nilai : Int) : String {
if (nilai < 0 || nilai > 100) {
return "Nilai error"
} else if (nilai <= 40) {
return "Gagal"
} else {
return "Lulus"
}
}
Lambda
Lambda It
• It merupakan argumen lambda yang memiliki nilai yang
mewakili setiap argumen yang diberikan ke fungsi lambda.
• Pengunaan it cocok digunakan bersamaan dengan forach
pada array. Contoh: //dekalrasi array
val array = arrayOf(1, 2, 3, 4, 5, 6)
//cara biasa
var hasil = 0
array.forEach { item ->
hasil = hasil + item * 4
}
//penggunaan it
array.forEach {
hasil = hasil + it * 4
}
Modifier
• Modifier di Kotlin sedikit berbeda dengan yang
anda pelajari di Java.
• Secara Umum, modifier pada kotlin akan dibuat
public, yang akan menghemat waktu dan
penentuan karakter data.
• Modifier di Kotlin dibagi menjadi:
• private
• protected
• internal
• public
Modifier
private
• Modifier private merupakan modifier paling
ketat, yaitu untuk memastikan hanya dapat
diakses pada file yang sama.
• Sehingga,
• Apa yang terjadi jika kelas dibuat private?
• Apa yang terjadi jika penggunaan private di dalam kelas?
Modifier
protected
Modifier ini hanya berlaku untuk anggota
kelas atau interface.
Modifier ini bekerja dengan cara yang sama
seperti di Jawa, yaitu?
Modifier
internal
• internal merupakan modifier yang
menyatakan sebuah data atau kelas hanya
dapat digunakan jika berada pada paket yang
sama
Modifier
public
• Merupakan modifier default dan akses yang
paling tidak dilindungi, yang artinya dapat
diakses di mana saja.
Modifier
Modifier pada konstraktor
• Secara umum, Konstraktor bersifat publik
• Jika anda ingin membatasi akses dari konstraktor, anda
dapat menambahkan modifier pada kelas dengan sintaks:
class myClass {
var a : Int =0
var b : Int =0
private constructor(ValueOfA: Int) {
a = ValueOfA
}
private constructor(ValueOfA: Int,ValueOfB: Int){
a = ValueOfA
b = ValueOfB
}
}
Modifier
Modifier pada fungsi dan Variable
• Secara umum, fungsi dan variable juga bersifat publik
• Jika anda ingin membatasi akses dari fungsi, anda dapat
menambahkan modifier pada fungsi dengan sintaks:
private fun getLowerNama()= nama.toLowerCase()

• Jika anda ingin membatasi akses dari variable, anda dapat


menambahkan modifier pada variable dengan sintaks:

private val konstant : Int = 10


Null safety pada Kotlin
• Null-safety merupakan fitur yang paling menarik
ketika anda datang dari bahasa Java
• Nilai null dianggap sebagai billion-dollar mistake
by its creator, walaupun kadang emang kita dapat
memeriksa apakah sebuah objek bernilai atau
kosong.
• Di Java saat ini, anda akan menggunakan bantuan
anotasi untuk memastikan objek tidak kosong.
@NotNull
MyData a = null; //akan error
public String nama = a.getLowerNama();
Null safety pada Kotlin
• Kebanyakan bahasa pemrograman modern telah
menangani masalah Null ini.
• Kotlin, the sama seperti bahasa modern lainnya
seperti Swift, menggunakan operator “?” untuk
mengidentifikasi objek null.
• Dengan cara itu, jika variable tersebut bernilai null,
compiler akan dipaksa untuk menangani hal
tersebut dengan cara dia sendiri.

var myValue : Int? = null


Null safety pada Kotlin
• Anda tetap tidak akan dapat menggunakan objek
dengan nilai null. Kode dibawah ini tidak akan
melewati Kompiler:
var myValue : Int? = null
myValue.toDouble();

• Variable boleh null, tetapi compiler akan


memastikan bahwa ada pengecekan nilai null,
sebelum anda dapat menggunakan objek tersebut.
var myValue : Int? = null
if(myValue!=null)
myValue.toDouble();
Null safety pada Kotlin
• Apakah anda harus selalu mengecek apakah objek null
atau tidak? Tidak
• Pada dasarnya, anda tidak membutuhkan objek Null,
sehingga pada pengembangan program, anda akan
baru akan menyadari objek mana yang benar-benar
memerlukan nilai, dan objek mana yang dapat bernilai
null.
• Tetapi pada Kotlin, terdapat safe call operator (?.) yang
memudahkan anda dalam menangani hal ini, contoh:
var myValue : Int? = null
myValue?.toDouble()
Null safety pada Kotlin
• Baris program sebelumnya hanya akan
dieksekusi jika variable tidak bernilai null.
• Anda juga dapat memberikan alternative
yang lebih tepat jika objek null, yaitu dengan
memberikan nilai default menggunakan Elvis
operator (?:)

var myValue : Int? = null


var myLong = myValue?.toDouble() ?: 0L;
Null safety pada Kotlin
• Kadang, anda akan menemukan situasi bahwa
objek harus bernilai non-nullable variable dari
tipe nullable.
• Anda dapat memaksa compiler untuk
menjalankan sebuah perintah dengan operator
!!
var myValue : Int? = null
var myLong = myValue!!.toDouble();

• Kode program ini akan mengakibatkan


program anda crash, jadi penggunaan operator
!! hanya dapat anda gunakan jika anda telah
memastikan objek anda bernilai non-nullable
Higher-Order Functions
• Higher-order function merupakan function yang
memanfaatkan fungsi lain(atau lambda expression)
sebagai parameter, atau mengembalikan function,
atau keduanya.
• Contoh:
val stringList: List<String> = listOf("super", "mini", "club","inn","0")
print(stringList.last())
• Fungsi last() pada koleksi merupakan standard
library untuk menampilkan data terakhir.

54
Higher-Order Functions
• Anda dapat membentuk fungsi last() sebagai
higher-order function dengan cara:
val stringList: List<String> = listOf("super", "mini", "club","inn","0")
print(stringList.last{it.length == 4})
• Higher-Order Functions pada contoh ini,
menjadikan lambda sebagai parameter kedalam
fungsi last(), yang berfungsi untuk mencari kata
dengan panjang huruf = 4

55
Higher-Order Functions
• Perhatikan fungsi ini:
fun calCircumference(radius: Double) = (2 * Math.PI) * radius
fun calArea(radius: Double): Double = (Math.PI) * Math.pow(radius, 2.0)
fun circleOperation(radius: Double, op: (Double) -> Double): Double {
val result = op(radius)
return result
}

56
Higher-Order Functions
• Lihat fungsi circleOperation(), terdiri atas 2
parameters:
• Pertama : radius bertipe Double
• op, merupakan sebuah fungsi yang menerima
parameter double dan mengembalikan returns nilai
double
• Fungsi circleOperation() ini merupakan contoh
higher-order function yang menerima fungsi
sebagai parameter.

57
Higher-Order Functions
• Untuk menggunakan fungsi circleOperation(), anda
dapat mengirimkan parameter fungsi seperti
, calArea() atau calCircumference()
• Untuk mengirimkan fungsi sebagai parameter
di circleOperation(), anda harus
menggunakan ”::” dan menghilangkan ()
• print(circleOperation(3.0, ::calArea))
• print(circleOperation(6.7, ::calCircumference))
• penggunaan higher-order functions dengan tepat,
akan membuat code anda lebih mudah dibaca dan
di mengerti.

58
Higher-Order Functions
• Lambdas and Higher-Order Functions
• Anda juga dapat mengirimkan lambda pada higher-
order function secara langsung. Contoh:
circleOperation(5.3, { (2 * Math.PI) * it })

59
Higher-Order Functions
• higher-order functions juga dapat mengembalikan
sebuah fungsi ke pemanggil
• Contoh:
• fun multiplier(factor: Double): (Double) -> Double
= { number -> number*factor }
• Fungsi di atas akan mengembalikan lambda
ekspresi yang mengembalikan type double.
• val doubler = multiplier(2)
• print(doubler(5.6)) // 11.2

60
Latihan
• Buat Extension Fungsi untuk:
• String, yang mengembalikan huruf besar untuk tiap kata
(Capitalize Each Word)
• Context, untuk membuat Toast, yang hanya
menampilkan angka
• MutableList, untuk mendapatkan nilai median
• View, mengubah tampilan dari letak text dalam
TextView, menjadi 3 pilihan, rata kiri, rata kanan, atau
center

61
Latihan
• Buat Higher-Order Functions dengan ketentuan:
• Buat fungsi isEven(int) yang mengembalikan Boolean
• Buat fungsi isOdd(int) yang mengembalikan Boolean
• Buat fungsi isPrim(int) yang mengembalikan Boolean
• Buat fungsi Higher-Order Functions untuk mengfilter
inputan ke dalam koleksi berdasarkan fungsi di atas

62

Anda mungkin juga menyukai