Object-Oriented Programming (OOP) adalah paradigma pemrograman yang mengorganisasi kode ke dalam objek — entitas yang menggabungkan data (atribut) dan perilaku (metode).
Membuat Class dan Object
class Mahasiswa:
# __init__ dipanggil saat objek dibuat
def __init__(self, nama: str, nim: str, ipk: float):
self.nama = nama # atribut instance
self.nim = nim
self.ipk = ipk
def perkenalan(self) -> str:
return f"Halo, saya {self.nama} ({self.nim}), IPK: {self.ipk}"
def lulus_cum_laude(self) -> bool:
return self.ipk >= 3.75
# Membuat objek (instance)
mhs1 = Mahasiswa("Andi Pratama", "20210001", 3.82)
mhs2 = Mahasiswa("Budi Rahayu", "20210042", 3.45)
print(mhs1.perkenalan())
# Halo, saya Andi Pratama (20210001), IPK: 3.82
print(mhs1.lulus_cum_laude()) # True
print(mhs2.lulus_cum_laude()) # False
Atribut Class vs Atribut Instance
class Produk:
pajak_persen = 11 # atribut class (dibagi semua instance)
def __init__(self, nama: str, harga: float):
self.nama = nama # atribut instance (unik per objek)
self.harga = harga
def harga_dengan_pajak(self) -> float:
return self.harga * (1 + self.pajak_persen / 100)
p = Produk("Laptop", 10_000_000)
print(p.harga_dengan_pajak()) # 11100000.0
# Ubah pajak global
Produk.pajak_persen = 12
print(p.harga_dengan_pajak()) # 11200000.0
Enkapsulasi: _ dan __
class RekeningBank:
def __init__(self, pemilik: str, saldo_awal: float):
self.pemilik = pemilik
self.__saldo = saldo_awal # private (name mangling)
self._riwayat = [] # protected (konvensi)
def setor(self, jumlah: float):
if jumlah <= 0:
raise ValueError("Jumlah setor harus positif")
self.__saldo += jumlah
self._riwayat.append(f"+{jumlah:,.0f}")
def tarik(self, jumlah: float):
if jumlah > self.__saldo:
raise ValueError("Saldo tidak cukup")
self.__saldo -= jumlah
self._riwayat.append(f"-{jumlah:,.0f}")
@property
def saldo(self) -> float:
return self.__saldo
rek = RekeningBank("Citra", 500_000)
rek.setor(200_000)
rek.tarik(100_000)
print(f"Saldo: Rp{rek.saldo:,.0f}") # Saldo: Rp600,000
print(rek._riwayat) # ['+200,000', '-100,000']
# rek.__saldo ← AttributeError (tidak bisa diakses langsung)
@property — Getter/Setter yang Elegan
class Lingkaran:
def __init__(self, radius: float):
self._radius = radius
@property
def radius(self) -> float:
return self._radius
@radius.setter
def radius(self, nilai: float):
if nilai < 0:
raise ValueError("Radius tidak boleh negatif")
self._radius = nilai
@property
def luas(self) -> float:
import math
return math.pi * self._radius ** 2
c = Lingkaran(5)
print(f"Luas: {c.luas:.2f}") # Luas: 78.54
c.radius = 10
print(f"Luas: {c.luas:.2f}") # Luas: 314.16
# c.radius = -1 ← ValueError
Inheritance (Pewarisan)
class Hewan:
def __init__(self, nama: str, umur: int):
self.nama = nama
self.umur = umur
def info(self) -> str:
return f"{self.nama} ({self.umur} tahun)"
def suara(self) -> str:
return "..."
class Anjing(Hewan):
def __init__(self, nama: str, umur: int, ras: str):
super().__init__(nama, umur) # panggil __init__ parent
self.ras = ras
def suara(self) -> str:
return "Guk guk!"
def info(self) -> str:
return f"{super().info()} - Ras: {self.ras}"
class Kucing(Hewan):
def suara(self) -> str:
return "Meow!"
dog = Anjing("Rex", 3, "Husky")
cat = Kucing("Mimi", 2)
print(dog.info()) # Rex (3 tahun) - Ras: Husky
print(dog.suara()) # Guk guk!
print(cat.suara()) # Meow!
Polymorphism
Objek berbeda bisa diperlakukan seragam lewat antarmuka yang sama:
hewan_list = [
Anjing("Buddy", 4, "Labrador"),
Kucing("Kitty", 1),
Anjing("Max", 2, "Poodle"),
]
for h in hewan_list:
print(f"{h.nama}: {h.suara()}")
# Buddy: Guk guk!
# Kitty: Meow!
# Max: Guk guk!
__str__ dan __repr__
class Titik:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def __str__(self) -> str:
# Untuk print() — ramah pengguna
return f"({self.x}, {self.y})"
def __repr__(self) -> str:
# Untuk debugging — representasi teknis
return f"Titik(x={self.x}, y={self.y})"
def __add__(self, other: "Titik") -> "Titik":
# Overload operator +
return Titik(self.x + other.x, self.y + other.y)
t1 = Titik(1, 2)
t2 = Titik(3, 4)
print(t1) # (1, 2)
print(repr(t1)) # Titik(x=1, y=2)
print(t1 + t2) # (4, 6)
Kesimpulan
| Konsep | Deskripsi |
|---|---|
class | Cetak biru untuk membuat objek |
__init__ | Konstruktor — dijalankan saat objek dibuat |
| Atribut instance | Data unik per objek (self.nama) |
| Atribut class | Data dibagi semua instance |
@property | Akses atribut private dengan validasi |
| Inheritance | Anak mewarisi atribut dan metode parent |
| Polymorphism | Objek berbeda respons berbeda pada metode sama |
Setelah menguasai OOP, coba terapkan pola desain profesional: Mengenal Design Patterns: Fondasi Arsitektur yang Scalable — belajar bagaimana class dan inheritance digunakan dalam pola desain Singleton dan Factory.