Class pada Kotlin - Lanjutan
Bismillahirrahmanirrahim.
Kembali lagi kita lanjutkan pembahasan mengenai OOP (Object Oriented Programming) dan melanjutkan pembahasan mengenai class.
Properties
Property pada class atau object dibuat dengan mendefinisikan member variable dan menyediakannya accessor method. Function ini mengikuti penamaan yang biasa di mana nama dari member variable akan diawali dengan get
dan set
.
Berikut contoh program dalam Java:
class Person {
private String name;
public String getName() {
return this.name
}
public void setName(String arg) {
this.name = arg;
}
public static void main(String []args) {
Person person = new Person();
person.setName("John Doe");
System.out.println(person.getName());
}
}
Ini contoh pembuatan class Java yang mendefinsikan sebuah property yaitu name
. name
ini ditetapkan sebagai private sehingga akses pada state ini hanya dapat dikontrol melalui accessor (getName()
dan setName()
). Ini merupakan pengungkapan kodenya dalam bahasa Java karena bahasa ini tidak memiliki cara tersendiri yang mendukung properties. Kita pun dapat mengikuti cara ini di Kotlin, tapi kita tidak harus karena Kotlin memiliki dukungan untuk properties.
Contoh programnya:
class Person(_name: String) {
val name: String = _name
}
fun main() {
var person = Person("John Smith")
println(person.name)
}
Constructor diambil di dalam parameter (_name: String
). val name: String = _name
kita mmiliki akses pada parameter melalui constructor dari sini. println(person.name)
ini terlihat seperti kita melakukan akses secara langsung pada nama member variable, tetapi tidak. Ini sebenarnya memanggil accessor method get
.
Definisi class tadi dapat disederhanakan menjadi:
class Person(val name: String)
Kode di sini merupakan cara paling ringkas untuk mendefinisikan property di Kotlin. Catatan perubahan yang kita buat yaitu:
- Parameter yang ada pada primary constructor dideklarasikan dengan
val
. Ini cara yang efektif untuk membuat property pada parameter constructor. Kita dapat menggunakanvar
dan akan berfungsi dengan baik. - Kita tidak lagi harus membedakan nama identifier pada parameter constructor dengan member variable, karena itu kita menghilangkan garis bawah (
_
) pada variabel. - Kita dapat menghilangkan seluruh body dari class karena kita tidak membutuhkannya lagi. Body hanya memuat kode untuk mengirim nilai dari parameter constructor menuju member variable. Karena Kotlin akan secara otomatis mendefinisikan backing field untuk parameter constructor, kita tidak harus melakukan apa-apa lagi di dalam body dari class.
Definisi class tadi merupakan cara paling dasar untuk mendefinisikan object data di Kotlin (programmer Java mengenalnya sebagai POJO atau plain old java object). Hanya dengan menggunakan val
atau var
pada parameter constructor, secara otomatis kita dapat mendefinisikan property dengan method yang sesuai. Akan tetapi, akan ada keadaan di saat kita akan butuh kontrol yang lebih pada proses “getting” dan “setting” dari property ini, Kotlin memungkinkan kita untuk melakukannya.
Berikut cara membuatnya:
- Deklarasikan property di dalam body class, bukan di primary constructor.
- Sediakan method getter dan setter di body class.
Sintaksnya yaitu:
var <property name>: <property type> = <initializer>
<getter>
<setter>
Berikut contoh dasar penggunaan custom accessor method.
class Employee {
var name: String = ""
get() {
Log("Getting lastname")
return field
}
set(value) {
Log("Setting value of lastname")
field = value
}
}
fun Log(msg: String) {
println(msg)
}
fun main() {
var emp = Employee()
emp.name = "John Doe"
println(emp.name)
}
var name: String = ""
kita mendefinisikan property di dalam body class, daripada kita membuatnya menjadi parameter di dalam primary constructor dan kita inisialisasi sebagai String kosong terlebih dahulu. Sintaks get()
terlihat seperti sintaks untuk mendefinisikan sebuah function, namun tidak menuliskan kata kunci fun
sebelumnya. Log("Getting lastname")
, ini dimana kita menuliskan kode custom. Statement ini akan dieksekusi setiap kali seseorang mencoba untuk mengakses nama property-nya. Kata kunci field
mengacu pada backing field yang secara otomatis disediakan oleh Kotlin ketika kita mendefinisikan sebuah property bernama name
. Member variable name
bukan variabel yang sederhana, Kotlin membuatkan backing field otomatis untuknya, tetapi kita tidak memiliki akses langsung terhadap variabel tersebut. Kita dapat mengaksesnya melalui kata kunci field
. Parameter value
ini sama dengan nilai yang akan di-assign pada property setelah object Employee
dibuat (emp.name = "John Doe"
). field = value
, setelah membuat custom logic, sekarang kita dapat mengeset nilai dari field
. emp.name = "John Doe"
ini akan memicu accessor method set()
. println(emp.name)
akan memicu accessor method get()
.
Data Classes
Sebelumnya, kita telah melihat bagaimana dengan mudahnya kita dapat membuat POJO analog di Kotlin. Kita hanya mendefinisikan property di dalam class dan program pun akan jalan. Data object yang dibuat seperti itu akan cukup bagus untuk use-case sederhana. Tetapi di sataa kita memerlukan sesuatu seperti menyimpan nilai object di collection atau membandingkan object dengan yang lainnya untuk melihat kesamaan konten, maka class dengan property yang tadi tidaklah cukup. Hanya satu hal yang kita butuhkan di Kotlin yaitu membuatkan class sebuah data class. Contoh program:
data class Employee(val name: String)
fun main() {
val e1 = Employee("John Doe")
val e2 = Employee("John Doe")
println(e1)
println(e1 == e2)
}
Untuk membuatkan data class dari class apapun di Kotlin, kita hanya menggunakan kata kunci data
pada deklarasi class. println(e1)
akan mencetak output Employee(name=John Doe)
. Permbandingan ini mengembalikan nilai true
.
Visibility Modifiers
Kotlin hampir semuanya menggunakan kata kunci yang sama dengan Java untuk mengontrol visibility. Kata kunci public
, private
, dan protected
sama maksudnya di Kotlin seperti yang dilakukan di Java. Tetapi, default visibility yang dimiliki itulah yang membuat perbedaan. Di Kotlin, jika modifier visibility dihilangkan (tidak dituliskan), maka default visibility-nya adalah public. Selain class tersebut, membernya pun akan bersifat public.
Berbeda dengan Java yang mana default visibility sebuah class merupakan package-private, artinya apa yang tersedia untuk class tersebut hanya yang berada dalam package yang sama. Di Kotlin, tidak memiliki package-private sebagai persamaan karena Kotlin tidak menggunakan package sebagai cara untuk mengelola visibility. Package di Kotlin hanya sebagai cara untuk mengorganisasi file.
Sebagai ganti package-private di Java, Kotlin memperkenalkan kata kunci internal
yang artinya visible dalam sebuah module. Module ini hanya collection file dapat berupa module atau project Intellij, project Eclipse, project Maven, atau project Gradle.
Untuk menunjukkan visibility sebuah modifier, perhatikan contoh berikut.
internal open class Foo {
private fun boo() = println("boo")
protected fun doo() = println("doo")
}
fun Foo.bar() {
boo()
doo()
}
fun main() {
var fu = Foo()
fu.bar()
}
Class Foo
ditandai sebagai internal
yang membuat visibility-nya hanya di dalam class dan top-level function yang berada dalam module yang sama dan visibility-nya juga ditandai sebagai internal. fun Foo.bar()
merupakan kesalahan. Extension function ditandai sebagai public tetapi receiver dari function tersebut (Foo
) ditandai sebagai internal. Class Foo
sedikit tersembunyi daripada extension function, karenanya, Kotlin tidak mengijinkan. boo()
dan doo()
yang masing-masing private dan protected tidak dapat diakses dari sini (function Foo.bar()
).
Agar bisa diakses, class dan member-nya harus dibuat internal. Begitu pun function yang ingin mengakses member dari class, harus dibuat internal.
internal open class Foo {
internal fun boo() = println("boo")
internal fun doo() = println("doo")
}
internal fun Foo.bar() {
boo()
doo()
}
fun main() {
var fu = Foo()
fu.bar()
}
Output:
boo
doo
Access Modifier
Access modifier di Kotlin yaitu final
, open
, abstract
, dan override
. Ini mempengaruhi inheritance. Sejauh ini, hanya kata kunci abstract
yang belum digunakan. Kata kunci abstract
memiliki arti yang sama di Kotlin dan di Java, diaplikasikan pada class dan function.
Baca Class dan Object pada Kotlin
Baca juga Interface pada Kotlin
Jika class ditandai sebagai abstract maka secara mutlak ia bersifat open, sehingga kita tidak memerlukan modifier open
. Interface tidak perlu dideklarasikan sebagai abstract dan open, karena secara mutlak ia telah bersifat abstract dan open.
Object Declaration
Kata kunci static
Java tidak terdaftar sebagai kata kunci di Kotlin. Tidak ada persamaan static
ini, sebagai gantinya, Kotlin memperkenalkan kata kunci object
dan companion
. Kata kunci object
memungkinkan kita untuk mendefinisikan class dan instance-nya pada waktu yang sama. Secara lebih spesifik, ia hanya mendefinisikan satu instance dari class itu. Contoh programnya dapat dilihat berikut ini.
object Util {
fun foo() = println("foo")
}
fun main() {
Util.foo()
}
Output:
foo
Kita mengganti posisi class
dengan kata kunci object
. Efektifnya, ini mendefinisikan class dengan instance yang dapat dibuat hanya satu. Untuk memanggil function yang didefinisikan di dalam object ini, kita gunakan gunakan dot (.
) dengan nama object-nya –seperti memanggil static method di Java.
Deklarasi object dapat memuat hampir semua hal yang bisa ditulis di class, seperti initializer, property, function, dan member variable. Hanya satu hal yang tidak bisa ditulis yaitu constructor. Alasannya, karena kita tidak membutuhkan constructor. Deklarasi object membuat sebuah instance pada saat definisi, jadi constructor tidak diperlukan.
Contoh programnya:
object Util {
var name = ""
set(value) {
field = value
}
init {
println("Initializing Util")
}
fun foo() = println(name)
}
fun main() {
Util.name = "Bar"
Util.foo()
}
Output:
Bar
Referensi
- Hagos, Ted. 2018. Learn Android Studio 3 with Kotlin: Efficient Android App Development. Apress: Manila.