Nesne Klonlamaya Derinlemesine Bakış
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 61 / 91.
Bu kursta daha önce __clone sihirli metodunu öğrendin. Şimdi nesneler özellik olarak başka nesneler içerdiğinde sığ ve derin klonlama arasındaki kritik farkı inceleyelim.
Varsayılan olarak PHP, klonlama sırasında sığ bir kopyalama gerçekleştirir. Skaler değerler çoğaltılır, ancak nesne özellikleri aynı nesnelere referans olarak kalır:
<?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;
Çıktı:
Alice - London$clone->name değerini değiştirmenin orijinali etkilemediğine, ancak adres şehrini değiştirmenin etkilediğine dikkat et! Her iki nesne de aynı Address örneğini paylaşır.
İç içe nesnelerin de klonlandığı bir derin kopya oluşturmak için __clone uygulayın:
<?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;
Çıktı:
ParisArtık her Person kendi bağımsız Address nesnesine sahip. Nesneleriniz birden fazla iç içe nesne içerdiğinde, özgün nesne ile kopya arasında gerçek bağımsızlık sağlamak için her birini __clone içinde klonlamalısınız.
Görev
KolayGüçsüz ve derin klonlama arasındaki farkı gösteren bir belge yönetim sistemi oluşturalım. Yazar bilgileri içeren belgeler oluşturacak ve bir belgeyi klonlamanın gerçekten bağımsız bir kopya oluşturmasını sağlayacaksınız.
Kodunuzu üç dosyaya ayıracaksınız:
Author.php: Bir belgenin yazarını temsil eden birAuthorsınıfı oluşturun. Genel bir$name(string) ve genel bir$email(string) tanımlamak için yapıcı destekli özellik tanımlamayı kullanın.Document.php: Bir yazar içeren birDocumentsınıfı oluşturun. Author dosyasını dahil edin. Sınıf şunları yapmalıdır:- Genel bir
$title(string) ve genel bir$author(Author) için yapıcı destekli özellik tanımlamayı kullanın - Derin klonlama gerçekleştirmek için
__clone()sihirli metodunu uygulayın; bir belge klonlandığında yazarı da klonlanmalıdır, böylece klonun yazarındaki değişiklikler orijinali etkilemez "[title] by [author name] ([author email])"değerini döndüren birgetInfo()metoduna sahip olun
- Genel bir
main.php: Document dosyasını dahil edin. Üç girdi alacaksınız: bir belge başlığı, bir yazar adı ve bir yazar e-posta adresi.Sağlanan girdileri kullanarak bir
Authorile birDocumentoluşturun. Belgeyi klonlayın, ardından klonun yazar adına" (Copy)"ekleyerek klonun yazar adını değiştirin ve klonun başlığının başına"Copy of "ekleyin.İki satır yazdırın:
- Orijinal belgenin bilgileri
- Klonlanan belgenin bilgileri
Derin klonlama doğru şekilde uygulanmışsa, klonun yazarını değiştirdikten sonra bile orijinal belgenin yazarı değişmeden kalmalıdır.
Bu görev, derin klonlamanın neden önemli olduğunu gösterir. __clone() doğru şekilde uygulanmadan her iki belge de aynı Author nesnesini paylaşır ve birinde yapılan değişiklik diğerini etkiler.
Kendin dene
<?php
require_once 'Document.php';
// Girdileri oku
$title = trim(fgets(STDIN));
$authorName = trim(fgets(STDIN));
$authorEmail = trim(fgets(STDIN));
// TODO: Sağlanan ad ve e-posta ile bir Author oluştur
// TODO: Sağlanan başlık ve Author ile bir Document oluştur
// TODO: Belgeyi klonla
// TODO: Klonun yazar adını sonuna " (Copy)" ekleyerek değiştir
// TODO: Klonun başlığını başına "Copy of " ekleyerek değiştir
// TODO: Orijinal belgenin bilgilerini yazdır
// TODO: Klonlanmış belgenin bilgilerini yazdır
?>Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesneler$this Anahtar SözcüğüMetotlarÖzelliklerYapıcı (__construct)Yıkıcı (__destruct)Tekrar - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımparent:: Anahtar SözcüğüMetot Geçersiz Kılmafinal Anahtar SözcüğüSoyut SınıflarTekrar - Çalışan Hiyerarşisi7Kapsülleme
Public, Protected, PrivateErişim Belirleyicileri DerinlemesineGetter ve Setter'larBilgi GizlemeYapıcı Özellik Terfisi (8.0)Tekrar - Öğrenci Kayıt Sistemi10İleri Düzey OOP Kavramları
Composition ve KalıtımBağımlılık EnjeksiyonuAnonim SınıflarEnum'lar (PHP 8.1)Fiber'lar (PHP 8.1)Nesne Klonlamaya Derinlemesine BakışÜreteçler ve Yineleyiciler13Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıBileşik KalıpDepo Kalıbı2Namespace’ler ve Autoloading
Namespace’lere Girişuse Anahtar SözcüğüPSR-4 Autoloading StandardıComposer AutoloaderTekrar - Düzenli Proje5Arayüzler ve Sözleşmeler
Arayüzlere GirişArayüzleri UygulamaBirden Çok Arayüz UygulamaArayüz ve Soyut Sınıf KarşılaştırmasıArayüzlerle Tür İpuçlarıTekrar - Şekil Hesaplayıcı8Sihirli Metotlar
Sihirli Metotlara Giriş__toString ve __debugInfo__get, __set, __isset, __unset__call ve __callStatic__clone ve Nesne Klonlama__serialize ve __unserializeTekrar - Özel Koleksiyon3Sınıf Özellikleri
Örnek ve Statik ÖzelliklerSınıflarda SabitlerStatik Metotlar ve ÖzelliklerPrivate ve Protected ÖzelliklerSalt Okunur Özellikler (PHP 8.1)Tekrar - Banka Hesabı Yöneticisi6Çok Biçimlilik
Metot Geçersiz Kılmayı Yeniden Ele AlmaArayüzler Yoluyla Çok BiçimlilikTür İpuçları ve Birleşim TürleriGeç Bağlanan Statik ÇağrılarÖzet - Ödeme İşlemcisi9Trait'ler
Trait'lere GirişBirden Çok Trait KullanımıTrait Çakışmalarını ÇözümlemeTrait'lerde Soyut MetotlarTrait'ler ve Kalıtım Karşılaştırması12Tasarım Desenleri 1. Bölüm
Tasarım Desenlerine GirişSingleton DeseniFactory DeseniObserver DeseniStrategy DeseniKendi başına pratik yap: Online PHP derleyicisi