Tiga kata kunci kecil — parent, self, dan static — mengatur bagaimana kode di dalam class merujuk member milik class itu sendiri atau milik induknya. Tanpa memahami ketiganya, hierarki OOP PHP mudah terasa seperti kotak hitam: method warisan berperilaku berbeda dari dugaan, dan constant seolah berubah nilai secara misterius. Pada chapter ini kita bedah peran masing-masing kata kunci, perbedaan mendasar antara self:: dan static:: yang sering menjebak, serta cara mengakses class constant melalui operator ::.
Mengakses Member Parent dengan Kata Kunci parent #
parent:: adalah cara child merujuk class induknya secara eksplisit — baik untuk memanggil method maupun membaca constant. Kita sudah memakainya untuk parent::__construct() pada Chapter Inheritance
; berikut penggunaan yang lebih lengkap:
<?php
class KonverterSuhu
{
public const SATUAN_DASAR = "Celsius";
protected function tampilkanCelsius(float $celsius): string
{
return "{$celsius}°C";
}
}
class KonverterFahrenheit extends KonverterSuhu
{
public function konversi(float $celsius): string
{
$fahrenheit = $celsius * 9 / 5 + 32;
$dasar = parent::tampilkanCelsius($celsius);
return "{$dasar} = {$fahrenheit}°F (" . parent::SATUAN_DASAR . " ke Fahrenheit)";
}
}
$konverter = new KonverterFahrenheit();
echo $konverter->konversi(25) . "\n";Output yang Dihasilkan:
25°C = 77°F (Celsius ke Fahrenheit)Mari kita amati perannya satu per satu:
KonverterSuhumenyediakan constantSATUAN_DASARdan methodprotectedtampilkanCelsius()sebagai utilitas dasar.parent::tampilkanCelsius($celsius)memanggil method warisan dari dalam child tanpa menimpanya.parent::SATUAN_DASARmembaca constant milik parent secara tegas.
Sebenarnya constant warisan juga bisa dibaca lewat self::SATUAN_DASAR karena pewarisan berlaku untuk constant; parent:: dipilih di sini karena tujuannya memang menunjuk asal nilai tersebut. Rujukan parent:: selalu mengarah ke class yang tertulis setelah extends pada child.
Perbedaan self dan static #
Inilah bagian yang paling sering menjebak. self:: merujuk ke class tempat baris kode ditulis, sedangkan static:: merujuk ke class object yang sedang menjalankan kode — mekanisme yang disebut late static binding. Keduanya tampak sama persis sampai pewarisan menimpa member yang dirujuk. Perhatikan contoh dengan constant:
<?php
class Hewan
{
public const JENIS = "Hewan umum";
public function jenisSelf(): string
{
return self::JENIS;
}
public function jenisStatic(): string
{
return static::JENIS;
}
}
class Kucing extends Hewan
{
public const JENIS = "Kucing";
}
$kucing = new Kucing();
echo $kucing->jenisSelf() . "\n";
echo $kucing->jenisStatic() . "\n";Output yang Dihasilkan:
Hewan umum
KucingConstant JENIS dideklarasikan di Hewan, lalu dideklarasikan ulang di Kucing. Method jenisSelf() ditulis di dalam Hewan, sehingga self::JENIS terikat ke Hewan apa pun object pemanggilnya — hasilnya selalu "Hewan umum". Sebaliknya, static::JENIS pada jenisStatic() menunggu object: karena pemanggilnya $kucing bertipe Kucing, resolusinya jatuh ke versi Kucing dan hasilnya "Kucing". Perilaku yang sama berlaku untuk method:
<?php
class Pembayaran
{
public static function metode(): string
{
return "Pembayaran umum";
}
public function tagihSelf(): string
{
return self::metode();
}
public function tagihStatic(): string
{
return static::metode();
}
}
class PembayaranQris extends Pembayaran
{
public static function metode(): string
{
return "Pembayaran QRIS";
}
}
$qris = new PembayaranQris();
echo $qris->tagihSelf() . "\n";
echo $qris->tagihStatic() . "\n";Output yang Dihasilkan:
Pembayaran umum
Pembayaran QRISself::metode() di dalam tagihSelf() terikat ke Pembayaran sejak kode ditulis, sedangkan static::metode() di dalam tagihStatic() menoleh ke class dari object $qris — yaitu PembayaranQris — lalu menjalankan versi override-nya. Panduan praktisnya: gunakan self:: untuk member yang memang dikunci pada class tersebut, dan static:: bila child diperbolehkan menimpa member yang dirujuk. Mekanisme lengkap late static binding akan dibedah tuntas pada Chapter Late Static Binding
.
self di Dalam Method Static #
Method static — method milik class, bukan object — juga bebas memakai self:: untuk memanggil member static lain di class yang sama. Pola ini umum dipakai untuk merangkai helper dalam satu wadah:
<?php
class Validasi
{
private const POLA_EMAIL = '/^[^@\s]+@[^@\s]+\.[^@\s]+$/';
public static function email(string $alamat): bool
{
return preg_match(self::POLA_EMAIL, $alamat) === 1;
}
public static function emailKorporat(string $alamat): bool
{
// Method static memanggil method static lain melalui self::.
$valid = self::email($alamat);
return $valid && str_ends_with($alamat, "@example.com");
}
}
var_dump(Validasi::email("[email protected]"));
var_dump(Validasi::emailKorporat("[email protected]"));
var_dump(Validasi::emailKorporat("[email protected]"));Output yang Dihasilkan:
bool(true)
bool(true)
bool(false)Method emailKorporat() memanggil self::email() tanpa perlu object, dan self::POLA_EMAIL membaca constant private milik class tersebut. Pemakaian self:: di sini aman karena Validasi tidak dirancang untuk diwarisi dan ditimpa. Jika suatu saat child boleh menimpa email(), ganti panggilan menjadi static::email() agar versi child yang dijalankan — persis pelajaran subbab sebelumnya.
Mengakses Class Constant dengan Operator :: #
Operator :: (disebut scope resolution operator) adalah gerbang menuju seluruh member milik class: constant, method static, dan property static. Untuk constant, polanya NamaClass::NAMA_CONSTANT:
<?php
class LevelPengguna
{
public const TAMU = 1;
public const ANGGOTA = 2;
public const ADMIN = 3;
public static function label(int $level): string
{
return match ($level) {
self::TAMU => "Tamu",
self::ANGGOTA => "Anggota",
self::ADMIN => "Admin",
default => "Tidak dikenal",
};
}
}
echo LevelPengguna::ADMIN . ": " . LevelPengguna::label(LevelPengguna::ADMIN) . "\n";
echo LevelPengguna::label(LevelPengguna::ANGGOTA) . "\n";Output yang Dihasilkan:
3: Admin
AnggotaTiga constant menyimpan angka level, dan method static label() menerjemahkannya melalui match dengan self::TAMU, self::ANGGOTA, dan self::ADMIN sebagai pembanding. Di luar class, ekspresi LevelPengguna::ADMIN dievaluasi menjadi 3 — nilainya bisa langsung dipakai dalam string, perbandingan, maupun elemen array. Constant class hidup di level class: nilainya sama untuk semua object dan tidak dapat diubah setelah didefinisikan.
Ringkasan #
parent:: merujuk class induk, self:: merujuk class tempat kode ditulis, dan static:: merujuk class yang sedang menjalankan kode — perbedaan self dan static baru terasa ketika pewarisan menimpa member yang dirujuk. Operator :: menjadi pintu ke seluruh member level class, termasuk constant yang dibahas pada chapter ini. Beberapa contoh di atas sudah menampilkan method yang dipanggil tanpa object sama sekali; chapter berikutnya membedahnya secara utuh: static properties dan methods, dari property yang dibagi seluruh object hingga batas-batas desain yang harus diwaspadai.