Anda di halaman 1dari 16

Find romance on the beach


Advertisement

CODE > KOTLIN

Belajar Kotlin Dari Dasar: Abstract Classes,


Interfaces, Inheritance, dan Type Alias
by Chike Mgbemena 18 Oct 2017
Difficulty: Intermediate Length: Long Languages: Bahasa Indonesia

Kotlin Android SDK Java Language Fundamentals Functional Programming OOP

Mobile Development



This post is part of a series called Kotlin From Scratch.

 Kotlin From Scratch: Advanced Properties and Classes

 Kotlin From Scratch: Exception Handling

Indonesian (Bahasa Indonesia) translation by Bagus Aji Santoso (you can also view the original English
article)

Kotlin  adalah sebuah bahasa pemrograman modern yang dikompile menjadi bytecode


Java. Bahasa ini tersedia secara gratis dan open source, serta memberikan janji untuk
menjadikan koding Android lebih menyenangkan.

Di artikel sebelumnya, kita telah belajar tentang properti Kotlin seperti late-initialization,
extention, dan inline properties. Tidak hanya itu, kita juga belajar tentang advanced
classes seperti data, enum, nested, dan sealed classes di Kotlin.

Di artikel ini, kita akan melanjutkan pelajaran tentang pemrograman berorientasi objek
di Kotlin dengan mempelajari abstract classes, interfaces, dan inheritance. Sebagai
bonus, kita juga akan belajar tentang type aliases. 

1. Abstract Classes
Kotlin mendukung abstract classes—seperti di Java, mereka adalah kelas yang kita
tidak perlu membuat objeknya. Sebuah abstract class adalah kelas yang tidak utuh
atau tidak berguna tanpa adanya sublass yang konkrit (non-abstract) yang bisa dipakai
untuk membuat objek. Subclass konkrit dari sebuah abstract class mengimplementasi
semua method dan properti yang didefinisikan di dalam abstract class—jika tidak maka
subclass itu masih termasuk abstract class!

Kita membuat sebuah abstract class dengan modifier abstract (mirip seperti Java)

1 abstract class Employee (val firstName: String, val lastName: String) {


2 abstract fun earnings(): Double
3 }

Perlu dicatat bahwa tidak semua member harus abstract. Dengan kata lain, kita juga
bisa memberikan implementasi default di dalam sebuah abstract class.

1 abstract class Employee (val firstName: String, val lastName: String) {


2 // ...
3
4 fun fullName(): String {
5 return lastName + " " + firstName;
6 }
7 }

Di sini kita membuat fungsi non-abstract bernama fullName() di dalam sebuah abstract
class Employee . Kelas konkrit (subclass dari abstract class) dapat meng-override
implementasi default sebuah method abstract—namun hanya jika method tersebut
memiliki modifier open (kita akan mempelajarinya sebentar lagi)

Kita juga dapat menyimpan state di dalam abstract classes.

1 abstract class Employee (val firstName: String, val lastName: String) {


2 // ...
3 val propFoo: String = "bla bla"
4 }

Meskipun abstract class tidak memiliki method apapun, kita masih perlu membuat
sebuah subclass sebelum kita dapat membuat objek, lihat contoh di bawah.

1 class Programmer(firstName: String, lastName: String) : Employee(firstName, lastName)


2
3 override fun earnings(): Double {
4 // calculate earnings
5 }
6 }

Kelas Programmer kita meng-extends abstract class Employee . Di Kotlin kita


menggunakan karakter titik dua ( : ) bukannya kata kunci extends yang dipakai Java
untuk meng- extends sebuah kelas atau mengimplementasi sebuah interface.

Kita dapat membuat sebuah objek dengan tipe Programmer dan memanggil method-nya
di objek tadi—baik method kelas itu sendiri maupun superclass-nya (base class).

1 val programmer = Programmer("Chike", "Mgbemena")


2 println(programmer.fullName()) // "Mgbemena Chike"

Satu hal yang mungkin dapat mengejutkan pembaca adalah kemampuan untuk meng-
override sebuah properti val (immutable) dengan var (mutable).

01 open class BaseA (open val baseProp: String) {


02
03 }
04
05 class DerivedA : BaseA("") {
06
07 private var derivedProp: String = ""
08
09 override var baseProp: String
10 get() = derivedProp
11 set(value) {
12 derivedProp = value
13 }
14 }

Pastikan bahwa pembaca menggunakan fungsionalitas ini dengan bijak! Ingat bahwa
kita tidak bisa melakukan kebalikannya—meng-override properti sebuah var dengan
val .
2. Interfaces
Sebuah interface secara sederhana adalah koleksi dari method  yang memberitahu
objek apa yang harus dapat ia lakukan dan bagaimana melakukannya. (Default method
di interface merupakan fitur baru yang ditambahkan ke Java 8.) Dengan kata lain,
sebuah interface merupakan kontrak yang harus diimplementasi oleh kelas yang
mengimplementasinya. 

Sebuah interface dibuat dengan menggunakan kata kunci interface di Kotlin (mirip
dengan Java).

1 class Result
2 class Student
3
4 interface StudentRepository {
5 fun getById(id: Long): Student
6 fun getResultsById(id: Long): List<Result>
7 }

Pada kode di atas, kita mendeklarasikan sebuah interface StudentRepository . Interface


ini memiliki dua method abstract: getById() dan getResultsById() . Perlu dicatat bahwa
penggunakan kata kunci abstract di sebuah interface adalah redundan karena mereka
secara implisit sudah merupakan sebuah kelas abstract. 

Sebuah interface tidak berguna tanpa sebuah kelas yang mengimplementasinya—jadi


sekarang mari kita buah sebuah kelas yang akan mengimplementasi interface ini.

1 class StudentLocalDataSource : StudentRepository {


2 override fun getResults(id: Long): List<Result> {
3 // do implementation
4 }
5
6 override fun getById(id: Long): Student {
7 // do implementation
8 }
9 }

Di sini kita membuat sebuah kelas StudentLocalDataSource yang mengimplement


interface StudentRepository . 

Kita gunakan modifier override untuk menandai method dan properti yang ingin dibuat
ulang dari sebuah interface atau superclass—mirip seperti anotasi @Override di Java.
Ingat aturan-aturan tambahan berikut untuk interface in Kotlin:

Sebuah kelas dapat mengimplementasi interface sebanyak-banyaknya, tapi ia


hanya bisa meng-extend satu kelas (mirip dengan Java).
Modifier override wajib ditambahkan di Kotlin—tidak seperti di Java.
Seperti method, kita juga dapat mendeklarasikan properti di interface Kotlin.
Method di interface Kotlin dapat memiliki implementasi bawaan (seperti Java 8).

Mari kita lihat sebuah contoh dari method interface dengan sebuah implementasi
bawaan.

1 interface StudentRepository {
2 // ...
3 fun delete(student: Student) {
4 // do implementation
5 }
6 }

Pada kode di atas, kita menambahkan sebuah method baru delete() dengan sebuah
implementasi bawaan (meskipun saya tidak menulis apapun karena hanya sebagai
contoh).

Kita juga memiliki kebebasan untuk meng-override implementasi bawaan jika mau.

1 class StudentLocalDataSource : StudentRepository {


2 // ...
3 override fun delete(student: Student) {
4 // do implementation
5 }
6 }

Seperti yang sudah dijelaskan, interface Kotlin dapat memiliki properti—namun catat
bahwa ia tidak bisa menyimpan suatu nilai. (Meski begitu, ingat bahwa abstract
classes bisa menyimpan nilai.) Jadi pembuatan interface berikut dengan sebuah
properti akan bekerja. 

1 interface StudentRepository {
2 val propFoo: Boolean // will work
3 // ...
4 }

Namun apabila kita mencoba menambah suatu nilai pada properti tersebut, interface
itu tidak akan bekerja.
1 interface StudentRepository {
2 val propFoo: Boolean = true // Error: Property initializers are not allowed in in
3 // ..
4 }

Namun, sebuah properti interface di KOtlin dapat memiliki getter and setter (meskipun
nanti bila properti tersebut mutable). Catat juga bahwa properti di dalam sebuah
interface tidak dapat memiliki sebuah backing field.

01 interface StudentRepository {
02 var propFoo: Boolean
03 get() = true
04 set(value) {
05 if (value) {
06 // do something
07 }
08 }
09 // ...
10 }

Kita juga dapat meng-override sebuah properti interface jika mau.

01 class StudentLocalDataSource : StudentRepository {


02 // ...
03 override var propFoo: Boolean
04 get() = false
05 set(value) {
06 if (value) {
07
08 }
09 }
10 }

Mari kita lihat kasus di mana kita memiliki sebuah kelas yang mengimplementasi
beberapa interface dengan nama method yang sama. Bagaimana kelas tersebut
menentukan method milik interface mana yang akan dipanggil?

1 interface InterfaceA {
2 fun funD() {}
3 }
4
5 interface InterfaceB {
6 fun funD() {}
7 }

Di sini kita memiliki dua interface yang memiliki sebuah methode dengan nama sama
funD() . Mari kita buat sebuah kelas yang mengimplementasi dua interface ini dan
meng-override method funD() .

1 class classA : InterfaceA, InterfaceB {


2 override fun funD() {
3 super.funD() // Error: Many supertypes available, please specify the one you
4 }
5 }

Kompiler akan bingung saat memanggil super.funD() karena ada dua interface yang
diimplementasi di dalam kelas yang sama dan memiliki nama method yang sama.

Untuk menyelesaikan masalah ini, kita membungkus nama interface yang methodnya
ingin kita panggil ke dalam kurung sudut <InterfaceName> . (IntelliJ IDEA atau Android
Studio akan memberitahu cara menyelesaikan permasalahan ini).

1 class classA : InterfaceA, InterfaceB {


2 override fun funD() {
3 super<InterfaceA>.funD()
4 }
5 }

Di atas kita akan memanggil method funD() milik InterfaceA . Masalah selesai!

3. Pewarisan
Sebuah kelas baru (subclass) dibuat dengan mengambil isi kelas super dan mungkin
mendefinisikan ulang implementasi bawaannya.  Mekanisme ini dikenal dengan istilah
pewarisan dalam konsep pemrograman berorientasi objek (PBO).

Base class untuk semua kelas di Kotlin adalah Any .

1 class Person : Any {


2 }

Kelas Any mirip dengan Object yang ada di Java.

1 public open class Any {


2 public open operator fun equals(other: Any?): Boolean
3 public open fun hashCode(): Int
4 public open fun toString(): String
5 }
Kelas Any memiliki beberapa method berikut: equals() , hashcode() , dan toString()

(mirip dengan di Java).

Kelas kita tidak perlu secara eksplisit meng-extend Any. Jika tidak secara eksplisit
menentukan sebuah kelas meng-extend kelas apa, maka secara implisit ia akan meng-
extend Any . Untuk alasan ini, Anda biasanya tidak perlu menambahkan : Any di kode
yang ditulis—kita menulisnya di atas hanya untuk contoh. 

Mari kita buat kelas-kelas di Kotlin untuk membahas pewarisan. 

1 class Student {
2
3 }
4
5 class GraduateStudent : Student() {
6
7 }

Pada kode di atas kelas GraduateStudent meng-extend superclass Student . Tapi kode ini
tidak akan berjalan. Mengapa? Karena kelas dan method bernilai final secara
otomatis di Kotlin. Dengan kata lain, mereka secara otomatis tidak bisa di extend—
berbeda dengan Java di mana kelas dan method sudah terbuka secara otomatis. 

Para ahli menganjurkan untuk membuat kelas dan method final secara otomatis—
artinya jika mereka tidak secara khusus perlu di extend atau di override oleh subclass.
Tim pengembang Kotlin (JetBrains) mengaplikasikan filosofi ini dan banyak best
practice lain dalam mengembangkannya. 

Agar kita bisa membuat sebuah subclass dari sebuah superclass, maka kita perlu
secara eksplisit menandari superclass dengan modifier open . Modifier ini juga berlaku
pada semua properti superclass atau method yang dapat di override oleh subclass.

1 open class Student {


2
3 }

Kita dapat mengubah modifier open sebelum kata kunci class . Kita sekarang sudah
menginstruksikan kompiler untuk memerbolehkan kelas Student untuk di extend oleh
kelas lain. 
Seperti yang sudah dijelaskan, anggota sebuah kelas Kotlin juga final secara otomatis. 

1 open class Student {


2
3 open fun schoolFees(): BigDecimal {
4 // do implementation
5 }
6 }

Pada kode di atas, kita menandai fungsi schoolFees sebagai open —dengan begitu
subclass dapat meng-override-nya.

01 open class GraduateStudent : Student() {


02
03 override fun schoolFees(): BigDecimal {
04 return super.schoolFees() + calculateSchoolFees()
05 }
06
07 private fun calculateSchoolFees(): BigDecimal {
08 // calculate and return school fees
09 }
10 }

Di sini, fungsi schoolFees yang sudah dibuka dari superclass Student di-override oleh
kelas GraduateStudent —dengan menambahkan modifier override sebelum kata kunci
fun.  Catat bahwa jika Anda meng-override sebuah anggota dari superclass atau
interface, member yang meng-override-nya juga akan menjadi open secara otomatis
seperti pada contoh berikut:

01 class ComputerScienceStudent : GraduateStudent() {


02
03 override fun schoolFees(): BigDecimal {
04 return super.schoolFees() + calculateSchoolFess()
05 }
06
07 private fun calculateSchoolFess(): BigDecimal {
08 // calculate and return school fees
09 }
10 }

Meskipun kita tidak menandai method schoolFees() di dalam kelas GraduateStudent

dengan modifier open , kita masih dapat meng-override-nya—seperti yang kita lakukan
pada kelas ComputerScienceStudent . Jika ingin mencegah hal ini, kita harus menandai
member tadi dengan kata kunci final . 
Ingat bahwa kita bisa menambah fungsionalitas ke dalam sebuah kelas—meskipun
dideklarasikan final—menggunakan extensino functino milik Kotlin. Untuk mengingat
lagi apa itu extention function, kunjungi artikel Advanced Functions in Kotlin.  Lalu, jika
Anda memerlukan pengingat tentang bagaimana memberikan sebuah kelas final
properti baru tanpa meng-extend-nya, baca pembahasan extentions Properties di
Advanced Properties and Classes saya. 

KOTL I N

Kotlin From Scratch: Advanced Functions


Kotlin From Scratch: Advanced Functions

KOTL I N

Kotlin From Scratch: Advanced Properties and Classes


Chike Mgbemena

Jika superclass kita memiliki konstruktor utama seperti ini:

1 open class Student(val firstName: String, val lastName: String) {


2 // ...
3 }

Maka semua subclass harus memanggil konstruktor utama miliki superclass.

1 open class GraduateStudent(firstName: String, lastName: String) : Student(firstName,


2 // ...
3 }

Kita dapat membuat objek dari kelas GraduteStudent seperti biasa. 

1 val graduateStudent = GraduateStudent("Jon", "Snow")


2 println(graduateStudent.firstName) // Jon

Jika subclass ingin memanggil konstruktor superclass dari konstruktor keduanya, kita
gunakan kata kunci super (mirip dengan cara kerja konstruktor superclass di Java).

1 open class GraduateStudent : Student {


2 // ...
3 private var thesis: String = ""
4
5 constructor(firstName: String, lastName: String, thesis: String) : super(firstNam
6 this.thesis = thesis
7 }
8 }

Jika Anda perlu mengingat konstruktor di Kotlin, silahkan baca artikel Classes and
Objects saya. 

4. Bonus: Type Alias


Hal keren lain yang bisa dilakukan di Kotlin adalah memberikan sebuah alias.

Lihat contoh berikut.

1 data class Person(val firstName: String, val lastName: String, val age: Int)

Pada contoh di atas kita memberikan alias untuk String dan Int di properti milik Person
dengan modifier typealias di Kotlin. Modifier ini dipakai untuk membuat sebuah alias
dari semua jenis tipe data di Kotin—termasuk yang baru saja kita buat. 

1 typealias Name = String


2 typealias Age = Int
3
4 data class Person(val firstName: Name, val lastName: Name, val age: Age)

Seperti yang dapat Anda lihat, kita membuat sebuah alias Name dan Age untuk tipe
String dan Int .  Kita sekarang dapat menimpa firstName dan lastName
menggunakan tipe data alias Name—juga Int untuk tipe Age. Catat bahwa kita tidak
membuat tipe data baru—kita hanya membuat alias atau nama lain dari sebuah tipe
data. 
Opsi ini sangat berguna untuk memberikan pemaknaan atau semantik untuk kode
Kotlin. Jadi gunakna dengan bijak!

Kesimpulan
Di tutorial ini, Anda telah belajar tentang pemrograman berorientasi objek di Kotlin. Kita
telah membahas:

abstract classes
interfaces
inheritance
type alias

Jika Anda sudah belajar melalui seri Kotlin From Scratch kami, pastikan untuk
menuliskan kode yang dilihat dan menjalankannya ke dalam IDE. Satu tips ini sangat
baik untuk dilakukan saat belajar bahasa pemrograman baru (atau konsep
pemrograman manapun) yaitu pastikan untuk tidak sekedar membaca suatu tutorial,
tapi menuliskan dan menjalankannya!

Tutorial selanjutnya di seri Kotlin From Scratch kita akan belajar menggunakan
exception handling di Kotlin. Sampai jumpa lagi!

Untuk mempelajari bahasa Kotlin lebih lanjut, saya merekomendasikan Anda untuk
mengunjungi dokumentasi Kotlin. Atau periksa beberapa post pembuatan aplikasi
Android di sini di Envato Tuts!

ANDR O I D SDK

Java vs. Kotlin: Should You Be Using Kotlin for Android


Development?
Jessica Thornsby

JESS I C A T HORNSBY

Introduction to Android Architecture Components


Tin Megali

ANDR O I D SDK

Get Started With RxJava 2 for Android


Jessica Thornsby

Advertisement

Chike Mgbemena
Mobile Developer, Nigeria
Chike is a senior mobile application engineer—based in Lagos, Nigeria. He has a
Bachelor of Science (B.Sc.) degree in computer science from the University of
Nigeria, Nsukka (UNN). Chike enjoys building software solutions, teaching
programming technologies, learning new tricks, listening to music, and
swimming. He loves building apps for Android. He has also built solutions using
other programming technologies—such as PHP, JavaScript, NodeJS, Symfony,
and Laravel.

 chikecodes

 FEED  LIKE  FOLLOW  FOLLOW

Weekly email summary


Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on
learning about the next big thing.

Email Address

Update me weekly

TAKE YOUR
FREELANCE GAME
TO THE NEXT LEVEL

Advertisement
Translations

Envato Tuts+ tutorials are translated into other languages by our community members—you can be involved
too!

Translate this post

Powered by

0 Komentar Tuts+ Hub 


1 Masuk

Urut dari yang terbaik


 Rekomendasikan ⤤ Bagikan

Mulai diskusinya...

MASUK DENGAN
ATAU DAFTAR DISQUS ?

Nama

Jadi yang pertama berkomentar.

✉ Langganan d Pasang Disqus di websitemuTambahkan DisqusTambahkan

Rp. 7.917/b…

Rp. 7.917/bulan Rp. 7.917/b…


Advertisement

QUICK LINKS - Explore popular categories

ENVATO TUTS+ 

JOIN OUR COMMUNITY 

HELP 

26,163 1,144 25,040


Tutorials Courses Translations

Envato.com Our products Careers Sitemap

© 2018 Envato Pty Ltd. Trademarks and brands are the property of their respective owners.

Follow Envato Tuts+