Class dan instance objek di Kotlin

Untuk codelab di jalur ini, Anda akan mem-build aplikasi Android Dice Roller. Saat pengguna "melempar dadu", hasil acak akan muncul. Hasilnya memperhitungkan jumlah sisi dadu. Misalnya, hanya nilai antara 1-6 yang dapat didapat dari 6 sisi.

Seperti inilah tampilan aplikasi final.

8299aaca25c93863.png

Untuk membantu berfokus pada konsep pemrograman baru untuk aplikasi ini, Anda akan menggunakan alat pemrograman Kotlin berbasis browser untuk membuat fungsi aplikasi inti. Program ini akan mengeluarkan hasil Anda ke konsol. Kemudian, Anda akan menerapkan antarmuka pengguna di Android Studio.

Dalam codelab pertama ini, Anda akan membuat program Kotlin yang menyimulasikan pelemparan dadu dan menghasilkan angka acak, seperti halnya dadu pada umumnya.

Prasyarat

  • Cara membuka, mengedit, dan menjalankan kode di https://developer.android.com/training/kotlinplayground
  • Membuat dan menjalankan program Kotlin yang menggunakan variabel dan fungsi, serta yang mencetak suatu hasil ke konsol.
  • Memformat angka dalam teks menggunakan template string dengan notasi ${variable}.

Yang akan Anda pelajari

  • Cara membuat angka acak secara terprogram untuk menyimulasikan pelemparan dadu.
  • Cara menyusun kode dengan membuat class Dice menggunakan variabel dan metode.
  • Cara membuat instance objek dari suatu class, memodifikasi variabelnya, dan memanggil metodenya.

Yang akan Anda build

  • Program Kotlin di alat pemrograman Kotlin berbasis browser yang dapat melakukan pelemparan dadu acak.

Yang Anda perlukan

  • Komputer dengan koneksi internet

Game sering kali memiliki elemen acak. Anda dapat memperoleh hadiah acak atau memainkan langkah dengan jumlah acak di papan game. Di kehidupan sehari-hari, Anda dapat menggunakan angka dan huruf acak untuk membuat sandi yang lebih aman.

Alih-alih melempar dadu yang sebenarnya, Anda dapat menulis program yang menyimulasikan pelemparan dadu untuk Anda. Setiap kali Anda melempar dadu, hasilnya dapat berupa angka berapa pun dalam rentang nilai yang memungkinkan. Untungnya, Anda tidak perlu mem-build generator angka acak untuk program semacam itu. Sebagian besar bahasa pemrograman, termasuk Kotlin, memiliki cara bawaan untuk menghasilkan angka acak. Dalam tugas ini, Anda akan menggunakan kode Kotlin untuk membuat angka acak.

Menyiapkan kode awal

  1. Di browser, buka situs https://developer.android.com/training/kotlinplayground.
  2. Hapus semua kode yang ada di editor kode dan ganti dengan kode di bawah. Ini adalah fungsi main() yang telah Anda gunakan di codelab sebelumnya.
fun main() {

}

Menggunakan fungsi acak

Untuk melempar dadu, Anda memerlukan cara untuk mewakili semua nilai lemparan dadu yang valid. Untuk dadu 6 sisi pada umumnya, lemparan dadu yang dapat diterima adalah: 1, 2, 3, 4, 5, dan 6.

Sebelumnya, Anda sudah mengetahui bahwa ada jenis data seperti Int untuk angka bilangan bulat dan String untuk teks. IntRange adalah jenis data lain, dan mewakili rentang bilangan bulat dari titik awal ke titik akhir. IntRange adalah jenis data yang sesuai untuk mewakili kemungkinan nilai yang dapat dihasilkan dari lemparan dadu.

  1. Di dalam fungsi main(), tentukan variabel sebagai val yang disebut diceRange. Tetapkan variabel IntRange dari 1 sampai 6 yang mewakili rentang bilangan bulat yang dapat dilempar oleh dadu 6 sisi.
val diceRange = 1..6

Anda dapat mengetahui bahwa 1..6 adalah rentang Kotlin karena memiliki angka awal, dua titik, yang diikuti dengan angka akhir (tanpa spasi di antaranya). Contoh rentang bilangan bulat lainnya adalah 2..5 untuk angka 2 sampai 5, dan 100..200 untuk angka 100 sampai 200.

Serupa dengan bagaimana panggilan println() memberi tahu sistem untuk mencetak teks yang diberikan, Anda dapat menggunakan fungsi yang disebut random() untuk membuat dan menampilkan angka acak untuk rentang tertentu. Seperti sebelumnya, Anda dapat menyimpan hasilnya dalam variabel.

  1. Di dalam main(), tentukan variabel sebagai val yang disebut randomNumber.
  2. Buat agar randomNumber memiliki nilai hasil dari memanggil random() dalam rentang diceRange, seperti yang ditunjukkan di bawah ini.
 val randomNumber = diceRange.random()

Perhatikan bahwa Anda memanggil random() di diceRange menggunakan titik, antara variabel dan panggilan fungsi. Anda dapat membaca ini sebagai "menghasilkan angka acak dari diceRange". Hasilnya kemudian disimpan dalam variabel randomNumber.

  1. Untuk melihat angka yang dibuat secara acak, gunakan notasi pemformatan string (disebut juga "template string") ${randomNumber} untuk mencetaknya, seperti yang ditunjukkan di bawah ini.
println("Random number: ${randomNumber}")

Kode yang sudah selesai akan terlihat seperti ini.

fun main() {
    val diceRange = 1..6
    val randomNumber = diceRange.random()
    println("Random number: ${randomNumber}")
}
  1. Jalankan kode Anda beberapa kali. Setiap kali kode dijalankan, Anda akan melihat output seperti di bawah ini dengan angka acak yang berbeda.
Random number: 4

Saat Anda melempar dadu, rentang menjadi objek nyata di kedua tangan Anda. Meskipun kode yang baru saja Anda tulis berfungsi dengan baik, sulit untuk dibayangkan bahwa kode ini tentang dadu yang sebenarnya. Mengatur program agar lebih menyerupai fungsi yang diwakilinya akan membuatnya lebih mudah dipahami. Jadi, akan lebih baik jika Anda memiliki dadu terprogram yang dapat Anda lempar.

Prinsip kerja semua dadu pada dasarnya sama. Keduanya memiliki properti yang sama, seperti sisi, dan memiliki perilaku yang sama, seperti sama-sama dapat dilempar. Di Kotlin, Anda dapat membuat blueprint terprogram dari sebuah dadu yang menyatakan bahwa dadu tersebut memiliki sisi-sisi dan dapat menghasilkan angka acak. Blueprint ini disebut class.

Dari class tersebut, Anda kemudian dapat membuat objek aktual yang disebut instance objek. Misalnya, Anda dapat membuat dadu 12 sisi atau 4 sisi.

Menentukan class Dadu

Pada langkah berikut, Anda akan menentukan class baru yang disebut Dice untuk mewakili kapabilitas lemparan dadu.

  1. Untuk memulai dari awal, hapus kode dalam fungsi main() sehingga Anda akan mendapatkan kode seperti yang ditunjukkan di bawah ini.
fun main() {

}
  1. Di bawah fungsi main() ini, tambahkan baris kosong, lalu tambahkan kode untuk membuat class Dice. Seperti yang ditunjukkan di bawah ini, mulai dengan kata kunci class, kemudian diikuti dengan nama class, lalu diikuti lagi dengan kurung kurawal buka dan tutup. Biarkan spasi di antara tanda kurung kurawal agar Anda dapat menempatkan kode class.
class Dice {

}

Di dalam definisi class, Anda dapat menentukan satu atau beberapa properti class menggunakan variabel. Dadu asli dapat memiliki sejumlah sisi, sebuah warna, atau berat. Dalam tugas ini, Anda akan berfokus pada properti jumlah sisi dadu.

  1. Dalam class Dice, tambahkan var yang bernama sides untuk jumlah sisi yang akan ada di dadu. Setel sides menjadi 6.
class Dice {
    var sides = 6
}

Selesai. Sekarang Anda sudah memiliki sebuah class sangat sederhana yang mewakili dadu.

Membuat instance class Dadu

Dengan class Dice ini, Anda memiliki blueprint tentang definisi dadu. Untuk memiliki dadu yang sebenarnya dalam program, Anda perlu membuat instance objek Dice. (Dan jika Anda harus memiliki tiga dadu, Anda akan membuat tiga instance objek.)

ba2038022410942c.jpeg

  1. Untuk membuat instance objek Dice, dalam fungsi main(), buat val yang bernama myFirstDice dan inisialisasikan sebagai instance dari class Dice. Perhatikan tanda kurung setelah nama class, yang menunjukkan bahwa Anda membuat instance objek baru dari class tersebut.
fun main() {
    val myFirstDice = Dice()
}

Setelah memiliki objek myFirstDice, sesuatu yang dibuat dari blueprint, Anda dapat mengakses propertinya. Satu-satunya properti Dice adalah sides. Anda mengakses properti menggunakan "notasi titik". Jadi, untuk mengakses properti sides dari myFirstDice, Anda memanggil myFirstDice.sides yang dibaca "myFirstDice titik sides".

  1. Di bawah deklarasi myFirstDice, tambahkan pernyataan println() untuk menghasilkan jumlah sides dari myFirstDice.
println(myFirstDice.sides)

Kode akan terlihat seperti ini.

fun main() {
    val myFirstDice = Dice()
    println(myFirstDice.sides)
}

class Dice {
    var sides = 6
}
  1. Jalankan program Anda dan program akan menghasilkan jumlah sides yang ditentukan dalam class Dice.
6

Anda sekarang memiliki class Dice dan dadu myFirstDice yang sebenarnya dengan 6 sides.

Ayo kita lemparkan dadunya sekarang!

Melempar Dadu

Anda sebelumnya telah menggunakan fungsi untuk melakukan tindakan mencetak lapisan kue. Melempar dadu juga merupakan tindakan yang dapat diimplementasikan sebagai fungsi. Dan karena semua dadu dapat dilempar, Anda dapat menambahkan fungsi dadu di dalam class Dice. Fungsi yang ditentukan di dalam class juga disebut metode.

  1. Di class Dice, di bawah variabel sides, masukkan baris kosong, lalu buat fungsi baru untuk melempar dadu. Mulai dengan kata kunci Kotlin fun, diikuti dengan nama metode, kemudian diikuti dengan tanda kurung (), lalu terakhir diikuti dengan kurung kurawal buka dan tutup {}. Anda dapat mengosongkan baris di antara tanda kurung kurawal untuk menyediakan lebih banyak kode seperti yang ditunjukkan di bawah ini. Class Anda akan terlihat seperti ini.
class Dice {
    var sides = 6

    fun roll() {

    }
}

Saat Anda melemparkan dadu enam sisi, dadu akan menghasilkan angka acak antara 1 hingga 6.

  1. Dalam metode roll(), buat val randomNumber. Tetapkan angka acak dalam rentang 1..6. Gunakan notasi titik untuk memanggil random() pada rentang.
val randomNumber = (1..6).random()
  1. Setelah menghasilkan angka acak, cetak angka tersebut ke konsol. Metode roll() yang telah selesai akan terlihat seperti kode di bawah.
fun roll() {
     val randomNumber = (1..6).random()
     println(randomNumber)
}
  1. Untuk benar-benar melempar myFirstDice, di main(), panggil metode roll() di myFirstDice. Anda memanggil metode menggunakan "notasi titik". Jadi, untuk memanggil metode roll() dari myFirstDice, ketik myFirstDice.roll() yang dibaca "myFirstDice titik roll()".
myFirstDice.roll()

Kode yang sudah selesai akan terlihat seperti ini.

fun main() {
    val myFirstDice = Dice()
    println(myFirstDice.sides)
    myFirstDice.roll()
}

class Dice {
    var sides = 6

    fun roll() {
        val randomNumber = (1..6).random()
        println(randomNumber)
    }
}
  1. Jalankan kode! Anda akan melihat hasil acak lemparan dadu di bawah jumlah sisi. Jalankan kode beberapa kali, dan perhatikan bahwa jumlah sisi tetap sama, tetapi nilai lemparan dadu berubah.
6
4

Selamat! Anda telah menentukan class Dice dengan variabel sides dan fungsi roll(). Di fungsi main(), Anda membuat instance objek Dice baru, lalu memanggil metode roll() pada instance tersebut untuk menghasilkan angka acak.

Saat ini Anda sedang mencetak nilai randomNumber dalam fungsi roll() dan sudah berhasil! Namun, akan lebih berguna jika hasil fungsi ditampilkan ke apa saja memanggil fungsi. Misalnya, Anda dapat menetapkan hasil metode roll() ke variabel, lalu memindahkan pemain sebesar jumlah tersebut. Mari kita lihat cara melakukannya.

  1. Di main() ubah baris yang bertuliskan myFirstDice.roll(). Buat val dengan nama diceRoll. Tetapkan agar nilainya sama dengan yang ditampilkan oleh metode roll().
val diceRoll = myFirstDice.roll()

Kode ini belum melakukan apa pun karena roll() belum menampilkan apa pun. Agar kode ini berfungsi sebagaimana mestinya, roll() harus menampilkan sesuatu.

Pada codelab sebelumnya, Anda telah mempelajari bahwa Anda perlu menentukan jenis data untuk argumen input ke fungsi. Dengan cara yang sama, Anda harus menentukan jenis data untuk data yang ditampilkan oleh fungsi.

  1. Ubah fungsi roll() untuk menentukan jenis data yang akan ditampilkan. Dalam hal ini, angka acaknya adalah Int sehingga jenis nilai yang ditampilkan adalah Int. Sintaksis untuk menentukan jenis nilai yang ditampilkan adalah: Setelah nama fungsi, setelah tanda kurung, tambahkan titik dua, spasi, lalu kata kunci Int untuk jenis nilai yang ditampilkan dari fungsi tersebut. Definisi fungsi akan terlihat seperti kode di bawah ini.
fun roll(): Int {
  1. Jalankan kode ini. Anda akan melihat error di Tampilan Masalah. Tertulis:
A ‘return' expression required in a function with a block body (‘{...}')

Anda mengubah definisi fungsi untuk menampilkan Int, namun sistem mengeluhkan bahwa kode Anda tidak benar-benar menampilkan Int. "Block body" atau "function body" mengacu pada kode di antara tanda kurung kurawal dari suatu fungsi. Anda dapat memperbaiki error ini dengan menampilkan nilai dari fungsi menggunakan pernyataan return di akhir isi fungsi.

  1. Di roll(), hapus pernyataan println() dan ganti dengan pernyataan return untuk randomNumber. Fungsi roll() akan terlihat seperti kode di bawah ini.
fun roll(): Int {
     val randomNumber = (1..6).random()
     return randomNumber
}
  1. Pada main(), hapus pernyataan cetak untuk sisi dadu.
  2. Tambahkan pernyataan untuk mencetak nilai sides dan diceRoll dalam kalimat informatif. Fungsi main() yang sudah selesai akan terlihat mirip dengan kode di bawah ini.
fun main() {
    val myFirstDice = Dice()
    val diceRoll = myFirstDice.roll()
    println("Your ${myFirstDice.sides} sided dice rolled ${diceRoll}!")
}
  1. Jalankan kode dan hasilnya akan seperti ini.
Your 6 sided dice rolled 4!

Ini semua adalah kode Anda sejauh ini.

fun main() {
    val myFirstDice = Dice()
    val diceRoll = myFirstDice.roll()
    println("Your ${myFirstDice.sides} sided dice rolled ${diceRoll}!")
}

class Dice {
    var sides = 6

    fun roll(): Int {
        val randomNumber = (1..6).random()
        return randomNumber
    }
}

Tidak semua dadu memiliki 6 sisi! Dadu tersedia dalam berbagai bentuk dan ukuran: 4 sisi, 8 sisi, hingga 120 sisi!

  1. Dalam class Dice Anda, dalam metode roll(), ubah 1..6 yang di-hardcode untuk menggunakan sides sebagai gantinya sehingga rentang dan angka acak yang ditampilkan akan selalu sesuai dengan jumlah sisi.
val randomNumber = (1..sides).random()
  1. Pada fungsi main(), di bawah dan setelah mencetak dadu, ubah sides dari myFirstDice agar disetel ke 20.
myFirstDice.sides = 20
  1. Salin dan tempel pernyataan cetak yang ada di bawah ini setelah Anda mengubah jumlah sisi.
  2. Ganti pencetakan diceRoll dengan mencetak hasil pemanggilan metode roll() di myFirstDice.
println("Your ${myFirstDice.sides} sided dice rolled ${myFirstDice.roll()}!")

Program Anda akan terlihat seperti ini.

fun main() {

    val myFirstDice = Dice()
    val diceRoll = myFirstDice.roll()
    println("Your ${myFirstDice.sides} sided dice rolled ${diceRoll}!")

    myFirstDice.sides = 20
    println("Your ${myFirstDice.sides} sided dice rolled ${myFirstDice.roll()}!")
}

class Dice {
    var sides = 6

    fun roll(): Int {
        val randomNumber = (1..sides).random()
        return randomNumber
    }
}
  1. Jalankan program dan Anda akan melihat sebuah pesan untuk dadu 6 sisi, dan pesan kedua untuk dadu 20 sisi.
Your 6 sided dice rolled 3!
Your 20 sided dice rolled 15!

Maksud dari class ialah untuk mewakili sesuatu di dunia nyata yang sering kali bersifat fisik. Dalam hal ini, class Dice mewakili dadu fisik. Di dunia nyata, dadu tidak dapat mengubah jumlah sisinya. Jika menginginkan jumlah sisi yang berbeda, Anda harus mendapatkan dadu yang berbeda. Secara terprogram, ini berarti, daripada mengubah properti sisi dari instance objek Dice yang ada, Anda sebaiknya membuat instance objek dadu baru dengan jumlah sisi sesuai kebutuhan.

Dalam tugas ini, Anda akan memodifikasi class Dice sehingga dapat menentukan jumlah sisi saat membuat instance baru. Ubah definisi class Dice sehingga Anda dapat menyediakan jumlah sisi. Ini mirip dengan cara fungsi menerima argumen untuk input.

  1. Ubah definisi class Dice agar dapat menerima bilangan bulat yang disebut numSides. Kode di dalam class Anda tidak berubah.
class Dice(val numSides: Int) {
   // Code inside does not change.
}
  1. Di dalam class Dice, hapus variabel sides, karena sekarang Anda dapat menggunakan numSides.
  2. Selain itu, perbaiki rentang agar dapat menggunakan numSides.

Class Dice Anda akan terlihat seperti ini.

class Dice (val numSides: Int) {

    fun roll(): Int {
        val randomNumber = (1..numSides).random()
        return randomNumber
    }
}

Jika menjalankan kode ini, Anda akan melihat banyak error karena Anda perlu mengupdate main() agar berfungsi dengan perubahan pada class Dice.

  1. Di main(), untuk membuat myFirstDice dengan 6 sisi, Anda harus menyediakan jumlah sisi sebagai argumen untuk class Dice, seperti yang ditunjukkan di bawah ini.
    val myFirstDice = Dice(6)
  1. Dalam pernyataan cetak, ubah sides menjadi numSides.
  2. Di bawahnya, hapus kode yang mengubah sides menjadi 20 karena variabel tersebut sudah tidak ada.
  3. Hapus juga pernyataan println di bawahnya.

Fungsi main() akan terlihat seperti kode di bawah, dan jika Anda menjalankannya, seharusnya tidak akan ada error.

fun main() {
    val myFirstDice = Dice(6)
    val diceRoll = myFirstDice.roll()
    println("Your ${myFirstDice.numSides} sided dice rolled ${diceRoll}!")
}
  1. Setelah mencetak lemparan dadu pertama, tambahkan kode untuk membuat dan mencetak objek Dice kedua yang disebut mySecondDice dengan 20 sisi.
val mySecondDice = Dice(20)
  1. Menambahkan pernyataan cetak yang mengacak dan mencetak nilai yang ditampilkan.
println("Your ${mySecondDice.numSides} sided dice rolled  ${mySecondDice.roll()}!")
  1. Fungsi main() yang sudah selesai akan terlihat seperti ini.
fun main() {
    val myFirstDice = Dice(6)
    val diceRoll = myFirstDice.roll()
    println("Your ${myFirstDice.numSides} sided dice rolled ${diceRoll}!")

    val mySecondDice = Dice(20)
    println("Your ${mySecondDice.numSides} sided dice rolled ${mySecondDice.roll()}!")
}

class Dice (val numSides: Int) {

    fun roll(): Int {
        val randomNumber = (1..numSides).random()
        return randomNumber
    }
}
  1. Jalankan program yang telah selesai, dan hasilnya akan terlihat seperti ini.
Your 6 sided dice rolled 5!
Your 20 sided dice rolled 7!

Saat menulis kode, lebih baik tuliskan secara ringkas. Anda dapat menghapus variabel randomNumber dan menampilkan angka acak secara langsung.

  1. Ubah pernyataan return untuk menampilkan angka acak secara langsung.
fun roll(): Int {
    return (1..numSides).random()
}

Dalam pernyataan cetak kedua, Anda menempatkan panggilan untuk memasukkan nomor acak ke dalam template string. Anda dapat menghapus variabel diceRoll dengan melakukan hal yang sama di pernyataan cetak pertama.

  1. Panggil myFirstDice.roll() di template string dan hapus variabel diceRoll. Dua baris pertama kode main() Anda sekarang akan terlihat seperti ini.
val myFirstDice = Dice(6)
println("Your ${myFirstDice.numSides} sided dice rolled ${myFirstDice.roll()}!")
  1. Jalankan kode Anda dan seharusnya tidak akan ada perbedaan pada output.

Ini adalah kode final Anda setelah melakukan pemfaktoran ulang.

fun main() {
    val myFirstDice = Dice(6)
    println("Your ${myFirstDice.numSides} sided dice rolled ${myFirstDice.roll()}!")

    val mySecondDice = Dice(20)
    println("Your ${mySecondDice.numSides} sided dice rolled ${mySecondDice.roll()}!")
}

class Dice (val numSides: Int) {

    fun roll(): Int {
        return (1..numSides).random()
    }
}
fun main() {
    val myFirstDice = Dice(6)
    println("Your ${myFirstDice.numSides} sided dice rolled ${myFirstDice.roll()}!")

    val mySecondDice = Dice(20)
    println("Your ${mySecondDice.numSides} sided dice rolled ${mySecondDice.roll()}!")
}

class Dice (val numSides: Int) {

    fun roll(): Int {
        return (1..numSides).random()
    }
}
  • Panggil fungsi random() pada IntRange untuk menghasilkan angka acak: (1..6).random()
  • Class itu seperti blueprint objek. Template dapat memiliki properti dan perilaku yang diterapkan sebagai variabel dan fungsi.
  • Instance class menyatakan sebuah objek, dan sering kali berupa objek fisik, seperti dadu. Anda dapat memanggil tindakan pada objek dan mengubah atributnya.
  • Anda dapat memberikan nilai ke class saat membuat instance. Misalnya: class Dice(val numSides: Int) lalu buat instance dengan Dice(6).
  • Fungsi dapat menampilkan sesuatu. Tentukan jenis data yang akan ditampilkan dalam definisi fungsi, dan gunakan pernyataan return dalam isi fungsi untuk menampilkan sesuatu. Misalnya: fun example(): Int { return 5 }.

Lakukan hal berikut:

  • Berikan atribut warna yang lain pada class Dice dan buat beberapa contoh dadu dengan jumlah sisi dan warna yang berbeda!
  • Buat class Coin, berikan kemampuan untuk membalik, buat instance class, dan balik beberapa koin! Bagaimana cara menggunakan fungsi random() dengan suatu rentang untuk menyelesaikan tugas pembalikan koin?