Belajar OOP PHP untuk Pemula: Konsep dan Contoh Lengkap

| | PHP
Belajar OOP PHP untuk Pemula: Konsep dan Contoh Lengkap

saya akui, waktu pertama kali belajar OOP di PHP, kepala saya langsung panas. class, object, inheritance, encapsulation, istilahnya saja sudah bikin pusing apalagi praktiknya. saya sempat bertahan di coding prosedural cukup lama karena malas pindah ke OOP, anggapannya ribet, buang-buang waktu, dan untuk project kecil terasa berlebihan 🙂

ternyata saya salah besar. setelah mulai pakai OOP di project nyata, terutama saat mulai menyentuh framework seperti Laravel, kode saya jadi jauh lebih rapi, gampang di-maintain, dan yang paling penting: komponen yang sudah dibuat bisa dipakai ulang di project lain tanpa nulis ulang dari nol. di artikel ini kita bahas fondasi OOP PHP langkah demi langkah dengan analogi sehari-hari dan contoh kode nyata yang bisa langsung kalian coba.

sebelum mulai, kalau kalian masih benar-benar awam dengan dasar sintaks PHP seperti variabel, perulangan, dan fungsi biasa, saya sarankan baca dulu panduan dasar di belajar php lengkap supaya lebih mudah mengikuti istilah di bawah.

Apa itu OOP?

OOP (Object-Oriented Programming) atau Pemrograman Berorientasi Objek adalah cara menulis kode dengan pendekatan objek. bayangkan kalian mendesain sebuah mobil di pabrik: ada mesin, roda, setir, dan pintu. masing-masing komponen adalah objek yang punya data (property, misalnya warna dan kapasitas) dan perilaku atau tindakan (method, misalnya maju, mundur, dan rem).

Perbedaan Gaya Prosedural vs OOP

di gaya prosedural, data dan fungsi hidup terpisah-pisah. di OOP, data dan fungsinya dibungkus jadi satu kesatuan:

// Gaya Prosedural: variabel dan fungsi terpisah
$nama = "Andi";
function sapaUser($nama) {
    return "Halo, $nama!";
}
echo sapaUser($nama);

// Gaya OOP: data dan fungsi menyatu di dalam class
class User {
    public $nama;

    public function sapa() {
        return "Halo, {$this->nama}!";
    }
}

$user = new User();
$user->nama = "Andi";
echo $user->sapa();

di aplikasi besar dengan puluhan tabel database, gaya OOP menyelamatkan kalian dari kekacauan nama variabel yang bentrok.

1. Class dan Object: Cetakan dan Hasilnya

dua istilah ini adalah pintu gerbang utama OOP:

  • Class adalah cetakan rancangan (blueprint)
  • Object adalah barang nyata hasil cetakan tersebut (instance)
<?php
// Definisi class (cetakan)
class Mobil {
    // Property (ciri-ciri mobil)
    public $merk;
    public $warna;
    public $kecepatan = 0;

    // Method (perilaku yang bisa dilakukan mobil)
    public function tambahKecepatan($kecepatanBaru) {
        $this->kecepatan += $kecepatanBaru;
        return "Mobil {$this->merk} sekarang melaju {$this->kecepatan} km/jam";
    }

    public function info() {
        return "{$this->merk} warna {$this->warna}";
    }
}

// Membuat object nyata dari cetakan Mobil
$mobilAvanza = new Mobil();
$mobilAvanza->merk = "Toyota Avanza";
$mobilAvanza->warna = "Putih";

$mobilBrio = new Mobil();
$mobilBrio->merk = "Honda Brio";
$mobilBrio->warna = "Kuning";

echo $mobilAvanza->info(); // Toyota Avanza warna Putih
echo "<br>";
echo $mobilAvanza->tambahKecepatan(40); // Mobil Toyota Avanza sekarang melaju 40 km/jam
?>

variabel $this di dalam method merujuk pada object yang sedang dipanggil saat itu. ketika $mobilAvanza->tambahKecepatan() dijalankan, $this->merk otomatis membaca “Toyota Avanza”.

2. Property dan Visibility (Access Modifier)

visibility menentukan dari mana saja sebuah property atau method boleh diakses:

KeywordRuang Akses
publicBebas diakses dari mana saja (luar class, dalam class, class turunan)
protectedHanya boleh diakses di dalam class itu sendiri dan class turunannya
privateHanya boleh diakses di dalam class tempat dia dideklarasikan
<?php
class RekeningBank {
    public $namaPemilik;       // informasi umum, boleh dibaca langsung
    protected $nomorRekening;  // rahasia, hanya untuk keluarga rekening
    private $saldo;            // sangat rahasia, jangan sampai disentuh sembarangan

    public function __construct($nama, $noRek, $saldoAwal) {
        $this->namaPemilik = $nama;
        $this->nomorRekening = $noRek;
        $this->saldo = $saldoAwal;
    }

    // Mengambil saldo lewat method resmi (getter)
    public function getSaldo() {
        return "Rp " . number_format($this->saldo, 0, ',', '.');
    }

    // Mengubah saldo lewat aturan ketat (setter)
    public function setorTunai($jumlah) {
        if ($jumlah <= 0) {
            return "Jumlah setor harus lebih dari 0!";
        }
        $this->saldo += $jumlah;
        return "Berhasil setor! Saldo baru: " . $this->getSaldo();
    }
}

$akun = new RekeningBank("Budi", "1234567890", 500000);
echo $akun->namaPemilik; // Budi
echo $akun->getSaldo();   // Rp 500.000

// Baris di bawah ini akan memicu fatal error jika diaktifkan:
// $akun->saldo = 999999999; // Error: Cannot access private property
?>

dengan menandai $saldo sebagai private, orang luar tidak bisa tiba-tiba mengubah nilai saldo secara curang. saldo hanya bisa berubah lewat method setorTunai() yang punya validasi. inilah prinsip dasar keamanan di OOP.

3. Constructor dan Destructor

constructor adalah method spesial yang otomatis jalan saat object pertama kali dibuat dengan kata kunci new.

<?php
class Produk {
    public $nama;
    public $harga;

    // Constructor otomatis jalan saat: new Produk(...)
    public function __construct($nama, $harga) {
        $this->nama = $nama;
        $this->harga = $harga;
        echo "Produk {$this->nama} berhasil didaftarkan.<br>";
    }

    public function getLabelHarga() {
        return "{$this->nama}: Rp " . number_format($this->harga, 0, ',', '.');
    }

    // Destructor otomatis jalan saat script selesai atau object dihapus
    public function __destruct() {
        // Cocok untuk menutup koneksi file atau database
    }
}

$laptop = new Produk("Laptop Asus", 8500000);
echo $laptop->getLabelHarga();
?>

Fitur Modern: Constructor Property Promotion (PHP 8+)

kalau kalian pakai PHP 8 ke atas, ada cara penulisan constructor yang jauh lebih ringkas bernama property promotion:

// Cara modern PHP 8.x: deklarasi property langsung di parameter constructor
class ProdukModern {
    public function __construct(
        public string $nama,
        public int $harga,
        private string $kodeRahasia = "PRD-001"
    ) {}
}

$item = new ProdukModern("Keyboard Mechanical", 450000);
echo $item->nama; // Keyboard Mechanical

kalian tidak perlu lagi mendeklarasikan property di atas lalu menulis $this->nama = $nama berulang kali. sintaks ini sangat umum dipakai di Laravel modern.

4. Inheritance (Pewarisan Sifat)

inheritance memungkinkan class anak (child class) mewarisi semua property dan method milik class induk (parent class) menggunakan kata kunci extends.

<?php
// Class Induk
class Karyawan {
    public function __construct(
        public string $nama,
        public int $gajiPokok
    ) {}

    public function getGaji() {
        return $this->gajiPokok;
    }
}

// Class Anak 1
class Programmer extends Karyawan {
    public int $bonusProject = 1500000;

    // Menimpa method induk (method overriding)
    public function getGaji() {
        return $this->gajiPokok + $this->bonusProject;
    }
}

// Class Anak 2
class Manager extends Karyawan {
    public int $tunjanganJabatan = 3000000;

    public function getGaji() {
        return $this->gajiPokok + $this->tunjanganJabatan;
    }
}

$dev = new Programmer("Rian", 6000000);
echo "Gaji {$dev->nama}: Rp " . number_format($dev->getGaji(), 0, ',', '.');
// Output: Gaji Rian: Rp 7.500.000
?>

Programmer otomatis punya property $nama dan $gajiPokok tanpa perlu nulis ulang constructor. kalian cukup menambahkan hal-hal spesifik yang dimiliki oleh programmer saja.

5. Encapsulation (Enkapsulasi Data)

enkapsulasi adalah teknik menyembunyikan data internal object agar tidak bisa dimanipulasi sembarangan dari luar, dan hanya membuka akses lewat getter dan setter yang sudah diberi filter.

<?php
class Mahasiswa {
    private string $nim;
    private string $nama;
    private int $nilai = 0;

    public function __construct(string $nim, string $nama) {
        $this->nim = $nim;
        $this->nama = $nama;
    }

    // Getter untuk membaca nilai
    public function getNilai(): int {
        return $this->nilai;
    }

    // Setter dengan validasi ketat
    public function setNilai(int $nilaiBaru): void {
        if ($nilaiBaru < 0 || $nilaiBaru > 100) {
            throw new InvalidArgumentException("Nilai harus berada di antara 0 sampai 100!");
        }
        $this->nilai = $nilaiBaru;
    }

    public function getGrade(): string {
        if ($this->nilai >= 85) return 'A';
        if ($this->nilai >= 70) return 'B';
        if ($this->nilai >= 55) return 'C';
        return 'D';
    }
}

$mhs = new Mahasiswa("240101", "Dina");
$mhs->setNilai(88);
echo "Grade {$mhs->getGrade()}"; // Grade A
?>

jika ada programmer lain yang mencoba mengisi $mhs->setNilai(150), program akan melempar error dan mencegah data sampah masuk ke database.

6. Polymorphism dan Interface

polymorphism artinya “banyak bentuk”. maksudnya: beberapa class yang berbeda bisa memiliki nama method yang sama, tetapi masing-masing punya cara kerja berbeda di dalamnya.

alat terbaik untuk mencapai polymorphism adalah interface:

<?php
// Interface mendefinisikan kontrak yang wajib dipatuhi
interface GatewayPembayaran {
    public function bayar(int $jumlah): string;
}

class MidtransGateway implements GatewayPembayaran {
    public function bayar(int $jumlah): string {
        return "Memproses pembayaran Rp $jumlah via Midtrans QRIS";
    }
}

class XenditGateway implements GatewayPembayaran {
    public function bayar(int $jumlah): string {
        return "Memproses pembayaran Rp $jumlah via Xendit Virtual Account";
    }
}

// Fungsi ini tidak peduli pakai gateway apa, asalkan mematuhi kontrak
function checkout(GatewayPembayaran $gateway, int $total) {
    echo $gateway->bayar($total) . "<br>";
}

checkout(new MidtransGateway(), 75000);
checkout(new XenditGateway(), 120000);
?>

kalau suatu hari aplikasi kalian mau nambah gateway baru (misal Doku atau Stripe), kalian tinggal buat class baru yang mengimplementasikan GatewayPembayaran tanpa perlu mengubah fungsi checkout() yang sudah ada.

7. Abstract Class vs Interface

sering muncul pertanyaan: kapan pakai abstract class, kapan pakai interface? berikut tabel pembandingnya:

AspekAbstract ClassInterface
Isi MethodBisa punya method konkret dan method abstractHanya deklarasi method (tanpa isi logika)
PropertyBisa punya property biasa dengan nilai defaultHanya bisa menyimpan konstanta (const)
PewarisanClass anak hanya bisa extends satu classClass bisa implements banyak interface
Tujuan utamaBerbagi kode dasar antar class sejenisMembuat standarisasi kontrak fungsi
<?php
// Contoh Abstract Class
abstract class Notifikasi {
    public function formatWaktu() {
        return date('Y-m-d H:i:s');
    }

    // Method ini wajib dibuat oleh class anak
    abstract public function kirim(string $pesan): bool;
}

class EmailNotifikasi extends Notifikasi {
    public function kirim(string $pesan): bool {
        echo "[{$this->formatWaktu()}] Kirim Email: $pesan";
        return true;
    }
}

$notif = new EmailNotifikasi();
$notif->kirim("Kode OTP kamu adalah 1234");
?>

8. Static Method dan Static Property

static method atau property bisa dipanggil langsung tanpa perlu membuat object baru lewat new. panggilannya menggunakan tanda titik dua ganda (::):

<?php
class StringHelper {
    public static function formatRupiah(int $angka): string {
        return "Rp " . number_format($angka, 0, ',', '.');
    }

    public static function slug(string $judul): string {
        return strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $judul)));
    }
}

// Langsung panggil tanpa: $helper = new StringHelper();
echo StringHelper::formatRupiah(150000); // Rp 150.000
echo "<br>";
echo StringHelper::slug("Belajar OOP PHP Pemula"); // belajar-oop-php-pemula
?>

static method sangat cocok untuk fungsi bantuan (helper) atau utility yang tidak menyimpan state di dalam memory.

Studi Kasus Nyata: Keranjang Belanja Sederhana

mari kita gabungkan konsep class, object, encapsulation, dan method dalam sebuah modul keranjang belanja:

<?php
class ItemKeranjang {
    public function __construct(
        private string $nama,
        private int $harga,
        private int $qty
    ) {}

    public function getSubtotal(): int {
        return $this->harga * $this->qty;
    }

    public function getInfo(): string {
        return "{$this->nama} ({$this->qty}x) = Rp " . number_format($this->getSubtotal(), 0, ',', '.');
    }
}

class KeranjangBelanja {
    private array $daftarItem = [];

    public function tambahItem(ItemKeranjang $item): void {
        $this->daftarItem[] = $item;
    }

    public function hitungTotal(): int {
        $total = 0;
        foreach ($this->daftarItem as $item) {
            $total += $item->getSubtotal();
        }
        return $total;
    }

    public function tampilkanNota(): void {
        echo "=== NOTA PEMBELIAN ===<br>";
        foreach ($this->daftarItem as $item) {
            echo $item->getInfo() . "<br>";
        }
        echo "----------------------<br>";
        echo "Total Bayar: Rp " . number_format($this->hitungTotal(), 0, ',', '.') . "<br>";
    }
}

// Penggunaan di aplikasi
$keranjang = new KeranjangBelanja();
$keranjang->tambahItem(new ItemKeranjang("Kopi Arabika", 35000, 2));
$keranjang->tambahItem(new ItemKeranjang("Croissant", 20000, 3));

$keranjang->tampilkanNota();
?>

coba perhatikan bagaimana class KeranjangBelanja dan ItemKeranjang saling bekerja sama. kodenya terbaca seperti bahasa manusia, mudah diuji coba, dan jika ada perubahan perhitungan diskon, kalian cukup mengubahnya di dalam class yang bersangkutan tanpa merusak bagian lain.

Kesimpulan

KonsepFungsi Utama
ClassBlueprint atau cetakan rancangan kode
ObjectBentuk nyata (instance) yang dibuat dari class
PropertyData atau variabel yang dimiliki objek
MethodFungsi atau perilaku yang bisa dilakukan objek
ConstructorInisialisasi awal saat object dibuat pertama kali
VisibilityMengatur batas hak akses (public, protected, private)
InheritanceMewariskan fitur dari class induk ke class anak
EncapsulationMelindungi data internal lewat getter dan setter
PolymorphismBanyak bentuk implementasi untuk kontrak fungsi yang sama
StaticPemanggilan method langsung tanpa instansiasi objek

OOP bukan sekadar gaya menulis kode, melainkan cara mengorganisasi logika aplikasi agar tetap terkendali saat project bertambah besar.

Baca Juga Mengenai :

Pertanyaan yang Sering Diajukan

Apa keuntungan memakai OOP dibanding prosedural di PHP?

OOP membuat kode terstruktur rapi ke dalam class dan object, sehingga mudah digunakan kembali (reusable) dan gampang dirawat saat project membesar. Pada kode prosedural, fungsi dan variabel terpisah-pisah di banyak file sehingga rawan bentrok nama dan sulit ditelusuri.

Apa perbedaan mendasar antara class dan object?

Class adalah blueprint atau cetakan rancangan, sedangkan object adalah bentuk nyata (instance) yang dibuat dari cetakan tersebut. Misalnya class Mobil mendefinisikan bahwa mobil punya merk dan warna, sedangkan object $mobilAvanza adalah mobil nyata yang dibuat dari class tersebut.

Kapan harus memakai public, protected, dan private?

Gunakan public jika property atau method memang boleh diakses bebas dari luar. Gunakan protected jika hanya boleh diakses oleh class itu sendiri dan class turunannya. Gunakan private untuk data sensitif internal yang sama sekali tidak boleh diubah langsung dari luar class.

Apa fungsi constructor (__construct) di PHP?

Constructor adalah method khusus yang otomatis dieksekusi saat sebuah object pertama kali dibuat dengan kata kunci new. Fungsinya menyiapkan nilai awal property atau koneksi penting yang dibutuhkan oleh object tersebut.

Apa perbedaan abstract class dan interface di PHP?

Interface hanya berisi daftar kontrak method tanpa implementasi sama sekali dan sebuah class bisa mengimplementasikan banyak interface. Abstract class bisa memiliki method konkret (sudah ada kodenya) sekaligus method abstract, tetapi class turunan hanya bisa mewarisi satu class saja.

Apakah wajib menguasai OOP sebelum belajar framework Laravel?

Sangat wajib. Seluruh arsitektur Laravel (Controller, Model Eloquent, Middleware, Service Provider) murni berbasis OOP. Tanpa paham konsep class, inheritance, dan dependency injection, belajar Laravel akan terasa sangat membingungkan.

Sigit Nurhanafi avatar
Full-stack developer & technical writer. Berpengalaman di PHP, Laravel, NodeJS, MySQL, dan Python. Aktif menulis tutorial pemrograman dan maintaining open-source projects di PemburuKode sejak 2021.