Menu
CoddyTech

Pengikatan Statis Tertunda

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan PHP di Coddy. Pelajaran 36 dari 91.

Saat kamu menggunakan self:: di class induk, kata tersebut selalu merujuk pada class tempatnya ditulis, bukan class yang benar-benar digunakan. Hal ini dapat menyebabkan perilaku yang tidak terduga dalam pewarisan. Pengikatan statis tertunda mengatasi masalah ini dengan menggunakan kata kunci static::.

Perhatikan contoh ini ketika self:: tidak berfungsi seperti yang diharapkan:

<?php
class ParentClass {
    public static function create() {
        return new self();
    }
    
    public static function getClassName() {
        return self::class;
    }
}

class ChildClass extends ParentClass {}

$obj = ChildClass::create();
echo get_class($obj) . "\n";
echo ChildClass::getClassName();

Output:

ParentClass
ParentClass

Meskipun kita memanggil ChildClass::create(), kita mendapatkan object ParentClass karena self:: ditentukan saat kompilasi. Sekarang, mari gunakan static:::

<?php
class ParentClass {
    public static function create() {
        return new static();
    }
    
    public static function getClassName() {
        return static::class;
    }
}

class ChildClass extends ParentClass {}

$obj = ChildClass::create();
echo get_class($obj) . "\n";
echo ChildClass::getClassName();

Output:

ChildClass
ChildClass

Dengan static::, PHP menunggu hingga waktu runtime untuk menentukan class yang akan digunakan. Ini disebut binding "late" karena keputusannya ditunda. Ini penting untuk fungsi factory dan setiap method statis yang harus mengikuti pewarisan.

Poin Utama: Gunakan static:: alih-alih self:: jika kamu ingin class turunan mewarisi dan menyesuaikan perilaku statis dengan benar.

challenge icon

Tantangan

Mudah

Mari kita bangun sistem registri model yang menunjukkan keunggulan late static binding. Kamu akan membuat class dasar Model dengan method factory yang dapat diwarisi oleh class turunan. Berkat static::, setiap class turunan akan membuat instance dirinya sendiri dengan benar, bukan instance class induk.

Kamu akan mengatur kodemu dalam empat file:

  • Model.php: Buat class dasar Model dengan property static protected $tableName yang nilainya "models". Tambahkan method static create() yang menggunakan new static() untuk mengembalikan instance baru dari class apa pun yang memanggilnya. Tambahkan method static lain, getTable(), yang mengembalikan static::$tableName. Terakhir, tambahkan method describe() yang mengembalikan "[ClassName] from table [tableName]" menggunakan static::class dan static::$tableName.
  • User.php: Buat class User yang mewarisi Model. Sertakan file induknya. Ganti nilai property static $tableName menjadi "users". Class ini mewarisi semua method dari Model tanpa perubahan.
  • Product.php: Buat class Product yang mewarisi Model. Sertakan file induknya. Ganti nilai property static $tableName menjadi "products". Class ini juga mewarisi semua method dari class induknya.
  • main.php: Sertakan file User dan Product. Gunakan method factory create() yang diwarisi untuk membuat instance User dan Product. Untuk setiap instance, panggil describe() dan cetak hasilnya pada baris tersendiri. Lalu cetak nama tabel untuk setiap class menggunakan User::getTable() dan Product::getTable(), masing-masing pada baris tersendiri.

Keunggulannya adalah method create() dan getTable() hanya didefinisikan di class induk Model, tetapi tetap berfungsi dengan benar pada class turunan karena static:: menunda pengikatan hingga runtime. Saat kamu memanggil User::create(), PHP membuat instance User, bukan instance Model, karena static:: merujuk pada class yang benar-benar dipanggil.

Outputmu harus menampilkan empat baris: deskripsi untuk instance User, deskripsi untuk instance Product, nama tabel User, dan nama tabel Product.

Coba sendiri

<?php

require_once 'User.php';
require_once 'Product.php';

// TODO: Gunakan factory method create() yang diwarisi untuk membuat instance User

// TODO: Gunakan factory method create() yang diwarisi untuk membuat instance Product

// TODO: Panggil describe() pada instance User dan cetak hasilnya

// TODO: Panggil describe() pada instance Product dan cetak hasilnya

// TODO: Cetak User::getTable()

// TODO: Cetak Product::getTable()

?>
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler PHP online