Episode ini membahas OOP di Swift: class, inheritance, dan method overriding, access control mulai dari public hingga private, protocols dengan protocol extensions sebagai fondasi protocol-oriented programming, serta generics dan type constraints untuk kode yang aman dan dapat digunakan kembali.

Swift adalah bahasa multi-paradigma, dan dua pilar terpentingnya adalah object-oriented programming dan protocol-oriented programming. Episode 5 membahas keduanya: class dengan pewarisan, aturan akses, protocol sebagai kontrak perilaku, serta generics untuk menulis kode yang abstrak dan aman tipe.
Banyak developer pemula menganggap protocol hanya pelengkap OOP. Kenyataannya, filosofi resmi Swift justru menempatkan protocol sebagai inti — bahkan Swift menambahkan fitur seperti protocol extensions dan protocol composition yang melampaui apa yang ditawarkan interface di bahasa lain.
Class di Swift mendukung inheritance: sebuah class bisa mewarisi properti, method, dan inisialisasi dari parent. Kelas induk disebut superclass, kelas turunan disebut subclass:
class Kendaraan {
var roda = 4
func deskripsi() -> String {
return "Kendaraan dengan \(roda) roda"
}
}
class Mobil: Kendaraan {
var bahanBakar = "bensin"
}
let mobil = Mobil()
print(mobil.deskripsi())
print(mobil.bahanBakar)class Mobil: Kendaraan mewarisi seluruh anggota Kendaraan dan menambah properti miliknya sendiri. Inheritance memungkinkan kode dibagikan, tetapi jangan berlebihan — hierarki yang terlalu dalam menjadi rapuh terhadap perubahan.
Subclass bisa mengganti implementasi method induk dengan kata kunci override:
class MobilListrik: Kendaraan {
var kapasitasBaterai = 60
override func deskripsi() -> String {
return "Mobil listrik dengan baterai \(kapasitasBaterai) kWh"
}
}
let tesla = MobilListrik()
print(tesla.deskripsi())override func deskripsi() mengganti perilaku parent. Swift mewajibkan kata kunci override untuk mencegah overriding tidak sengaja — tanpa kata kunci itu, kompilasi gagal.
Swift menyediakan lima tingkat akses dari yang paling terbuka hingga paling tertutup:
public struct AkunPengguna {
public private(set) var saldo: Double = 0
private var pin: String = "0000"
public mutating func tambahSaldo(_ jumlah: Double) {
saldo += jumlah
}
}public private(set) var saldo membuat properti saldo bisa dibaca publik tetapi hanya bisa diubah di dalam type. Penerapan access control yang disiplin menjaga invariant internal — di sinilah konsep encapsulation bekerja nyata.
Protocol mendeskripsikan properti dan method yang wajib dimiliki oleh tipe yang mengadopsinya, tanpa menyimpan implementasi:
protocol MenampilkanRingkas {
var judulRingkas: String { get }
func ringkasan() -> String
}
struct Artikel: MenampilkanRingkas {
var judulRingkas: String
var isi: String
func ringkasan() -> String {
return "\(judulRingkas): \(isi.prefix(40))"
}
}struct Artikel: MenampilkanRingkas menyatakan komitmen memenuhi kontrak protocol. Compiler memeriksa kepatuhan — lupa mengimplementasikan method berarti error kompilasi, bukan bug runtime.
Protocol extension memberi implementasi default sehingga setiap tipe yang mengadopsi protocol otomatis mendapat perilakunya:
extension MenampilkanRingkas {
func lengkap() -> String {
return judulRingkas + " - " + ringkasan()
}
}
let artikel = Artikel(judulRingkas: "Swift", isi: "Pemrograman modern")
print(artikel.lengkap())extension MenampilkanRingkas menambahkan method lengkap() untuk semua tipe yang mengadopsi protocol. Inilah inti protocol-oriented programming: perilaku dikomposisikan lewat protocol dan default implementation, bukan diwariskan lewat hierarki class yang kaku.
Generics memungkinkan kalian menulis kode yang bekerja untuk banyak tipe tanpa mengorbankan keamanan tipe:
func tukar<T>(_ a: inout T, _ b: inout T) {
let sementara = a
a = b
b = sementara
}
var x = 1
var y = 2
tukar(&x, &y)
print(x, y)func tukar<T>(_ a: inout T) bekerja untuk tipe apa pun — Int, String, atau tipe custom. Tanda inout berarti parameter dimodifikasi in-place. Generic mencegah kalian membuat kode duplikat untuk setiap tipe.
Kadang kalian perlu membatasi tipe yang boleh dipakai, misalnya tipe yang conform ke protocol tertentu:
func gabungkan<T: StringProtocol>(_ a: T, _ b: T) -> String {
return "\(a) + \(b)"
}
print(gabungkan("Swift", "iOS"))T: StringProtocol membatasi T pada tipe yang mengadopsi StringProtocol. Constraint membolehkan kompilasi memanggil anggota protocol itu pada parameter generic — kombinasi generics dan protocols adalah pasangan paling kuat di Swift.
Info
Kombinasi generics, protocols, dan protocol extensions adalah fondasi dari banyak API Swift modern seperti Collection, View di SwiftUI, dan Publisher di Combine. Perhatikan pola ini saat membaca kode pihak ketiga.
Inti yang harus dibawa pulang:
override.Di episode 6 selanjutnya kita akan membahas error handling dan debugging — penanganan error dengan throws, try, catch, dan defer, pembuatan custom error type, debugging di Xcode dengan breakpoint dan LLDB, serta assertions dan unit tests untuk memvalidasi perilaku. Saatnya membuat kode kalian tangguh!