🐍 📗 Bagian 2 (Struktur Data, OOP & Proyek) • Modul 08 100% Standar Industri & Vokasi

Pemrograman Berorientasi Objek (OOP)

Paradigma OOP modern di Python: Class & Object, constructor __init__, methods, encapsulation & property decorators, inheritance (pewarisan), dan polymorphism.

Target Pembelajaran:
  • Memahami peran parameter self saat method dieksekusi di balik layar.
  • Menerapkan Enkapsulasi data dengan teknik Name Mangling (__private).
  • Menggunakan method super() untuk pewarisan konstruktor Parent Class.
  • Membuat representasi string objek yang elegan dengan Dunder Method __str__.
Empat Pilar Utama Pemrograman Berorientasi Objek (Enkapsulasi, Pewarisan, Polimorfisme, Abstraksi).
Gambar 8.2: Empat Pilar Utama Pemrograman Berorientasi Objek (Enkapsulasi, Pewarisan, Polimorfisme, Abstraksi).

1. Cara Kerja `self` di Balik Layar

Konsep OOP Dasar: Class sebagai Cetak Biru vs Object Real di Memori.
Gambar 8.1: Konsep OOP Dasar: Class sebagai Cetak Biru vs Object Real di Memori.

Banyak pemula bertanya: "Mengapa kita wajib menuliskan self sebagai parameter pertama pada method class?"

💡 Rahasia Eksekusi Method Python:

Ketika Anda memanggil rek1.setor(50000), interpreter Python di latar belakang sebenarnya mengubah sintaks tersebut menjadi:

RekeningBank.setor(rek1, 50000) # rek1 dikirim sebagai argumen pertama 'self'!

Jadi self hanyalah variabel referensi yang menunjuk ke objek pemanggil itu sendiri di memori.

2. Magic Methods (Dunder Methods)

Dunder (Double Underscore) adalah method bawaan spesial yang diawali dan diakhiri dua garis bawah. Mengimplementasikan dunder method membuat objek kustom Anda dapat berinteraksi dengan fungsi bawaan Python seperti print(), len(), atau operator +.

python (dunder_methods.py)
class Playlist:
    def __init__(self, nama):
        self.nama = nama
        self.lagu = []

    def tambah_lagu(self, judul):
        self.lagu.append(judul)

    # Dijalankan otomatis saat objek dipanggil oleh print() atau str()
    def __str__(self):
        return f"Playlist '{self.nama}' ({len(self.lagu)} lagu)"

    # Dijalankan otomatis saat objek dipanggil oleh len()
    def __len__(self):
        return len(self.lagu)

my_music = Playlist("Lagu Favorit")
my_music.tambah_lagu("Bohemian Rhapsody")
my_music.tambah_lagu("Imagine")

print(my_music)        # Output: Playlist 'Lagu Favorit' (2 lagu)
print(len(my_music))   # Output: 2

3. Enkapsulasi & Pewarisan Terpadu

Hierarki Pewarisan Kelas dan Rantai Resolusi Konstruktor dengan super().
Gambar 8.3: Hierarki Pewarisan Kelas dan Rantai Resolusi Konstruktor dengan super().
python (enkapsulasi_inheritance.py)
class Akun:
    def __init__(self, username, password):
        self.username = username
        self.__password = password  # Private Attribute (Name Mangling)

    def verifikasi_password(self, input_pass):
        return self.__password == input_pass

class AkunAdmin(Akun):
    def __init__(self, username, password, level_akses=1):
        super().__init__(username, password)
        self.level_akses = level_akses

    def hapus_database(self, input_pass):
        if self.verifikasi_password(input_pass):
            print(f"[SUCCESS] Admin {self.username} berhasil menghapus database.")
        else:
            print("[ERROR] Password salah! Akses ditolak.")

admin = AkunAdmin("superadmin", "Rahasia123#")
admin.hapus_database("Rahasia123#")

4. Kuis Pemahaman & Latihan

🧠 Kuis Cepat: Apa nama mekanisme proteksi atribut `__nama` di Python?
Klik untuk melihat jawaban & pembahasan
Jawaban: Name Mangling
Penjelasan: Python tidak benar-benar mengunci atribut private, melainkan mengubah namanya secara otomatis menjadi _NamaClass__nama untuk mencegah benturan nama pada class turunan dan menghindari akses tidak sengaja.

Tantangan 8: Desain Class Kendaraan Listrik (EV)

Buat Class Mobil dengan atribut merk dan kecepatan. Buat Child Class MobilListrik yang mewarisi Mobil dan menambahkan atribut __kapasitas_baterai serta method isi_daya(persen) yang memastikan daya tidak melebihi 100%.

Kriteria: Gunakan super().__init__(merk, kecepatan) pada konstruktor MobilListrik.
📋 Cheat Sheet: Pemrograman Berorientasi Objek (OOP)
Cheat Sheet
Sintaks / Perintah Keterangan Fungsi
class NamaKelas: Mendefinisikan kerangka kelas blueprint objek baru
def __init__(self, ...): Konstruktor inisialisasi state awal atribut objek
def nama_method(self): Method instance yang merepresentasikan perilaku objek
def __str__(self): Dunder method untuk representasi teks readable saat di-print
class Anak(Induk): Inheritance (pewarisan sifat dan method dari superclass)
self._proteksi, self.__privat Konvensi enkapsulasi atribut terproteksi dan privat
🛠️ Praktikum Terkait

Jobsheet 05: OOP Dasar & Desain Kelas

Implementasikan sistem simulasi perbankan OOP lengkap dengan kelas Akun, Nasabah, Transaksi, dan Rekening Bunga.

⚠️ Perangkap Pemula: Lupa Parameter self pada Method Class
Waspada Error

Menuliskan method di dalam class tanpa argumen self, sehingga memicu TypeError saat method dipanggil melalui instance objek.

Kode Salah (Memicu Error)
class Persegi:
    def __init__(self, sisi):
        self.sisi = sisi

    # ERROR: Lupa menyertakan parameter self
    def hitung_luas(): 
        return 5 * 5

p = Persegi(5)
print(p.hitung_luas()) 
# TypeError: Persegi.hitung_luas() takes 0 positional arguments but 1 was given
Solusi Benar & Aman
class Persegi:
    def __init__(self, sisi):
        self.sisi = sisi

    # Solusi Benar: Cantumkan self sebagai parameter pertama
    def hitung_luas(self):
        return self.sisi * self.sisi

p = Persegi(5)
print(p.hitung_luas()) # Berjalan lancar: 25
Penyebab & Solusi: Saat Anda memanggil p.hitung_luas(), Python secara otomatis menyisipkan objek instance p ke dalam argumen pertama. Parameter self wajib dideklarasikan pada setiap method instance.
💡 Tips Pythonic: Magic Method __str__ vs Method Cetak Manual
Standar PEP 8

Integrasikan kelas Anda dengan ekosistem Python menggunakan dunder method standar daripada membuat fungsi cetak kustom.

Kurang Pythonic (Hindari)
# Kurang Pythonic (Method manual untuk cetak profil)
class AkunUser:
    def __init__(self, username, level):
        self.username = username
        self.level = level

    def cetak_profil(self):
        print("User: " + self.username + " [" + self.level + "]")

user1 = AkunUser("budi99", "Admin")
user1.cetak_profil()
Pythonic Way (Direkomendasikan)
# Pythonic (Implementasikan __str__ untuk representasi string)
class AkunUser:
    def __init__(self, username, level):
        self.username = username
        self.level = level

    def __str__(self):
        return f"User: {self.username} [{self.level}]"

user1 = AkunUser("budi99", "Admin")
print(user1) # print() otomatis memanggil __str__()
Kelebihan __str__: Dengan menyediakan dunder method __str__, objek kelas dapat langsung digunakan di dalam print(objek), f"{objek}", logging, maupun interface grafis tanpa perlu memanggil method khusus.
🎯

Cek Pemahaman Mandiri

Uji pemahaman Anda terhadap konsep bab ini dengan feedback evaluasi instan.

2 Soal Pilihan Ganda
Q1

Apa fungsi parameter self pada setiap method di dalam class Python?

💡 Pembahasan: self merupakan referensi ke instance objek yang sedang aktif, memungkinkan method mengakses atribut dan method lain milik objek tersebut.

Q2

Bagaimana cara menerapkan Encapsulation (atribut privat) pada class Python menurut konvensi standar?

💡 Pembahasan: Prefix dua garis bawah __ memicu mekanisme Name Mangling di Python, yang menyembunyikan atribut agar tidak dapat diakses langsung secara bebas dari luar class.