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:
| Keyword | Ruang Akses |
|---|---|
public | Bebas diakses dari mana saja (luar class, dalam class, class turunan) |
protected | Hanya boleh diakses di dalam class itu sendiri dan class turunannya |
private | Hanya 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:
| Aspek | Abstract Class | Interface |
|---|---|---|
| Isi Method | Bisa punya method konkret dan method abstract | Hanya deklarasi method (tanpa isi logika) |
| Property | Bisa punya property biasa dengan nilai default | Hanya bisa menyimpan konstanta (const) |
| Pewarisan | Class anak hanya bisa extends satu class | Class bisa implements banyak interface |
| Tujuan utama | Berbagi kode dasar antar class sejenis | Membuat 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
| Konsep | Fungsi Utama |
|---|---|
| Class | Blueprint atau cetakan rancangan kode |
| Object | Bentuk nyata (instance) yang dibuat dari class |
| Property | Data atau variabel yang dimiliki objek |
| Method | Fungsi atau perilaku yang bisa dilakukan objek |
| Constructor | Inisialisasi awal saat object dibuat pertama kali |
| Visibility | Mengatur batas hak akses (public, protected, private) |
| Inheritance | Mewariskan fitur dari class induk ke class anak |
| Encapsulation | Melindungi data internal lewat getter dan setter |
| Polymorphism | Banyak bentuk implementasi untuk kontrak fungsi yang sama |
| Static | Pemanggilan 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.

