Menu
Coddy logo textTech

Çoklu Trait Kullanımı

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

Tek bir trait kullanışlıdır, ancak asıl güç birden fazla trait'i tek bir sınıfta birleştirdiğinizde ortaya çıkar. PHP, ihtiyacınız olan sayıda trait eklemenize izin vererek sınıfınıza aynı anda birkaç kaynaktan yetenekler kazandırır.

Birden fazla trait kullanmak için, use anahtar kelimesinden sonra bunları virgülle ayırarak listelemeniz yeterlidir:

<?php
trait Timestampable {
    public function getTimestamp(): string {
        return date('Y-m-d H:i:s');
    }
}

trait Identifiable {
    private string $id;
    
    public function generateId(): void {
        $this->id = uniqid('id_');
    }
    
    public function getId(): string {
        return $this->id;
    }
}

class Post {
    use Timestampable, Identifiable;
    
    public function __construct(public string $title) {
        $this->generateId();
    }
}

$post = new Post("Hello World");
echo $post->getId() . " - " . $post->getTimestamp();

Çıktı:

id_6789abc123 - 2024-01-15 10:30:00

Post sınıfı artık her iki trait'ten de metotlara sahiptir. Her trait kendi işlevselliğini katar - Timestampable zamanla ilgili metotlar sağlarken, Identifiable benzersiz kimlikleri (ID) yönetir. Bu yaklaşım, her trait'in tek bir sorumluluğa odaklanmasını sağlayarak kodunuzu daha modüler ve yeniden kullanılabilir hale getirir.

İki trait aynı isme sahip metotlara sahip olduğunda ne olur? Bu, bir sonraki derste inceleyeceğimiz bir çakışma durumudur.

challenge icon

Görev

Kolay

Ürünlere hem fiyatlandırma hem de envanter yetenekleri kazandırmak için birden fazla trait'i birleştiren bir ürün yönetim sistemi oluşturalım. Her trait tek bir sorumluluğu üstlenecek ve ürün sınıfınız her ikisinden de işlevsellik kazanacaktır.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • Priceable.php — Fiyatlandırma işlevselliğini yöneten Priceable adında bir trait oluşturun. Trait şunlara sahip olmalıdır:
    • Özel (private) bir özellik $price (float)
    • Fiyatı kaydeden bir setPrice(float $price) metodu
    • Fiyatı döndüren bir getPrice() metodu
    • Fiyatı 2 ondalık basamaklı "$[price]" olarak biçimlendirilmiş şekilde döndüren bir getFormattedPrice() metodu
  • Stockable.php — Envanteri yöneten Stockable adında bir trait oluşturun. Trait şunlara sahip olmalıdır:
    • Özel (private) bir özellik $stock (integer)
    • Stok miktarını kaydeden bir setStock(int $quantity) metodu
    • Mevcut stoğu döndüren bir getStock() metodu
    • Stok 0'dan büyükse true, aksi takdirde false döndüren bir isInStock() metodu
  • main.php — Her iki trait dosyasını da dahil edin ve hem Priceable hem de Stockable trait'lerini kullanan bir Product sınıfı oluşturun. Genel (public) bir $name özelliği tanımlamak için constructor promotion kullanın. Yapıcı metod (constructor) ayrıca bir fiyat ve stok miktarı kabul etmeli ve bunları ayarlamak için trait metodlarını kullanmalıdır.

    Üç girdi alacaksınız: bir ürün adı, bir fiyat ve bir stok miktarı. Bu değerlerle bir ürün oluşturun ve dört satır yazdırın:

    • Ürün adı
    • Biçimlendirilmiş fiyat (getFormattedPrice() kullanarak)
    • Stok miktarı
    • Stokta varsa "Available", yoksa "Out of stock"

Bu, birden fazla trait'in birlikte nasıl çalıştığını gösterir — Product sınıfınız bir trait'ten fiyatlandırma yetenekleri, diğerinden envanter yönetimi kazanarak her bir konuyu düzgün bir şekilde ayrı tutarken bunları tam özellikli bir üründe birleştirir.

Kopya kağıdı

Bir sınıfta birden fazla trait kullanmak için, bunları use anahtar kelimesinden sonra virgülle ayırarak listeleyin:

<?php
trait Timestampable {
    public function getTimestamp(): string {
        return date('Y-m-d H:i:s');
    }
}

trait Identifiable {
    private string $id;
    
    public function generateId(): void {
        $this->id = uniqid('id_');
    }
    
    public function getId(): string {
        return $this->id;
    }
}

class Post {
    use Timestampable, Identifiable;
    
    public function __construct(public string $title) {
        $this->generateId();
    }
}

$post = new Post("Hello World");
echo $post->getId() . " - " . $post->getTimestamp();
// Çıktı: id_6789abc123 - 2024-01-15 10:30:00

Her bir trait, sınıfa kendi işlevselliğini katar. Bu yaklaşım, her bir trait'in tek bir sorumluluğa odaklanmasını sağlayarak kodu daha modüler ve yeniden kullanılabilir hale getirir.

Kendin dene

<?php
require_once 'Priceable.php';
require_once 'Stockable.php';

// TODO: Hem Priceable hem de Stockable trait'lerini kullanan bir Product sınıfı oluşturun
// public $name özelliği için constructor promotion kullanın
// Constructor; name, price ve stock değerlerini kabul etmeli ve fiyat ile stok bilgilerini ayarlamak için trait metotlarını kullanmalıdır

class Product {
    // TODO: Trait'leri burada kullanın

    // TODO: $name için constructor promotion kullanarak constructor'ı uygulayın
    // ve trait metotlarını kullanarak fiyat ve stok bilgilerini ayarlayın
}

// Girdiyi oku
$name = trim(fgets(STDIN));
$price = floatval(trim(fgets(STDIN)));
$stock = intval(trim(fgets(STDIN)));

// TODO: Girdi değerleriyle bir Product örneği oluşturun

// TODO: Ürün adını yazdırın
// TODO: getFormattedPrice() kullanarak formatlanmış fiyatı yazdırın
// TODO: Stok miktarını yazdırın
// TODO: Stokta varsa "Available", yoksa "Out of stock" 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