Pendalaman Kloning object
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan PHP di Coddy. Pelajaran 61 dari 91.
Kamu telah mempelajari magic method __clone sebelumnya dalam kursus ini. Sekarang, mari kita pelajari perbedaan penting antara cloning dangkal dan mendalam ketika object memiliki object lain sebagai property.
Secara default, PHP melakukan salinan dangkal saat melakukan cloning. Nilai skalar diduplikasi, tetapi property object tetap menjadi referensi ke object yang sama:
<?php
class Address {
public function __construct(public string $city) {}
}
class Person {
public function __construct(
public string $name,
public Address $address
) {}
}
$original = new Person("Alice", new Address("Paris"));
$clone = clone $original;
$clone->name = "Bob";
$clone->address->city = "London";
echo $original->name . " - " . $original->address->city;
Output:
Alice - LondonPerhatikan bahwa mengubah $clone->name tidak memengaruhi object aslinya, tetapi mengubah kota pada alamat ternyata berpengaruh! Kedua object berbagi instance Address yang sama.
Untuk membuat salinan mendalam yang juga mengkloning object bersarang, implementasikan __clone:
<?php
class Person {
public function __construct(
public string $name,
public Address $address
) {}
public function __clone(): void {
$this->address = clone $this->address;
}
}
$original = new Person("Alice", new Address("Paris"));
$clone = clone $original;
$clone->address->city = "London";
echo $original->address->city;
Output:
ParisSekarang setiap Person memiliki Address independen miliknya sendiri. Saat object-mu berisi beberapa object bertingkat, kamu harus menyalin masing-masing di __clone agar objek asli dan salinannya benar-benar independen.
Tantangan
MudahMari kita bangun sistem pengelolaan dokumen yang menunjukkan perbedaan antara cloning dangkal dan cloning dalam. Kamu akan membuat dokumen yang berisi informasi penulis, dan memastikan bahwa cloning dokumen menghasilkan salinan yang benar-benar mandiri.
Kamu akan mengatur kodemu dalam tiga file:
Author.php: Buat classAuthoryang mewakili penulis dokumen. Gunakan promosi konstruktor untuk mendefinisikan$namepublik (string) dan$emailpublik (string).Document.php: Buat classDocumentyang berisi seorang penulis. Sertakan file Author. Class ini harus:- Menggunakan promosi konstruktor untuk
$titlepublik (string) dan$authorpublik (Author) - Mengimplementasikan magic method
__clone()untuk melakukan cloning dalam. Saat dokumen di-clone, penulisnya juga harus di-clone agar perubahan pada penulis salinan tidak memengaruhi dokumen asli - Memiliki method
getInfo()yang mengembalikan"[title] by [author name] ([author email])"
- Menggunakan promosi konstruktor untuk
main.php: Sertakan file Document. Kamu akan menerima tiga input: judul dokumen, nama penulis, dan email penulis.Buat
DocumentdenganAuthormenggunakan input yang diberikan. Clone dokumen, lalu ubah nama penulis pada salinan dengan menambahkan" (Copy)"di akhir namanya dan ubah judul salinan dengan menambahkan"Copy of "di awal judulnya.Cetak dua baris:
- Info dokumen asli
- Info dokumen hasil cloning
Jika cloning dalammu diterapkan dengan benar, penulis dokumen asli akan tetap tidak berubah meskipun kamu mengubah penulis salinannya.
Tantangan ini menunjukkan pentingnya cloning dalam. Tanpa implementasi __clone() yang tepat, kedua dokumen akan berbagi object Author yang sama, sehingga perubahan pada salah satunya akan memengaruhi yang lain.
Coba sendiri
<?php
require_once 'Document.php';
// Baca input
$title = trim(fgets(STDIN));
$authorName = trim(fgets(STDIN));
$authorEmail = trim(fgets(STDIN));
// TODO: Buat Author dengan nama dan email yang diberikan
// TODO: Buat Document dengan judul yang diberikan dan Author tersebut
// TODO: Klon dokumen
// TODO: Ubah nama penulis pada hasil klon dengan menambahkan " (Copy)" di belakangnya
// TODO: Ubah judul hasil klon dengan menambahkan "Copy of " di depannya
// TODO: Cetak info dokumen asli
// TODO: Cetak info dokumen hasil klon
?>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 Siswa10Konsep OOP Lanjutan
Komposisi vs PewarisanInjeksi Dependensiclass AnonimEnum (PHP 8.1)Fiber (PHP 8.1)Pendalaman Kloning objectGenerator dan Iterator2Namespace 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