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
ParentClassMeskipun 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
ChildClassDengan 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.
Tantangan
MudahMari 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 dasarModeldengan property static protected$tableNameyang nilainya"models". Tambahkan method staticcreate()yang menggunakannew static()untuk mengembalikan instance baru dari class apa pun yang memanggilnya. Tambahkan method static lain,getTable(), yang mengembalikanstatic::$tableName. Terakhir, tambahkan methoddescribe()yang mengembalikan"[ClassName] from table [tableName]"menggunakanstatic::classdanstatic::$tableName.User.php: Buat classUseryang mewarisiModel. Sertakan file induknya. Ganti nilai property static$tableNamemenjadi"users". Class ini mewarisi semua method dariModeltanpa perubahan.Product.php: Buat classProductyang mewarisiModel. Sertakan file induknya. Ganti nilai property static$tableNamemenjadi"products". Class ini juga mewarisi semua method dari class induknya.main.php: Sertakan file User dan Product. Gunakan method factorycreate()yang diwarisi untuk membuat instanceUserdanProduct. Untuk setiap instance, panggildescribe()dan cetak hasilnya pada baris tersendiri. Lalu cetak nama tabel untuk setiap class menggunakanUser::getTable()danProduct::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()
?>Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP
File EksternalPengenalan OOPclass vs objectKata Kunci $thismethodpropertyConstructor (__construct)Destructor (__destruct)Ringkasan: Kalkulator Sederhana4Pewarisan
Pewarisan DasarKata Kunci parent::Penimpaan methodKata Kunci finalClass AbstrakRingkasan: Hierarki Karyawan7Enkapsulasi
Public, Protected, PrivateModifier Akses secara MendalamGetter dan SetterPenyembunyian InformasiPromosi Constructor (8.0)Ulasan: Sistem Catatan Siswa2Namespace dan Autoloading
Pengenalan NamespaceKata Kunci useStandar Autoloading PSR-4Autoloader ComposerRingkasan: Proyek yang Terorganisasi5Interface dan Kontrak
Pengenalan InterfaceMengimplementasikan InterfaceImplementasi Beberapa InterfaceInterface vs Abstract ClassPetunjuk Tipe dengan InterfaceRekap: Kalkulator Bentuk8Magic Methods
Pengantar Magic Methods__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Cloning Object__serialize & __unserializeRingkasan: Koleksi Kustom11Sistem Tipe Data dan Penanganan Error
Deklarasi TipeTipe NullableTipe Union dan IntersectionClass ExceptionHierarki Exception KustomTry, Catch, FinallyRekap: Validator Form3Property dalam class
Property instance vs staticKonstanta dalam classMethod & property staticProperty private & protectedProperty readonly (PHP 8.1)Ulasan: Pengelola Rekening Bank6Polimorfisme
Meninjau Kembali Method OverridingPolimorfisme melalui AntarmukaPetunjuk Tipe dan Tipe UnionPengikatan Statis TertundaRangkuman: Pemroses PembayaranLatihan sendiri: Compiler PHP online