Advertisement
  1. Code
  2. Swift

Belajar Swift dari Nol: Mengenal Kelas dan Struktur

Scroll to top
Read Time: 11 min
This post is part of a series called Swift From Scratch.
Swift From Scratch: Closures
Swift From Scratch: Inheritance and Protocols

() translation by (you can also view the original English article)

Di artikel sebelumnya dalam seri ini, kami membahas tentang dasar-dasar bahasa pemrograman Swift. Jika Anda mengikuti tutorial tersebut, sekarang Anda seharusnya sudah memiliki pemahaman yang bagus akan variabel, konstanta, fungsi, dan closure. Sekarang saatnya menggunakan apa yang telah kita pelajari sejauh ini dan  mengaplikasikan pengetahuan tersebut ke konsp-konsep berorientasi objek yang ada di Swift.

Untuk memahami konsep yang dibahasa di tutorial ini, penting bagi Anda untuk memiliki pemahamam dasar tentang pemrograman berbasis objek. Jika Anda belum akrab dengan kelas, objek, dan metode, saya sarankan Anda membaca terlebih dahulu topik-topik tersebut sebelum melanjutkan dengan artikel ini.

1. Perkenalan

Di artikel ini, kita akan mengeksplorasi blok bangunan fundamental pemrograman berorientasi objek di Swift, yakni kelas dan struktur. Di Swift, kelas dan struktur terasa dan berperilaku sangat mirip, tetapi ada sejumlah perbedaan utama yang harus Anda pahami untuk menghindari sejumlah perangkap yang umum terjadi.

Di Objective-C, kelas dan struktur sangatlah berbeda. Ini tidak berlaku untuk Swift. Misalnya di Swift, baik kelas maupun struktur bisa memiliki properti dan metode. Tidak seperti struktur C, struktur di Swift bisa diperluas dan diselaraskan ke protokol.

Pertanyaannya adalah "Apa perbedaan antara kelas dan struktur?" Kita akan menyambangi pertanyaan ini di bagian selanjutnya artikel ini. Pertama mari kita lihat seperti apa kelas di Swift.

2. Terminologi

Sebelum mulai bekerja dengan kelas dan struktur, saya ingin mengklarifikasi beberapa istilah yang umumnya digunakan dalam pemrograman berorientasi objek. Istilah kelas, objek, dan instance sering membingungkan orang yang masih baru terhadap pemrograman berorientasi objek dan oleh karenanya penting untuk diketahui bagaimana Swift menggunaan istilah-istilah ini.

Objek dan Instance

Kelas adalah cetak biru atau templat untuk instance kelas tersebut. Istilah objek sering digunakan untuk merujuk pada instance dari suatu kelas. Meskipun demikian, di Swift kelas dan struktur sangatlah mirip dan oleh karenannya lebih mudah dan tidak begitu membingungkan untuk menggunakan istilah instance bagi kelas maupun struktur.

Metode dan Fungsi

Di bagian awal seri ini, kita bekerja dengan beberapa fungsi. Dalam konteks kelas dan struktur, kita bisanya merujuk pada fungsi sebagai metode. Dengan kata lain, metode dan fungsi yang dimiliki oleh kelas atau struktur tertentu. Dalam konteks kelas dan struktur, Anda bisa menggunakan kedua istilah saling menggantikan karena tiap metode adalah fungsi.

3. Mendefinisikan suatu Kelas

Mari memulai perjalanan kita dengan mendefinisikan suatu kelas. Buka Xcode dan ciptakan tempat bermain baru. Hapus konten di tempat bermain itu dan masukkan definisi kelas berikut.

1
class Person {
2
    
3
}

Kata kunci class mengindikasikan bahwa kita sedang mendefinisikan suatu kelas yang dinamai Person. Implementasi kelas dilingkupi dengan sepasang kurung kurawal. Meskipun kelas Person tidak begitu bermanfaat dalam bentuknya yang sebenarnya, ini adalah kelas Swift yang benar dan fungsional.

Properti

Sebagaimana di kebanyakan bahasa pemrograman, suatu kelas bisa memiliki properti dan metode. Di contoh yang telah diperbarui di bawah ini, kita mendefinisikan tiga properti:

  • firstName, suatu properti variabel tipe String?
  • lastName, suatu properti variabel tipe String?
  • gender: suatu properti konstantan tipe String
1
class Person {
2
    var firstName: String?
3
    var lastName: String?
4
    let gender = "female"
5
}

Sebagaimana yang diilustrasikan di contoh, mendefinisikan properti di suatu definisi kelas sangat mirip dengan mendefinisikan variabel dan konstanta reguler. Kita menggunakan kata kunci var untuk mendefinisikan properti variabel dan kata kunci let mendefinisikan suatu properti konstanta.

Properti-properti di atas juga dikenal sebagai properti stored. Lebih lanjut di seri ini, kita akan mempelajari tentang properti computed. Sebagaimana disiratkan oleh namanya, properti stored adalah properti yang disimpan oleh instance kelas. Sangat mirip dengan properti-properti di Objective-C.

Penting untuk dicatat bahwa tiap properti yang disimpan harus punya nilai setelah inisialisasi atau didefinisikan sebagai tipe opsional. Di contoh di atas, kita memberikan nilai awal "female" pada properti gender. Ini memberitahu Swift bahwa properti gendernya adalah tipe String. Selanjutnya di artikel ini, kita akan melihat inisialisasi secara lebih detail dan mengeksplorasi bagaimana hal ini berhubungan dengan inisialisasi properti.

Meskipun properti gender didefinisikan sebagai suatu konstantam masih mungkin mengubah nilainya selama inisialisasi suatu instance Person. Beguu suatu instance diinisialisasi, properti gender tidak bisa lagi dimodifikasi karena kita mendefinisikan properti tersebut sebagai properti konstanta dengan kata kunci let. Selanjutnya ini akan menjadi lebih jelas di artikel ini ketika kita membahas tentang inisialisasi.

Metode

Kita bisa menambah perilaku atau fungsionalitas ke suatu kelas melalui fungsi atau metode. Di banyak bahasa pemrograman, istilah yang digunakan alih-alih fungsi dalam konteks kelas dan instance. Mendefinisikan metode hampir identik dengan mendefinisikan fungsi. Di contoh berikutnya, kita mendefinisikan metode fullName di kelas Person.

1
class Person {
2
    var firstName: String?
3
    var lastName: String?
4
    let gender = "female"
5
    
6
    func fullName() -> String {
7
        var parts: [String] = []
8
        
9
        if let firstName = self.firstName {
10
            parts += [firstName]
11
        }
12
        
13
        if let lastName = self.lastName {
14
            parts += [lastName]
15
        }
16
        
17
        return " ".join(parts)
18
    }
19
}

Metode fullName selanjutnya nested di definisi kelas. Metode ini tidak menerima parameter dan mengembalikan suatu String. Implementasi metode fullName cukup langsung ke tujuan. Melalui pengikatan opsional (optional binding), yang sudah kita bahas sebelumnya di seri ini, kita mengakses nilai yang disimpan dalam properti firstName dan lastName.

Kita menyimpan nama depan dan nama belakang instance Person di suatu array dan menggabungkan bagian-bagiannya dengan suatu spasi. Alasan untuk implementasi yang canggung ini harus jelas, nama depan dan belakang boleh kosong, inilah mengapa kedua properti adalah tipe String?.

Instansiasi

Kita telah mendefinisikan kelas dengan beberapa properti dan suatu metode. Bagaimana kita membuat suatu instance kelas Person? Jika Anda akrab dengan Objective-C, Anda akan menyukai keringkasan snippet berikut.

1
let john = Person()

Instansiasi suatu instance kelas sangat mirip dengan memanggil suatu fungsi. Untuk membuat suatu instance, nama kelas diikuti dengan sepasang tanda kurung, nilai yang dikembalikan lalu diberikan ke suatu konstanta atau variabel.

Di contoh kami, konstanta john sekarang menunjuk ke suatu instance dari kelas Person. Apakah itu berarti kita tidak bisa mengubah propertinya sama sekali? Contoh berikut menjawab pertanyaan ini.

1
john.firstName = "John"
2
john.lastName = "Doe"
3
john.gender = "male"

Kita bisa mengakses properti suatu instance dengan menggunakan failitas dot syntax. Di contoh tersebut, kita mengatur firstName ke "John", lastName ke "Doe" dan gender ke "male". Sebelum kita membuat kesimpulan apapun berdasarkan contoh di atas, kita harus memeriksa kesalahan yang ada di tempat bermainnya.

Pengaturan firstName dan lastName kelihatannya tidak mengakibatkan permasalahan apapun. Menetapkan "male" ke properti gender bagaimanapun tetap akan menghasilkan kesalahan. Penjelasannya sederhana. Meskipun john ditetapkan sebagai suatu konstanta, itu tidak akan mencegah modifikasi instance Person. Namun ada satu kekurangan, hanya properti variable yang bisa dimodifikasi setelah inisialisasi suatu instance. Properti yang didefinisikan sebagai konstanta tidak bisa dimodifikasi setelah inisialisasi.

Perhatikan bahwa saya menekankan kata setelah di kalimat sebelumnya. Sebuah properti konstanta bisa dimodifikasi selama inisialisasi instance. Meskipun properti gender tidak boleh diubah begitu instance Person dibuat, kelasnya tidak akan banyak bermanfaat jika, misalnya, kita hanya bisa menginstansiasi instance Person. Mari kita jadikan kelas Person sedikit lebih fleksibel.

Inisialisasi

Inisialisasi adalah langkah sekali seumur hidup suatu instance kelas atau struktur. Selama inisialisasi, kami menyiapkan instance untuk digunakan dengan mengisi propertinya dengan nilai-nilai awal. Inisialisasi suatu instance bisa diswakreasi dengan mengimplementasikan suatu initializer, suatu metode tipe khusus. Mari menambahkan initializer ke kelas Person.

1
class Person {
2
    var firstName: String?
3
    var lastName: String?
4
    let gender = "female"
5
    
6
    init() {
7
        gender = "male"
8
    }
9
}

Perhatikan bahwa initializernya, init, tidak dimulai dengan kata kunci func. Berlawanan dengan initializer di Objective-C, initializer di Swift tidak mengembalikan instance yang diinisialisasi.

Detail penting lainnya adalah cara mengatur properti gender dengan nilai awal. Meskipun properti gender didefinisikan sebagai properti konstanta, kita bisa mengatur nilainya di initializer. Kita mengatur properti gender dengan menggunakan nama properti, tetapi bak juga untuk lebih eksplisit dan menuliskan kode berikut:

1
init() {
2
    self.gender = "male"
3
}

Pada contoh di atas, self merujuk pada contoh yang diinisialisasi. Ini berarti self.gender merujuk pada properti gender dari instance. Kita bisa mengabaikan self, sebagaimana di contoh pertama, karena tidak ada kebingungan properti apa dimaksudkan. Meskipun tidak selalu seperti itu. Mari saya jelaskan apa maksudnya.

Parameter

Di banyak situasi, Anda mungkin ingin memasukkan nilai awal ke initializer untuk mengubahsuai instance yang Anda instansiasi. Ini dimungkinkan dengan membuat suatu initializer kustom yang menerima satu argumen atau lebih. Di contoh berikut kami membuat initializer kustom yang menerima satu argumen, gender, dari tipe String.

1
init(gender: String) {
2
    self.gender = gender
3
}

Ada dua hal yang perlu diperhatikan. Pertama, kita harus mengakses properti gender melalui self.gender untuk menghindari ambiguitas karena nama parameter lokal setara dengan gender. Yang kedua, meskipun kita belum menetapkan nama parameter eksternal, secara default Swift menciptakan nama parameter eksternal yang setara dengan nama parameter lokal. Hasilnya sama dengan seakan kita menambahkan simbol # sebagai prefiks paramter gender.

Di contoh berikut, kita menginstansiasi instance Person dengan memanggil initializer kustom yang baru saja kita definisikan.

1
let bart = Person(gender: "male")
2
3
println(bart.gender) // Outputs "male"

Meskipun nilai awal properti gender diset ke "female" di definisi kelas, dengan memasukkan nilai dari parameter gender kita bisa menetapkan nilai kustom ke konstanta properti gender dalam proses inisialisasi.

Banyak Initializer

Seperti di Objective-C, suatu kelas atau struktur bisa memiliki banyak initializer. Di contoh berikut, kami membuat dua instance Person. Di baris pertama, kami menggunakan initializer default. Di baris kedua, kami menggunakan initializer kustom yang kami definisikan sebelumnya.

1
let p1 = Person()
2
let p2 = Person(gender: "male")

4. Mendefinisikan suatu Struktur

Yang mengejutkan adalah bahwa struktur sangat mirip dengan kelas, tetapi berikut ada beberapa perbedaan kunci. Mari memulai dengan mendefinisikan suatu struktur dasar.

1
struct Wallet {
2
    var dollars: Int
3
    var cents: Int
4
    
5
    init() {
6
        dollars = 0
7
        cents = 0
8
    }
9
}

Sekilas satu-satunya perbedan adalah pada penggunaan kata kunci struct, alih-alih class. Contoh tersebut menunjukkan pada kita alternatif pendekatan untuk memasukkan nilai awal ke properti. Alih-alih mengeset nilai awal untuk tiap properti, kita bisa memberikan nilai awal properti dalam initializer struktur. Swift tidak akan melemparkan pesan kesalahan karena dia juga menginspeksi initializer untuk menentukan nilai awal—dan tipe—tiap properti.

5. Kelas dan Struktur

Anda mungkin mulai bertanya-tanya tentang perbedaan antara kelas dan struktur. Selayang pandang keduanya terlihat identik dalam bentuk dan fungsinya, dengan pengecualian kata kunci class dan struct. Kendatipun demikian ada sejumlah perbedaan utama.

Inheritance

Kelas mendukung inheritance, sedangkan struktur tidak. Contoh berikut mengilustrasikannya. Pola desain inheritance mutlak harus ada di pemrograman berorientasi objek dan di Swift inilah perbedaan utama antara kelas dan struktur.

1
class Person {
2
    var firstName: String?
3
    var lastName: String?
4
    let gender = "female"
5
    
6
    init(gender: String) {
7
        self.gender = gender
8
    }
9
}
10
11
class Student: Person {
12
    var school: String?
13
}
14
15
let student = Student(gender: "male")

Pada contoh di atas, kelas Person adalah parent atau superclass dari kelas Student. Ini berarti kelas Student mewarisi properti dan perilaku kelas Person. Baris terakhirnya mengilustrasikan ini. Kita menginisialisasi instance Student dengan memanggil initializer custom yang kita definisikan sebelumnya di kelas Person.

Menyalin dan Mereferensikan

Konsep berikut mungkin konsep Swift terpenting yang akan Anda pelajari hari ini, perbedaan antara tipe value dan reference. Struktur adalah tipe value, yang artinya tipe tersebut dilewati oleh suatu nilai. Suatu contoh mengilustrasikan hal tersebut dengan sangat baik.

1
struct Point {
2
    var x: Int
3
    var y: Int
4
    
5
    init(x: Int, y: Int) {
6
        self.x = x
7
        self.y = y
8
    }
9
}
10
11
var point1 = Point(x: 0, y: 0)
12
var point2 = point1
13
14
point1.x = 10
15
16
println(point1.x) // Outputs 10

17
println(point2.x) // Outputs 0

Kita mendefinisikan struktur Point untuk mengenkapsulasi data agar bisa menyimpan koordinat dalam ruang dua dimensi. Kita menginstansiasi point1 dengan x setara 0 dan y setara 0. Kita tetapkan point1 ke point2 dan mengeset koordinat x point1 ke 10. Jika kita membuat keluaran koordinat x kedua titik, kita akan menemukan bahwa keduanya tidak setara.

Struktur dilewati oleh nilai, sedangkan kelas oleh referensi. Jika Anda berencana untuk terus bekerja dengan Swift, Anda harus memahami pernyataan tersebut. Ketika kita menetapkan point1 ke point2, Swift membuat salinan point1 dan menetapkannya ke point2. Dengan kata lain, point1 dan point2 masing-masingnya menunjuk ke instance struktur Point yang berbeda.

Sekarang mari mengulangi latihan ini dengan kelas Person. Di contoh berikut, kita menginstansiasi instance Person, mengeset propertinya, menetapkan person1 hingga person2, dan memperbarui properti firstName dari person1. Untuk melihat referensi apa yang masuk untuk kelas, kita membuat keluaran nilai untuk properti firstName untuk kedua instance Person.

1
var person1 = Person(gender: "female")
2
3
person1.firstName = "Jane"
4
person1.lastName = "Doe"
5
6
var person2 = person1
7
8
person1.firstName = "Janine"
9
10
println(person1.firstName)
11
println(person2.firstName)

Contoh tersebut membuktikan bahwa kelas adalah tipe referensi. Ini berarti person1 dan person2 merujuk ke atau mereferensikan instance Person yang sama. Dengan menetapkan person1 ke person2, Swift tidak membuat salinan person1. Variabel person2 menunjuk ke instance Person yang sama dengan yang ditunjukkan oleh person1. Mengubah properti firstName person1 juga mempengaruhi properti firstName person2, karena keduanya mereferensikan instance Person yang sama.

Sebagaimana saya sebutkan beberapa kali dalam artikel ini, kelas dan struktur sangatlah mirip. Yang memisahkan kelas dan struktur sangatlah penting. Jika konsep yang disampaikan di atas belum jelas, saya dorong Anda membaca artikelnya sekali lagi dan membiarkan konsep tersebut meresap ke dalam pikiran.

Pelajari Lebih Banyak di Kursus Pemrograman Swift Kami

Jika Anda tertarik lebih mendalami pembelajaran Swift, Anda bisa memeriksa kursus lengkap kami tentang pengembangan Swift.

Kesimpulan

Di serial Belajar Swift dari Nol ini, kita mulai mengeksplorasi dasar-dasar pemrograman berorientasi objek di Swift. Kelas dan struktur adalah blok bangunan fundamental kebanyakan proyek Swift dan kita akan mempelajarinya lebih lanjut di tutorial-tutorial berikutnya dalam seri ini.

Di artikel berikutnya, kita akan melanjutkan eksplorasi kelas dan struktur dengan melihat lebih dekat pada properti dan inheritance.

Advertisement
Did you find this post useful?
Want a 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.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.