Menu
Coddy logo textTech

Trait Çakışma Çözümü

Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 53 / 91.

İki trait aynı isme sahip metotlar tanımladığında, PHP ölümcül bir hata (fatal error) verir. Bu çakışmanın nasıl ele alınacağını insteadof ve as operatörlerini kullanarak PHP'ye açıkça belirtmelisiniz.

<?php
trait FileLogger {
    public function log(string $message): void {
        echo "File: $message";
    }
}

trait DatabaseLogger {
    public function log(string $message): void {
        echo "DB: $message";
    }
}

class Application {
    use FileLogger, DatabaseLogger {
        FileLogger::log insteadof DatabaseLogger;
        DatabaseLogger::log as logToDatabase;
    }
}

$app = new Application();
$app->log("Error occurred");
$app->logToDatabase("Error occurred");

Çıktı:

File: Error occurred
DB: Error occurred

insteadof operatörü, bir çakışma olduğunda hangi trait'in metodunun kullanılacağını seçer. Bu örnekte, FileLogger::log kazanır ve varsayılan log() metodu olur. as operatörü bir takma ad oluşturarak diğer trait'in metoduna farklı bir isimle erişmenizi sağlar.

Bir metodun görünürlüğünü değiştirmek için as ifadesini de kullanabilirsiniz:

<?php
trait Greeting {
    public function sayHello(): void {
        echo "Hello!";
    }
}

class Person {
    use Greeting {
        sayHello as private;
    }
}

Bu, sayHello() metodunu, trait içinde public olmasına rağmen Person sınıfı içinde private yapar. Çakışma çözümü, trait metotlarının sınıflarınıza nasıl entegre edileceği üzerinde size ince ayarlı kontrol sağlar.

challenge icon

Görev

Kolay

Farklı kanalların mesaj gönderebildiği bir bildirim sistemi kuralım, ancak birden fazla trait aynı metot adını sağladığında oluşacak çakışmaları çözmemiz gerekiyor.

Kodunuzu dört dosya halinde düzenleyeceksiniz:

  • EmailNotifier.php"Email: [message]" döndüren notify(string $message) metoduna sahip EmailNotifier adında bir trait oluşturun.
  • SmsNotifier.php"SMS: [message]" döndüren notify(string $message) metoduna sahip SmsNotifier adında bir trait oluşturun.
  • AlertService.php — Her iki traiti de kullanan bir AlertService sınıfı oluşturun. Her iki trait de bir notify() metoduna sahip olduğundan, bu çakışmayı çözmeniz gerekecek:
    • Varsayılan notify() metodu olarak EmailNotifier::notify kullanın
    • SmsNotifier::notify metodu için notifyBySms adında bir takma ad (alias) oluşturun
    Ayrıca, her iki bildirim metodunu da çağıran ve bunları ayrı satırlarda birleştirilmiş olarak döndüren bir notifyAll(string $message) metodu ekleyin.
  • main.php — Gerekli tüm dosyaları dahil edin ve bir AlertService örneği oluşturun. Bir girdi alacaksınız: bir mesaj dizesi. Üç satır yazdırın:
    • Mesaj ile notify() çağırmanın sonucu
    • Mesaj ile notifyBySms() çağırmanın sonucu
    • Mesaj ile notifyAll() çağırmanın sonucu

Bu, bir isimlendirme çakışması olduğunda insteadof anahtar kelimesinin hangi trait metodunun kazanacağını nasıl belirlediğini, as anahtar kelimesinin ise diğer trait metoduna farklı bir isimle erişmenizi nasıl sağladığını gösterir.

Kopya kağıdı

Birden fazla trait aynı isme sahip metotlar tanımladığında, PHP insteadof ve as operatörlerini kullanarak açık bir çakışma çözümü gerektirir.

insteadof operatörü, hangi trait'in metodunun varsayılan olarak kullanılacağını seçer:

<?php
trait FileLogger {
    public function log(string $message): void {
        echo "File: $message";
    }
}

trait DatabaseLogger {
    public function log(string $message): void {
        echo "DB: $message";
    }
}

class Application {
    use FileLogger, DatabaseLogger {
        FileLogger::log insteadof DatabaseLogger;
        DatabaseLogger::log as logToDatabase;
    }
}

$app = new Application();
$app->log("Error occurred"); // File: Error occurred
$app->logToDatabase("Error occurred"); // DB: Error occurred

as operatörü, bir trait metodu için takma ad (alias) oluşturarak farklı bir isim altında erişim sağlar.

as operatörünü metot görünürlüğünü değiştirmek için de kullanabilirsiniz:

<?php
trait Greeting {
    public function sayHello(): void {
        echo "Hello!";
    }
}

class Person {
    use Greeting {
        sayHello as private;
    }
}

Kendin dene

<?php
require_once 'AlertService.php';

// Girdiyi oku
$message = trim(fgets(STDIN));

// YAPILACAK: Bir AlertService örneği oluşturun

// YAPILACAK: Mesaj ile notify() çağırma sonucunu yazdırın

// YAPILACAK: Mesaj ile notifyBySms() çağırma sonucunu yazdırın

// YAPILACAK: Mesaj ile notifyAll() çağırma sonucunu yazdırın
?>
quiz iconKendini test et

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