1. Sebelum memulai
Prasyarat
- Telah terbiasa menggunakan Kotlin Playground untuk mengedit program Kotlin.
- Memahami konsep dasar pemrograman di Kotlin seperti yang dijelaskan dalam Unit 1 pada kursus ini. Secara khusus, program
main()berfungsi dengan argumen yang menampilkan nilai, variabel, jenis data, dan operasi, serta pernyataanif/else. - Mampu menetapkan class di Kotlin, membuat instance objek darinya, serta mengakses properti dan metodenya.
Yang akan Anda pelajari
- Membuat program Kotlin yang menggunakan pewarisan untuk menerapkan hierarki class.
- Memperluas class, mengganti fungsi yang sudah ada, dan menambahkan fungsi baru.
- Memilih pengubah visibilitas yang benar untuk variabel.
Yang akan Anda build
- Program Kotlin dengan berbagai jenis tempat tinggal yang diterapkan sebagai hierarki class.
Yang Anda perlukan
- Komputer dengan koneksi internet untuk mengakses Kotlin Playground
2. Apa yang dimaksud dengan hierarki class?
Wajar bagi manusia untuk mengklasifikasikan item yang memiliki properti dan perilaku serupa ke dalam beberapa grup dan bahkan membentuk beberapa jenis hierarki. Misalnya, Anda dapat memiliki kategori yang luas seperti sayuran, dan di dalamnya Anda dapat memiliki jenis yang lebih spesifik seperti polong-polongan. Di dalam polong-polongan, Anda dapat memiliki jenis yang lebih spesifik seperti kacang polong, kacang, lentil, chick pea, dan kedelai.
Contoh di atas dapat diwakili sebagai hierarki karena polong-polongan mengandung atau mewarisi semua sifat-sifat sayuran (misalnya, tanaman dan dapat dimakan). Demikian pula, kacang polong, kacang, dan lentil juga memiliki sifat polong-polongan ditambah sifat uniknya sendiri.
Mari lihat cara Anda mewakili hubungan ini dalam istilah pemrograman. Jika Anda menjadikan Vegetable sebagai class di Kotlin, Anda dapat membuat Legume sebagai turunan atau subclass dari class Vegetable. Ini berarti semua properti dan metode class Vegetable diwarisi oleh (artinya juga tersedia di) class Legume.
Anda dapat mewakili hal ini dalam diagram hierarki class seperti yang ditunjukkan di bawah ini. Anda dapat merujuk ke Vegetable sebagai induk atau superclass dari class Legume.

Anda dapat melanjutkan dan memperluas hierarki class dengan membuat subclass Legume seperti Lentil dan Chickpea. Ini akan membuat Legume sebagai turunan atau subclass Vegetable serta induk atau superclass Lentil dan Chickpea. Vegetable adalah class root atau level atas (atau dasar) dari hierarki ini.

Pewarisan di Class Android
Meskipun Anda dapat menulis kode Kotlin tanpa menggunakan class, dan Anda telah melakukannya di codelab sebelumnya, ada banyak bagian Android yang diberikan kepada Anda dalam bentuk class, seperti aktivitas, tampilan, dan kelompok tampilan. Oleh karena itu, memahami hierarki class sangat penting untuk mengembangkan aplikasi Android dan memungkinkan Anda memanfaatkan fitur yang disediakan oleh framework Android.
Misalnya, ada class View di Android yang mewakili area persegi panjang di layar dan bertanggung jawab menangani gambar dan peristiwa. Class TextView adalah subclass dari class View yang artinya TextView mewarisi semua properti dan fungsi dari class View, serta menambahkan logika khusus untuk menampilkan teks kepada pengguna.

Lebih jauh, class EditText dan Button adalah turunan dari class TextView. Kedua class tersebut mewarisi semua properti dan metode class TextView dan View, serta menambahkan logika spesifiknya sendiri. Misalnya, EditText menambahkan fungsinya sendiri untuk dapat mengedit teks di layar.
Daripada harus menyalin dan menempelkan semua logika dari class View dan TextView ke dalam class EditText, EditText hanya perlu membuat subclass dari class TextView yang selanjutnya akan membuat subclass untuk class View. Kemudian, kode dalam class EditText dapat secara khusus berfokus pada perbedaan komponen UI ini dengan tampilan lainnya.
Di bagian atas halaman dokumentasi untuk class Android di situs developer.android.com, Anda dapat melihat diagram hierarki class. Anda akan dapat melihat kotlin.Any di bagian atas hierarki karena di Kotlin, semua class memiliki superclass umum Any. Pelajari lebih lanjut di sini.

Seperti yang Anda lihat, mempelajari cara memanfaatkan pewarisan di antara class dapat membuat kode Anda lebih mudah ditulis, digunakan kembali, dibaca, dan diuji.
3. Membuat class dasar
Hierarki class tempat tinggal
Dalam codelab ini, Anda akan mem-build program Kotlin yang menunjukkan cara kerja hierarki class, menggunakan tempat tinggal (selter hunian) yang dilengkapi ruang lantai, tingkat, dan penghuni sebagai contoh.
Di bawah ini merupakan diagram hierarki class yang akan Anda buat. Di root, Anda memiliki Dwelling yang menentukan properti dan fungsi yang berlaku untuk semua tempat tinggal, mirip dengan cetak biru. Anda juga akan memiliki class untuk kabin persegi (SquareCabin), pondok bundar (RoundHut), dan menara bundar (RoundTower) yang merupakan RoundHut dengan beberapa lantai.

Class yang akan diterapkan:
Dwelling: class dasar yang mewakili selter non-spesifik yang menyimpan informasi umum untuk semua tempat tinggal.SquareCabin: kabin persegi yang terbuat dari kayu dengan area lantai persegi.RoundHut: pondok bundar yang terbuat dari jerami dengan area lantai melingkar, dan induk dariRoundTower.RoundTower: menara bundar yang terbuat dari batu dengan area lantai melingkar dan beberapa tingkat.
Membuat class Dwelling abstrak
Semua class dapat berupa class dasar dari hierarki class atau induk dari class lainnya.
Class "abstrak" adalah class yang tidak dapat dibuat instance-nya karena tidak diterapkan sepenuhnya. Anda bisa menganggapnya sebagai sketsa. Sketsa menggabungkan ide dan rencana akan sesuatu, tetapi tidak cukup informasi untuk membuatnya. Anda menggunakan sketsa (class abstrak) untuk membuat cetak biru (class) tempat Anda membuat instance objek yang sebenarnya.
Manfaat umum pembuatan superclass adalah untuk menampung properti dan fungsi yang sama untuk semua subclass-nya. Jika nilai properti dan implementasi fungsi tidak diketahui, buatlah abstrak class. Misalnya, Vegetables memiliki banyak properti yang sama dengan semua sayuran, tetapi Anda tidak dapat membuat instance sayuran non-spesifik karena tidak tahu bentuk atau warnanya. Jadi, Vegetable adalah class abstrak yang membebaskan subclass untuk menentukan detail spesifik setiap sayuran.
Deklarasi class abstrak dimulai dengan kata kunci abstract.
Dwelling akan menjadi class abstrak seperti Vegetable. Contoh class tersebut akan berisi properti dan fungsi umum untuk banyak jenis tempat tinggal, tetapi nilai properti dan detail penerapan fungsi yang tepat tidak diketahui.
- Buka Kotlin Playground di https://developer.android.com/training/kotlinplayground.
- Di editor, hapus
println("Hello, world!")di dalam fungsimain(). - Lalu, tambahkan kode ini di bawah fungsi
main()untuk membuat classabstractyang disebutDwelling.
abstract class Dwelling(){
}
Menambahkan properti bahan bangunan
Di class Dwelling ini, Anda menentukan berbagai hal yang benar untuk semua tempat tinggal, meskipun hal tersebut mungkin berbeda untuk tempat tinggal lain. Semua tempat tinggal terbuat dari bahan bangunan.
- Di dalam
Dwelling, buat variabelbuildingMaterialjenisStringuntuk mewakili bahan bangunan. Bahan bangunan tidak pernah akan berubah. Jadi, gunakanvaluntuk menjadikannya sebagai variabel yang tidak dapat diubah.
val buildingMaterial: String
- Jalankan program Anda dan error ini akan muncul.
Property must be initialized or be abstract
Properti buildingMaterial tidak memiliki nilai. Bahkan, Anda TIDAK dapat menilainya karena bangunan non-spesifik tidak dibuat dari sesuatu yang spesifik. Jadi, seperti yang ditunjukkan oleh pesan error, Anda dapat mengawali deklarasi buildingMaterial dengan kata kunci abstract untuk menunjukkan bahwa bahan bangunan tidak akan ditentukan di sini.
- Tambahkan kata kunci
abstractke dalam definisi variabel.
abstract val buildingMaterial: String
- Jalankan kode Anda, dan meskipun tidak melakukan apa pun, kode tersebut akan dikompilasi tanpa error.
- Buat instance
Dwellingdalam fungsimain()dan jalankan kode Anda.
val dwelling = Dwelling()
- Anda akan mendapatkan error karena Anda tidak dapat membuat instance class
Dwellingabstrak.
Cannot create an instance of an abstract class
- Hapus kode yang salah ini.
Kode akhir Anda sejauh ini:
abstract class Dwelling(){
abstract val buildingMaterial: String
}
Menambahkan properti kapasitas
Properti lain dari tempat tinggal adalah kapasitas, yaitu jumlah orang yang dapat tinggal di dalamnya.
Semua tempat tinggal memiliki kapasitas yang tidak berubah. Namun, kapasitas tidak dapat ditetapkan dalam superclass Dwelling. Kapasitas harus didefinisikan dalam subclass untuk jenis tempat tinggal tertentu.
- Dalam
Dwelling, tambahkan bilangan bulatabstractvalyang disebutcapacity.
abstract val capacity: Int
Menambahkan properti pribadi untuk jumlah penghuni
Semua tempat tinggal akan memiliki jumlah residents yang menghuni tempat tinggal (jumlahnya bisa kurang dari atau sama dengan capacity). Jadi, tentukan properti residents dalam superclass Dwelling untuk semua subclass yang akan diwarisi dan digunakan.
- Anda dapat membuat parameter
residentsyang diteruskan ke konstruktor classDwelling. Propertiresidentsadalahvarkarena jumlah penghuni dapat berubah setelah instance dibuat.
abstract class Dwelling(private var residents: Int) {
Perhatikan bahwa properti residents ditandai dengan kata kunci private. Private merupakan pengubah visibilitas di Kotlin yang berarti bahwa properti residents hanya terlihat oleh (dan dapat digunakan di dalam) class ini. Kode ini tidak dapat diakses dari tempat lain dalam program Anda. Anda dapat menandai properti atau metode dengan kata kunci private. Sebaliknya, jika tidak ada pengubah visibilitas yang ditentukan, properti dan metode akan bersifat public secara default dan dapat diakses dari bagian lain program Anda. Jumlah orang yang menghuni tempat tinggal biasanya merupakan informasi pribadi (dibandingkan dengan informasi bahan bangunan atau kapasitas bangunan) dan ini adalah keputusan yang wajar.
Dengan capacity dari tempat tinggal dan jumlah residents saat ini yang ditentukan, Anda dapat membuat fungsi hasRoom() untuk menentukan ketersediaan ruang untuk penghuni lain dalam tempat tinggal. Anda dapat menentukan dan mengimplementasikan fungsi hasRoom() dalam class Dwelling karena penghitungan ketersediaan ruang menggunakan formula yang sama untuk semua tempat tinggal. Ada ruang di dalam Dwelling jika jumlah residents kurang dari capacity, dan fungsi ini akan menampilkan true atau false berdasarkan perbandingan ini.
- Tambahkan fungsi
hasRoom()ke classDwelling.
fun hasRoom(): Boolean {
return residents < capacity
}
- Anda dapat menjalankan kode ini dan seharusnya tidak akan ada error. Kode belum melakukan apa pun yang tampak.
Kode yang sudah selesai akan terlihat seperti ini:
abstract class Dwelling(private var residents: Int) {
abstract val buildingMaterial: String
abstract val capacity: Int
fun hasRoom(): Boolean {
return residents < capacity
}
}
4. Membuat subclass
Membuat subclass SquareCabin
- Di bawah class
Dwelling, buat class dengan namaSquareCabin.
class SquareCabin
- Selanjutnya, Anda harus menunjukkan bahwa
SquareCabinberkaitan denganDwelling. Dalam kode, Anda ingin menunjukkan bahwaSquareCabindiperluas dariDwelling(atau merupakan subclass untukDwelling)karenaSquareCabinakan menyediakan implementasi untuk bagian abstrakDwelling.
Tunjukkan hubungan pewarisan ini dengan menambahkan titik dua (:) setelah nama class SquareCabin, lalu diikuti dengan panggilan untuk menginisialisasi class induk Dwelling. Jangan lupa tambahkan tanda kurung setelah nama class Dwelling.
class SquareCabin : Dwelling()
- Saat memperluas dari superclass, Anda harus meneruskan parameter wajib yang diminta oleh superclass.
Dwellingmemerlukan jumlahresidentssebagai input. Anda dapat meneruskan jumlah penghuni tetap seperti3.
class SquareCabin : Dwelling(3)
Namun, Anda ingin program menjadi lebih fleksibel dan memungkinkan jumlah variabel penghuni untuk SquareCabins. Oleh karena itu, buat parameter residents dengan definisi class SquareCabin. Jangan mendeklarasikan residents sebagai val, karena Anda menggunakan kembali properti yang sudah dinyatakan di class induk Dwelling.
class SquareCabin(residents: Int) : Dwelling(residents)
- Jalankan kode.
- Ini akan menyebabkan error. Lihat:
Class 'SquareCabin' is not abstract and does not implement abstract base class member public abstract val buildingMaterial: String defined in Dwelling
Saat Anda mendeklarasikan fungsi dan variabel abstrak, deklarasi ini akan menyerupai promise yang Anda beri nilai dan implementasinya nanti. Untuk variabel, ini artinya setiap subclass dari class abstrak tersebut harus memberikan nilai. Untuk fungsi, ini artinya setiap subclass perlu menerapkan isi fungsi.
Dalam class Dwelling, Anda menetapkan variabel abstract buildingMaterial. SquareCabin adalah subclass dari Dwelling sehingga harus memberikan nilai untuk buildingMaterial. Gunakan kata kunci override untuk menunjukkan bahwa properti ini telah ditetapkan di class induk dan akan diganti di class ini.
- Dalam class
SquareCabin,overridepropertibuildingMaterialdan isi nilainya dengan"Wood". - Lakukan hal yang sama untuk
capacityyang menyebutkan 6 penghuni dapat tinggal diSquareCabin.
class SquareCabin(residents: Int) : Dwelling(residents) {
override val buildingMaterial = "Wood"
override val capacity = 6
}
Kode yang sudah selesai akan terlihat seperti ini.
abstract class Dwelling(private var residents: Int) {
abstract val buildingMaterial: String
abstract val capacity: Int
fun hasRoom(): Boolean {
return residents < capacity
}
}
class SquareCabin(residents: Int) : Dwelling(residents) {
override val buildingMaterial = "Wood"
override val capacity = 6
}
Untuk menguji kode Anda, buat instance SquareCabin di dalam program.
Menggunakan SquareCabin
- Sisipkan fungsi
main()kosong sebelum definisi classDwellingdanSquareCabin.
fun main() {
}
abstract class Dwelling(private var residents: Int) {
...
}
class SquareCabin(residents: Int) : Dwelling(residents) {
...
}
- Dalam fungsi
main(), buat instanceSquareCabinbernamasquareCabindengan 6 penghuni. Tambahkan pernyataan cetak untuk bahan bangunan, kapasitas, dan fungsihasRoom().
fun main() {
val squareCabin = SquareCabin(6)
println("\nSquare Cabin\n============")
println("Capacity: ${squareCabin.capacity}")
println("Material: ${squareCabin.buildingMaterial}")
println("Has room? ${squareCabin.hasRoom()}")
}
Perhatikan bahwa fungsi hasRoom() tidak ditentukan di class SquareCabin, tetapi ditentukan di class Dwelling. Karena SquareCabin adalah subclass dari class Dwelling, fungsi hasRoom() diwarisi secara cuma-cuma. Fungsi hasRoom() sekarang dapat dipanggil di semua instance SquareCabin, seperti yang terlihat dalam cuplikan kode sebagai squareCabin.hasRoom().
- Jalankan kode Anda, dan kode tersebut akan mencetak perintah berikut ini:
Square Cabin ============ Capacity: 6 Material: Wood Has room? false
Anda membuat squareCabin dengan 6 penghuni yang setara dengan capacity sehingga hasRoom() menampilkan false. Anda dapat bereksperimen dengan menginisialisasi SquareCabin dengan jumlah residents yang lebih kecil, dan saat Anda menjalankan program lagi, hasRoom() harus menampilkan true.
Menggunakan with untuk menyederhanakan kode Anda
Dalam pernyataan println(), setiap kali Anda mereferensikan properti atau fungsi squareCabin, perhatikan bagaimana Anda mengulangi squareCabin. Hal ini menjadi berulang-ulang dan dapat menjadi sumber error saat Anda menyalin dan menempelkan pernyataan cetak.
Saat Anda bekerja dengan instance class tertentu dan harus mengakses beberapa properti dan fungsi instance tersebut, Anda dapat mengucapkan "lakukan semua operasi berikut dengan objek instance ini" menggunakan pernyataan with. Mulai dengan kata kunci with, diikuti dengan nama instance dalam tanda kurung, lalu diikuti dengan tanda kurung kurawal yang berisi operasi yang ingin Anda lakukan.
with (instanceName) {
// all operations to do with instanceName
}
- Dalam fungsi
main(), ubah pernyataan cetak untuk menggunakanwith. - Hapus
squareCabin.di laporan cetak.
with(squareCabin) {
println("\nSquare Cabin\n============")
println("Capacity: ${capacity}")
println("Material: ${buildingMaterial}")
println("Has room? ${hasRoom()}")
}
- Jalankan kode Anda lagi untuk memastikan kode berjalan tanpa error dan menampilkan output yang sama.
Square Cabin ============ Capacity: 6 Material: Wood Has room? false
Ini adalah kode lengkap Anda:
fun main() {
val squareCabin = SquareCabin(6)
with(squareCabin) {
println("\nSquare Cabin\n============")
println("Capacity: ${capacity}")
println("Material: ${buildingMaterial}")
println("Has room? ${hasRoom()}")
}
}
abstract class Dwelling(private var residents: Int) {
abstract val buildingMaterial: String
abstract val capacity: Int
fun hasRoom(): Boolean {
return residents < capacity
}
}
class SquareCabin(residents: Int) : Dwelling(residents) {
override val buildingMaterial = "Wood"
override val capacity = 6
}
Membuat subclass RoundHut
- Dengan cara yang sama seperti
SquareCabin, tambahkan subclass lain,RoundHut, keDwelling. - Ganti
buildingMaterialdan beri nilai"Straw". - Ganti
capacitydan tetapkan ke 4.
class RoundHut(residents: Int) : Dwelling(residents) {
override val buildingMaterial = "Straw"
override val capacity = 4
}
- Di
main(), buat instanceRoundHutdengan 3 penghuni.
val roundHut = RoundHut(3)
- Tambahkan kode di bawah untuk mencetak informasi tentang
roundHut.
with(roundHut) {
println("\nRound Hut\n=========")
println("Material: ${buildingMaterial}")
println("Capacity: ${capacity}")
println("Has room? ${hasRoom()}")
}
- Jalankan kode Anda, dan output untuk seluruh program seharusnya akan seperti berikut:
Square Cabin ============ Capacity: 6 Material: Wood Has room? false Round Hut ========= Material: Straw Capacity: 4 Has room? true
Anda sekarang memiliki hierarki class yang terlihat seperti ini, dengan Dwelling sebagai class root serta SquareCabin dan RoundHut sebagai subclass dari Dwelling.

Membuat subclass RoundTower
Class terakhir dalam hierarki class ini adalah menara bundar. Anggap menara bundar sebagai pondok bulat yang terbuat dari batu dan memiliki banyak lantai. Jadi, Anda dapat membuat RoundTower sebagai subclass dari RoundHut.
- Buat class
RoundToweryang merupakan subclass dariRoundHut. Tambahkan parameterresidentske konstruktorRoundTower, lalu teruskan parameter tersebut ke konstruktor superclassRoundHut. - Ganti
buildingMaterialmenjadi"Stone". - Tetapkan
capacityke4.
class RoundTower(residents: Int) : RoundHut(residents) {
override val buildingMaterial = "Stone"
override val capacity = 4
}
- Jalankan kode ini dan Anda akan mendapatkan pesan error.
This type is final, so it cannot be inherited from
Error ini berarti bahwa class RoundHut tidak dapat dibuatkan subclass-nya (atau diwariskan). Secara default, di Kotlin, class bersifat final dan tidak dapat dibuatkan subclass-nya. Anda hanya diizinkan untuk mewarisi dari class abstract atau class yang ditandai dengan kata kunci open. Oleh karena itu, Anda harus menandai class RoundHut dengan kata kunci open agar dapat diwariskan.
- Tambahkan kata kunci
opendi awal deklarasiRoundHut.
open class RoundHut(residents: Int) : Dwelling(residents) {
override val buildingMaterial = "Straw"
override val capacity = 4
}
- Di
main(), buat instanceroundTowerdan cetak informasinya.
val roundTower = RoundTower(4)
with(roundTower) {
println("\nRound Tower\n==========")
println("Material: ${buildingMaterial}")
println("Capacity: ${capacity}")
println("Has room? ${hasRoom()}")
}
Kode lengkapnya sebagai berikut.
fun main() {
val squareCabin = SquareCabin(6)
val roundHut = RoundHut(3)
val roundTower = RoundTower(4)
with(squareCabin) {
println("\nSquare Cabin\n============")
println("Capacity: ${capacity}")
println("Material: ${buildingMaterial}")
println("Has room? ${hasRoom()}")
}
with(roundHut) {
println("\nRound Hut\n=========")
println("Material: ${buildingMaterial}")
println("Capacity: ${capacity}")
println("Has room? ${hasRoom()}")
}
with(roundTower) {
println("\nRound Tower\n==========")
println("Material: ${buildingMaterial}")
println("Capacity: ${capacity}")
println("Has room? ${hasRoom()}")
}
}
abstract class Dwelling(private var residents: Int) {
abstract val buildingMaterial: String
abstract val capacity: Int
fun hasRoom(): Boolean {
return residents < capacity
}
}
class SquareCabin(residents: Int) : Dwelling(residents) {
override val buildingMaterial = "Wood"
override val capacity = 6
}
open class RoundHut(residents: Int) : Dwelling(residents) {
override val buildingMaterial = "Straw"
override val capacity = 4
}
class RoundTower(residents: Int) : RoundHut(residents) {
override val buildingMaterial = "Stone"
override val capacity = 4
}
- Jalankan kode. Seharusnya sekarang kode dapat berfungsi tanpa error dan menghasilkan output berikut.
Square Cabin ============ Capacity: 6 Material: Wood Has room? false Round Hut ========= Material: Straw Capacity: 4 Has room? true Round Tower ========== Material: Stone Capacity: 4 Has room? false
Menambahkan beberapa lantai ke RoundTower
Berdasarkan implikasinya, RoundHut merupakan bangunan satu lantai. Menara biasanya memiliki beberapa tingkat (lantai).
Dengan mempertimbangkan kapasitas, makin banyak lantai yang dimiliki sebuah menara, makin besar kapasitas yang seharusnya dimiliki.
Anda dapat mengubah RoundTower agar memiliki beberapa lantai dan menyesuaikan kapasitasnya berdasarkan jumlah lantai.
- Perbarui konstruktor
RoundToweruntuk mengambil parameter bilangan bulat tambahanval floorsuntuk jumlah lantai. Tempatkan setelahresidents. Perhatikan bahwa Anda tidak perlu meneruskan ini ke konstruktorRoundHutinduk karenafloorsditentukan di sini dalamRoundTowerdanRoundHuttidak memilikifloors.
class RoundTower(
residents: Int,
val floors: Int) : RoundHut(residents) {
...
}
- Jalankan kode. Terjadi error saat membuat
roundTowerdalam metodemain()karena Anda tidak memberikan angka untuk argumenfloors. Anda dapat menambahkan argumen yang tidak ada.
Atau, dalam definisi class RoundTower, Anda dapat menambahkan nilai default untuk floors seperti yang ditunjukkan di bawah ini. Kemudian, jika tidak ada nilai untuk floors yang diteruskan ke dalam konstruktor, nilai default dapat digunakan untuk membuat instance objek.
- Dalam kode Anda, tambahkan
= 2setelah pernyataanfloorsuntuk menetapkan nilai default 2.
class RoundTower(
residents: Int,
val floors: Int = 2) : RoundHut(residents) {
...
}
- Jalankan kode. Kode harus dikompilasi karena
RoundTower(4)sekarang membuat instance objekRoundTowerdengan nilai default 2 lantai. - Di class
RoundTower, perbaruicapacityuntuk mengalikannya dengan jumlah lantai.
override val capacity = 4 * floors
- Jalankan kode Anda dan perhatikan bahwa kapasitas
RoundTowersekarang menjadi 8 untuk 2 lantai.
Berikut adalah kode yang sudah selesai.
fun main() {
val squareCabin = SquareCabin(6)
val roundHut = RoundHut(3)
val roundTower = RoundTower(4)
with(squareCabin) {
println("\nSquare Cabin\n============")
println("Capacity: ${capacity}")
println("Material: ${buildingMaterial}")
println("Has room? ${hasRoom()}")
}
with(roundHut) {
println("\nRound Hut\n=========")
println("Material: ${buildingMaterial}")
println("Capacity: ${capacity}")
println("Has room? ${hasRoom()}")
}
with(roundTower) {
println("\nRound Tower\n==========")
println("Material: ${buildingMaterial}")
println("Capacity: ${capacity}")
println("Has room? ${hasRoom()}")
}
}
abstract class Dwelling(private var residents: Int) {
abstract val buildingMaterial: String
abstract val capacity: Int
fun hasRoom(): Boolean {
return residents < capacity
}
}
class SquareCabin(residents: Int) : Dwelling(residents) {
override val buildingMaterial = "Wood"
override val capacity = 6
}
open class RoundHut(residents: Int) : Dwelling(residents) {
override val buildingMaterial = "Straw"
override val capacity = 4
}
class RoundTower(
residents: Int,
val floors: Int = 2) : RoundHut(residents) {
override val buildingMaterial = "Stone"
override val capacity = 4 * floors
}
5. Mengubah class dalam hierarki
Menghitung luas lantai
Dalam latihan ini, Anda akan mempelajari cara mendeklarasikan fungsi abstrak di class abstrak, lalu menerapkan fungsinya di subclass.
Semua tempat tinggal memiliki luas lantai, tetapi penghitungannya berbeda-beda menyesuaikan bentuk tempat tinggal.
Menentukan floorArea() di class Dwelling
- Pertama-tama, tambahkan fungsi
abstractfloorArea()ke classDwelling. TampilkanDouble. Double adalah jenis data, sepertiStringdanInt; data ini digunakan untuk bilangan floating point, yaitu bilangan yang memiliki titik desimal yang diikuti oleh bagian pecahan, seperti 5,8793.
abstract fun floorArea(): Double
Semua metode abstrak yang didefinisikan dalam class abstrak harus diterapkan di salah satu subclass-nya. Sebelum dapat menjalankan kode, Anda perlu mengimplementasikan floorArea() di subclass.
Mengimplementasikan floorArea() untuk SquareCabin
Seperti pada buildingMaterial dan capacity, karena mengimplementasikan fungsi abstract yang ditentukan di class induk, Anda harus menggunakan kata kunci override.
- Di class
SquareCabin, mulai dengan kata kuncioverridelalu diikuti dengan penerapan fungsifloorArea()yang sebenarnya seperti yang ditunjukkan di bawah ini.
override fun floorArea(): Double {
}
- Tampilkan luas lantai yang dihitung. Luas persegi panjang atau persegi adalah panjang sisi yang dikalikan dengan panjang sisi lainnya. Isi fungsinya adalah
return length * length.
override fun floorArea(): Double {
return length * length
}
Panjang ini bukanlah variabel dalam class dan berbeda untuk setiap instance sehingga Anda dapat menambahkannya sebagai parameter konstruktor untuk class SquareCabin.
- Ubah definisi class
SquareCabinuntuk menambahkan parameterlengthjenisDouble. Nyatakan properti sebagaivalkarena panjang bangunan tidak berubah.
class SquareCabin(residents: Int, val length: Double) : Dwelling(residents) {
Dwelling dan semua subclass-nya memiliki residents sebagai argumen konstruktor. Argumen tersebut merupakan argumen pertama dalam konstruktor Dwelling. Jadi, sebaiknya Anda juga menjadikannya sebagai argumen pertama di semua konstruktor subclass dan menempatkan argumen dalam urutan yang sama di semua definisi class. Oleh karena itu, masukkan parameter length baru setelah parameter residents.
- Dalam
main(), perbarui pembuatan instancesquareCabin. Teruskan50.0ke konstruktorSquareCabinsebagailength.
val squareCabin = SquareCabin(6, 50.0)
- Dalam pernyataan
withuntuksquareCabin, tambahkan pernyataan cetak untuk luas lantai.
println("Floor area: ${floorArea()}")
Kode tidak akan berjalan karena Anda juga harus mengimplementasikan floorArea() dalam RoundHut.
Mengimplementasikan floorArea() untuk RoundHut
Dengan cara yang sama, implementasikan luas lantai untuk RoundHut. RoundHut juga merupakan subclass langsung dari Dwelling sehingga Anda harus menggunakan kata kunci override.
Luas lantai tempat tinggal melingkar adalah PI * radius * radius.
PI adalah nilai matematika. Nilai ini ditentukan dalam library matematika. Library adalah kumpulan fungsi dan nilai yang telah ditentukan sebelumnya dan ditetapkan di luar program yang dapat digunakan oleh program. Untuk menggunakan fungsi atau nilai library, Anda harus memberi tahu compiler bahwa Anda akan menggunakannya. Anda melakukannya dengan mengimpor fungsi atau nilai ke dalam program. Untuk menggunakan PI dalam program, Anda perlu mengimpor kotlin.math.PI.
- Impor
PIdari library matematika Kotlin. Letakkan ini di bagian atas file, sebelummain().
import kotlin.math.PI
- Implementasikan fungsi
floorArea()untukRoundHut.
override fun floorArea(): Double {
return PI * radius * radius
}
Peringatan: Jika tidak mengimpor kotlin.math.PI, Anda akan mendapatkan error, jadi impor library ini sebelum menggunakannya. Atau, Anda dapat menulis versi PI yang sepenuhnya memenuhi syarat, seperti dalam kotlin.math.PI * radius * radius, dan kemudian pernyataan impor tidak diperlukan.
- Perbarui konstruktor
RoundHutuntuk memasukkanradius.
open class RoundHut(
residents: Int,
val radius: Double) : Dwelling(residents) {
- Dalam
main(), perbarui inisialisasiroundHutdengan meneruskanradiusdari10.0ke konstruktorRoundHut.
val roundHut = RoundHut(3, 10.0)
- Tambahkan pernyataan cetak di dalam pernyataan
withuntukroundHut.
println("Floor area: ${floorArea()}")
Mengimplementasikan floorArea() untuk RoundTower
Kode Anda belum berjalan, dan gagal dengan menampilkan error ini:
Error: No value passed for parameter 'radius'
Dalam RoundTower, agar program dapat dikompilasi, Anda tidak perlu mengimplementasikan floorArea() karena akan diwarisi dari RoundHut, tetapi Anda perlu memperbarui definisi class RoundTower agar memiliki argumen radius yang sama dengan induknya, RoundHut.
- Ubah konstruktor RoundTower untuk menggunakan
radius. Masukkanradiussetelahresidentsdan sebelumfloors. Sebaiknya variabel dengan nilai default dicantumkan di bagian akhir. Jangan lupa meneruskanradiuske konstruktor class induk.
class RoundTower(
residents: Int,
radius: Double,
val floors: Int = 2) : RoundHut(residents, radius) {
- Perbarui inisialisasi
roundTowerdimain().
val roundTower = RoundTower(4, 15.5)
- Dan tambahkan pernyataan cetak yang memanggil
floorArea().
println("Floor area: ${floorArea()}")
- Sekarang Anda sudah dapat menjalankan kode!
- Perhatikan bahwa penghitungan untuk
RoundTowertidak benar karena diwarisi dariRoundHutdan tidak memperhitungkan jumlahfloors. - Di dalam
RoundTower, lakukanoverride floorArea()agar dapat memberikan penerapan berbeda yang mengalikan luas dengan jumlah lantai. Perhatikan bahwa Anda dapat menentukan fungsi dalam class abstrak (Dwelling), menerapkannya dalam subclass (RoundHut), lalu menggantinya lagi dalam subclass dari subclass (RoundTower). Ini adalah cara terbaik untuk keduanya karena Anda mewarisi fungsi yang diinginkan dan dapat mengganti fungsi yang tidak diinginkan.
override fun floorArea(): Double {
return PI * radius * radius * floors
}
Kode ini berfungsi, tetapi ada cara untuk menghindari pengulangan kode yang sudah ada di class induk RoundHut. Anda dapat memanggil fungsi floorArea() dari class RoundHut induk, yang menampilkan PI * radius * radius. Lalu, kalikan hasil tersebut dengan jumlah floors.
- Dalam
RoundTower, perbaruifloorArea()untuk menggunakan implementasi superclassfloorArea(). Gunakan kata kuncisuperuntuk memanggil fungsi yang ditentukan di induk.
override fun floorArea(): Double {
return super.floorArea() * floors
}
- Jalankan lagi kode Anda dan
RoundTowermenghasilkan ruang lantai yang benar untuk beberapa lantai.
Berikut adalah kode yang sudah selesai:
import kotlin.math.PI
fun main() {
val squareCabin = SquareCabin(6, 50.0)
val roundHut = RoundHut(3, 10.0)
val roundTower = RoundTower(4, 15.5)
with(squareCabin) {
println("\nSquare Cabin\n============")
println("Capacity: ${capacity}")
println("Material: ${buildingMaterial}")
println("Has room? ${hasRoom()}")
println("Floor area: ${floorArea()}")
}
with(roundHut) {
println("\nRound Hut\n=========")
println("Material: ${buildingMaterial}")
println("Capacity: ${capacity}")
println("Has room? ${hasRoom()}")
println("Floor area: ${floorArea()}")
}
with(roundTower) {
println("\nRound Tower\n==========")
println("Material: ${buildingMaterial}")
println("Capacity: ${capacity}")
println("Has room? ${hasRoom()}")
println("Floor area: ${floorArea()}")
}
}
abstract class Dwelling(private var residents: Int) {
abstract val buildingMaterial: String
abstract val capacity: Int
fun hasRoom(): Boolean {
return residents < capacity
}
abstract fun floorArea(): Double
}
class SquareCabin(residents: Int,
val length: Double) : Dwelling(residents) {
override val buildingMaterial = "Wood"
override val capacity = 6
override fun floorArea(): Double {
return length * length
}
}
open class RoundHut(residents: Int,
val radius: Double) : Dwelling(residents) {
override val buildingMaterial = "Straw"
override val capacity = 4
override fun floorArea(): Double {
return PI * radius * radius
}
}
class RoundTower(residents: Int, radius: Double,
val floors: Int = 2) : RoundHut(residents, radius) {
override val buildingMaterial = "Stone"
override val capacity = 4 * floors
override fun floorArea(): Double {
return super.floorArea() * floors
}
}
Output harus berupa:
Square Cabin ============ Capacity: 6 Material: Wood Has room? false Floor area: 2500.0 Round Hut ========= Material: Straw Capacity: 4 Has room? true Floor area: 314.1592653589793 Round Tower ========== Material: Stone Capacity: 8 Has room? true Floor area: 1509.5352700498956
Memungkinkan penghuni baru mendapatkan ruangan
Tambahkan kemampuan bagi penghuni baru agar mendapatkan ruangan dengan fungsi getRoom() yang akan meningkatkan jumlah penghuni sebanyak satu. Logika ini sama untuk semua tempat tinggal sehingga Anda dapat mengimplementasikan fungsi di Dwelling, dan logika akan tersedia untuk semua subclass dan turunannya. Keren!
Catatan:
- Gunakan pernyataan
ifyang hanya akan menambahkan satu penghuni jika kapasitas tersisa. - Cetak pesan untuk mendapatkan hasilnya.
- Anda dapat menggunakan
residents++sebagai singkatanresidents = residents + 1untuk menambahkan 1 ke variabelresidents.
- Implementasikan fungsi
getRoom()di classDwelling.
fun getRoom() {
if (capacity > residents) {
residents++
println("You got a room!")
} else {
println("Sorry, at capacity and no rooms left.")
}
}
- Tambahkan beberapa pernyataan cetak ke blok pernyataan
withuntukroundHutguna mengamati proses yang akan terjadi jikagetRoom()danhasRoom()digunakan bersamaan.
println("Has room? ${hasRoom()}")
getRoom()
println("Has room? ${hasRoom()}")
getRoom()
Output untuk pernyataan cetak ini:
Has room? true You got a room! Has room? false Sorry, at capacity and no rooms left.
Lihat Kode solusi untuk mengetahui detailnya.
Memasang karpet ke dalam tempat tinggal bundar
Misalnya Anda perlu mengetahui panjang satu sisi karpet yang harus digunakan untuk RoundHut atau RoundTower. Masukkan fungsi ke dalam RoundHut untuk menyediakannya ke semua tempat tinggal bundar.

- Impor terlebih dahulu fungsi
sqrt()dari librarykotlin.math.
import kotlin.math.sqrt
- Implementasikan fungsi
calculateMaxCarpetLength()di classRoundHut. Formula untuk menghitung panjang karpet persegi yang dapat pas dalam lingkaran adalahsqrt(2) * radius. Hal ini dijelaskan dalam diagram di atas.
fun calculateMaxCarpetLength(): Double {
return sqrt(2.0) * radius
}
Teruskan nilai Double, 2.0 ke fungsi matematika sqrt(2.0), karena jenis nilai fungsi yang ditampilkan adalah Double, bukan Integer.
- Sekarang metode
calculateMaxCarpetLength()dapat dipanggil pada instanceRoundHutdanRoundTower. Tambahkan pernyataan cetak keroundHutdanroundTowerdalam fungsimain().
println("Carpet Length: ${calculateMaxCarpetLength()}")
Lihat Kode solusi untuk mengetahui detailnya.
Selamat! Anda telah membuat hierarki class lengkap dengan properti dan fungsi, serta mempelajari semua yang Anda butuhkan untuk membuat class yang lebih bermanfaat.
6. Kode solusi
Kode solusi lengkap di bawah untuk codelab ini, termasuk komentar.
/**
* Program that implements classes for different kinds of dwellings.
* Shows how to:
* Create class hierarchy, variables and functions with inheritance,
* abstract class, overriding, and private vs. public variables.
*/
import kotlin.math.PI
import kotlin.math.sqrt
fun main() {
val squareCabin = SquareCabin(6, 50.0)
val roundHut = RoundHut(3, 10.0)
val roundTower = RoundTower(4, 15.5)
with(squareCabin) {
println("\nSquare Cabin\n============")
println("Capacity: ${capacity}")
println("Material: ${buildingMaterial}")
println("Floor area: ${floorArea()}")
}
with(roundHut) {
println("\nRound Hut\n=========")
println("Material: ${buildingMaterial}")
println("Capacity: ${capacity}")
println("Floor area: ${floorArea()}")
println("Has room? ${hasRoom()}")
getRoom()
println("Has room? ${hasRoom()}")
getRoom()
println("Carpet size: ${calculateMaxCarpetLength()}")
}
with(roundTower) {
println("\nRound Tower\n==========")
println("Material: ${buildingMaterial}")
println("Capacity: ${capacity}")
println("Floor area: ${floorArea()}")
println("Carpet Length: ${calculateMaxCarpetLength()}")
}
}
/**
* Defines properties common to all dwellings.
* All dwellings have floorspace,
* but its calculation is specific to the subclass.
* Checking and getting a room are implemented here
* because they are the same for all Dwelling subclasses.
*
* @param residents Current number of residents
*/
abstract class Dwelling(private var residents: Int) {
abstract val buildingMaterial: String
abstract val capacity: Int
/**
* Calculates the floor area of the dwelling.
* Implemented by subclasses where shape is determined.
*
* @return floor area
*/
abstract fun floorArea(): Double
/**
* Checks whether there is room for another resident.
*
* @return true if room available, false otherwise
*/
fun hasRoom(): Boolean {
return residents < capacity
}
/**
* Compares the capacity to the number of residents and
* if capacity is larger than number of residents,
* add resident by increasing the number of residents.
* Print the result.
*/
fun getRoom() {
if (capacity > residents) {
residents++
println("You got a room!")
} else {
println("Sorry, at capacity and no rooms left.")
}
}
}
/**
* A square cabin dwelling.
*
* @param residents Current number of residents
* @param length Length
*/
class SquareCabin(residents: Int, val length: Double) : Dwelling(residents) {
override val buildingMaterial = "Wood"
override val capacity = 6
/**
* Calculates floor area for a square dwelling.
*
* @return floor area
*/
override fun floorArea(): Double {
return length * length
}
}
/**
* Dwelling with a circular floorspace
*
* @param residents Current number of residents
* @param radius Radius
*/
open class RoundHut(
residents: Int, val radius: Double) : Dwelling(residents) {
override val buildingMaterial = "Straw"
override val capacity = 4
/**
* Calculates floor area for a round dwelling.
*
* @return floor area
*/
override fun floorArea(): Double {
return PI * radius * radius
}
/**
* Calculates the max length for a square carpet
* that fits the circular floor.
*
* @return length of square carpet
*/
fun calculateMaxCarpetLength(): Double {
return sqrt(2.0) * radius
}
}
/**
* Round tower with multiple stories.
*
* @param residents Current number of residents
* @param radius Radius
* @param floors Number of stories
*/
class RoundTower(
residents: Int,
radius: Double,
val floors: Int = 2) : RoundHut(residents, radius) {
override val buildingMaterial = "Stone"
// Capacity depends on the number of floors.
override val capacity = floors * 4
/**
* Calculates the total floor area for a tower dwelling
* with multiple stories.
*
* @return floor area
*/
override fun floorArea(): Double {
return super.floorArea() * floors
}
}
7. Ringkasan
Dalam codelab ini, Anda telah mempelajari cara:
- Membuat hierarki class, yaitu pohon class tempat turunan mewarisi fungsi dari class induk. Properti dan fungsi diwarisi oleh subclass.
- Membuat class
abstracttempat beberapa fungsi dibiarkan untuk diimplementasikan oleh subclass-nya. Oleh karena itu, instance untuk classabstracttidak dapat dibuat. - Membuat subclass dari class
abstract. - Menggunakan kata kunci
overrideuntuk mengganti properti dan fungsi di subclass. - Menggunakan kata kunci
superuntuk mereferensikan fungsi dan properti di class induk. - Membuat class
openagar dapat dibuatkan subclass-nya. - Membuat properti
privateagar hanya dapat digunakan di dalam class. - Menggunakan konstruksi
withuntuk melakukan beberapa panggilan pada instance objek yang sama. - Mengimpor fungsi dari library
kotlin.math