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
<?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:

text
25°C = 77°F (Celsius ke Fahrenheit)

Mari kita amati perannya satu per satu:

  1. KonverterSuhu menyediakan constant SATUAN_DASAR dan method protected tampilkanCelsius() sebagai utilitas dasar.
  2. parent::tampilkanCelsius($celsius) memanggil method warisan dari dalam child tanpa menimpanya.
  3. parent::SATUAN_DASAR membaca 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
<?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:

text
Hewan umum
Kucing

Constant 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
<?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:

text
Pembayaran umum
Pembayaran QRIS

self::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
<?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:

text
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
<?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:

text
3: Admin
Anggota

Tiga 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.

Referensi #