Object-Oriented Python untuk Pemula: Class, Object, dan Dataclass

Python By TryzTech Team
PythonOOPClassesBeginnerSoftware Design
Bagikan

Object-oriented programming atau OOP sering terdengar besar dan akademis. Padahal dalam praktik Python, OOP bisa dipahami dengan sederhana: object adalah data yang dibungkus bersama behavior yang relevan.

Kamu tidak harus memakai class untuk semua hal. Banyak kode Python tetap lebih enak ditulis dengan function biasa. Tapi saat data dan behavior mulai sering jalan bareng, class bisa membuat kode lebih rapi.

Gunakan OOP untuk memperjelas batas sebuah konsep, bukan sekadar supaya kode terlihat lebih profesional. Sebelum membuat class, tanyakan: apakah object ini punya identitas, data yang bertahan, dan operasi yang selalu berkaitan dengan data tersebut? Jika tidak, function dan dictionary mungkin sudah cukup.

Object sebagai data plus behavior

Bayangkan expense dalam aplikasi pencatat pengeluaran. Expense punya data:

  • title
  • amount
  • category

Expense juga bisa punya behavior:

  • mengecek apakah pengeluaran besar
  • memformat amount
  • mengubah data menjadi dictionary

Kalau data dan behavior itu selalu dipakai bersama, object bisa membantu.

Object juga membantu menjaga aturan. Misalnya, BankAccount dapat memastikan saldo tidak berkurang melebihi batas yang diizinkan. Aturan itu diletakkan dekat dengan data yang dijaganya, sehingga caller tidak perlu mengulang validasi di banyak tempat.

Membuat class sederhana

Class adalah blueprint. Object adalah hasil nyata dari blueprint itu.

# File: 01-class-object.py
class Expense:
    pass

expense = Expense()
print(expense)

Kode di atas membuat class kosong. Belum berguna, tapi menunjukkan bentuk paling dasar.

init dan instance attribute

Method __init__ berjalan saat object dibuat. Kita bisa memakainya untuk menerima data awal.

# File: 02-user-class.py
class Expense:
    def __init__(self, title, amount):
        self.title = title
        self.amount = amount

expense = Expense("Keyboard", 350_000)

print(expense.title)
print(expense.amount)

self merujuk ke object yang sedang dibuat atau sedang memakai method. self.title dan self.amount disebut instance attribute karena nilainya melekat pada instance tertentu.

Method

Method adalah function yang hidup di dalam class.

# File: 03-init-attribute.py
class Expense:
    def __init__(self, title, amount):
        self.title = title
        self.amount = amount

    def is_large(self):
        return self.amount >= 100_000

expense = Expense("Keyboard", 350_000)
print(expense.is_large())

is_large() bisa mengakses self.amount karena method itu milik object expense.

Class vs instance

Class adalah blueprint:

# File: 04-method.py
class User:
    pass

Instance adalah object yang dibuat dari class:

# File: 05-class-vs-instance.py
user_a = User()
user_b = User()

Setiap instance bisa punya data berbeda.

# File: 06-dataclass.py
class User:
    def __init__(self, name):
        self.name = name

user_a = User("Ayu")
user_b = User("Budi")

print(user_a.name)
print(user_b.name)

Pahami perbedaan ini dulu sebelum masuk ke konsep yang lebih jauh seperti inheritance.

Dataclass untuk object data

Kalau class kamu terutama berisi data, dataclass membuat kode lebih ringkas.

# File: 07-bank-account.py
from dataclasses import dataclass

@dataclass
class Expense:
    title: str
    amount: int

    def is_large(self):
        return self.amount >= 100_000

expense = Expense("Keyboard", 350_000)
print(expense.is_large())
print(expense)

Dengan dataclass, Python otomatis membuat __init__ dan representasi object yang lebih nyaman dibaca.

Gunakan dataclass saat object terutama berfungsi sebagai wadah data. Jika ada aturan validasi atau perubahan state yang harus selalu dijaga, tambahkan method seperti is_large() atau gunakan class biasa agar behavior tetap dekat dengan data.

Contoh: BankAccount

Class berguna saat ada aturan yang perlu menjaga data.

# File: 08-composition.py
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def deposit(self, amount):
        if amount <= 0:
            raise ValueError("Amount must be positive")

        self.balance += amount

    def withdraw(self, amount):
        if amount > self.balance:
            raise ValueError("Insufficient balance")

        self.balance -= amount

account = BankAccount("Ayu")
account.deposit(100_000)
account.withdraw(40_000)

print(account.balance)

Tanpa class, owner, balance, dan aturan deposit/withdraw bisa tersebar di banyak function. Dengan class, aturan itu berada dekat dengan data yang dijaga.

Perhatikan bahwa method deposit() memvalidasi amount sebelum mengubah balance. Ini contoh encapsulation sederhana: caller tidak perlu tahu detail perubahan saldo, cukup memanggil operasi yang tersedia dan menangani error jika aturan dilanggar.

Composition dibanding inheritance

Pemula sering terlalu cepat belajar inheritance. Inheritance memang berguna, tapi tidak selalu pilihan pertama.

Composition berarti sebuah object menyimpan object lain.

# File: 09-inheritance-overuse.py
from dataclasses import dataclass

@dataclass
class Customer:
    name: str
    email: str

@dataclass
class Order:
    customer: Customer
    total: int

customer = Customer("Ayu", "[email protected]")
order = Order(customer, 250_000)

print(order.customer.email)

Untuk banyak kasus aplikasi sehari-hari, composition lebih mudah dipahami daripada inheritance bertingkat.

Contohnya, Order memiliki Customer; order bukan customer. Ini hubungan “has-a”, sehingga composition lebih cocok. Inheritance lebih tepat saat subclass benar-benar merupakan bentuk khusus dari parent dan dapat dipakai di tempat yang sama tanpa perilaku mengejutkan.

Kapan OOP membantu?

OOP biasanya membantu ketika:

  • Data dan behavior sering dipakai bersama.
  • Ada aturan yang perlu menjaga perubahan data.
  • Kamu punya beberapa object dengan bentuk sama.
  • Kode function mulai sering mengoper dictionary besar ke banyak tempat.

Contoh yang cocok: user, order, invoice, bank account, task, expense, product, atau game character.

Kapan function biasa cukup?

Function biasa sering cukup ketika:

  • Logic-nya kecil.
  • Data tidak punya behavior khusus.
  • Kamu hanya melakukan transformasi sederhana.
  • Class hanya akan berisi satu method.

Contoh:

# File: 10-function-enough.py
def calculate_total(prices):
    return sum(prices)

Tidak perlu membuat class hanya untuk function sesederhana ini.

Kesalahan umum

Kesalahan pertama adalah membuat class terlalu besar. Jika class punya banyak tanggung jawab, pecah menjadi class atau function yang lebih kecil.

Kesalahan kedua adalah memakai inheritance terlalu dini. Mulai dari composition dan function sederhana dulu.

Kesalahan ketiga adalah shared mutable state di level class.

# File: 11-class-mistake.py
class Cart:
    items = []

items di atas dibagi oleh semua instance. Lebih aman taruh di __init__:

# File: 12-private-state.py
class Cart:
    def __init__(self):
        self.items = []

Latihan mini

Coba buat:

  • Class Task dengan title, done, dan method mark_done().
  • Dataclass Product dengan name, price, dan method is_expensive().
  • Class BankAccount dengan deposit dan withdraw.
  • Class Order yang menyimpan beberapa item dan menghitung total.
  • Versi function biasa dari salah satu contoh, lalu bandingkan mana yang lebih enak dibaca.

Checklist sebelum lanjut

Sebelum membuat class, coba tulis versi function dan dictionary terlebih dahulu. Jika versi itu masih pendek dan jelas, class belum tentu memberi manfaat. Jika aturan validasi mulai tersebar atau beberapa function selalu menerima data yang sama, itulah sinyal bahwa object mungkin membantu.

Setelah membuat class, uji state awal, operasi yang valid, dan operasi yang harus ditolak. Class yang baik bukan hanya punya banyak method; ia membuat aturan domain lebih mudah ditemukan dan lebih sulit dilanggar secara tidak sengaja.

Lanjut ke project structure

Setelah memahami OOP, langkah berikutnya adalah menyusun project Python yang lebih rapi: folder, virtual environment, dependency, dan testing. Lanjut ke Python Project Structure: venv, pip, Requirements, dan Testing.

Kalau ingin mengulang bagian sebelumnya, baca Python Files, Errors, dan Modules.

Lanjutkan membaca topik yang masih satu konteks.

Jangan Ketinggalan Info Terbaru

Dapatkan artikel teknologi, tips, dan insights menarik langsung ke email Kamu.