Menu

PHP Trait: use, Birden Çok Trait ve insteadof

PHP trait'i, use TraitName; ile bir sınıfa kopyaladığınız yeniden kullanılabilir bir metot ve özellik bloğudur. Birkaç trait kullanmayı, ad çakışmalarını insteadof ve as ile çözmeyi, soyut ve statik trait üyelerini, hangi metodun kazandığını ve trait, arayüz ve soyut sınıf farkını öğrenin.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

PHP trait'i yeniden kullanılabilir bir metot ve özellik bloğudur. Onu trait Name { ... } ile tanımlar ve sınıf gövdesinin içinde use Name; ile herhangi bir sınıfa alırsınız. PHP trait'in üyelerini sınıfa kopyalar, böylece onları oraya siz yazmışsınız gibi çalışırlar.

User ve Robot sınıflarının ortak bir üst sınıfı yoktur, yine de ikisinde de artık hello() vardır. Trait'ler bu durum için vardır: PHP sınıfları yalnızca bir sınıfı genişletebilir ve bir trait kodu ilişkisiz sınıflar arasında yatay olarak paylaşır.

Özellikli trait'ler

Bir trait metotlarıyla birlikte özellikler de getirebilir. Metotlar sınıfın herhangi bir metodu gibi $this kullanır, çünkü trait kopyalandıktan sonra onlar sınıfın metotlarıdır:

Bir sınıf, iki tanım tamamen aynı (aynı görünürlük, tür ve varsayılan değer) olmadıkça bir trait özelliğiyle aynı adda bir özellik tanımlayamaz; aksi halde bu ölümcül bir hatadır.

Birden çok trait kullanma

Tek bir use deyiminde birkaç trait'i virgülle ayırarak listeleyin ya da birkaç use satırı yazın. Sınıf hepsinin üyelerini alır:

Çakışmaları insteadof ve as ile çözme

İki trait aynı adla bir metot tanımladığında PHP tahmin yürütmeyi reddeder ve ölümcül bir hatayla durur. Bir use bloğunun içinde insteadof kazananı seçer, as ise kaybeden metodu başka bir adla tutar:

Blok olmadan düz bir use EnglishGreeting, FrenchGreeting; ile betik daha hiçbir şey yazdırılmadan durur:

PHP Fatal error:  Trait method FrenchGreeting::greet has not been applied as Host::greet, because of collision with EnglishGreeting::greet in /home/index.php on line 12

as görünürlüğü de değiştirebilir. use Loggable { log as protected; } trait'in log() metodunu yalnızca bu sınıfta protected yapar ve use Loggable { log as private writeLog; } private bir takma ad ekler.

Bir trait içindeki soyut ve statik üyeler

Bir trait, soyut bir metot tanımlayarak onu kullanan sınıftan bir şey isteyebilir. Statik metotları ve statik özellikleri de olabilir. Trait'i kullanan her sınıf statik bir özelliğin kendi kopyasını alır:

Car ve Bike ayrı ayrı sayar, çünkü statik özellik her sınıfa kopyalanır. Bu, tüm alt sınıfların paylaştığı ortak bir üst sınıfta tanımlanan statik bir özellikten farklıdır; static sayfası o durumu gösterir.

Hangi metot kazanır: sınıf, trait veya üst sınıf

Aynı metot adı sınıfın kendisinde, kullandığı bir trait'te ve üst sınıfında varsa PHP şu sırayla seçer: sınıfın kendi metodu, sonra trait'inki, sonra üst sınıfınki. Trait'in içinde parent:: hâlâ üst sınıfın sürümüne ulaşır:

Bir trait bir tür değildir

instanceof asla bir trait ile eşleşmez ve bir trait adıyla türlendirilmiş bir parametre her nesneyi bir TypeError ile reddeder. "Bu sınıf bu davranışa sahip mi" diye sormak için trait'i bir arayüzle eşleştirin ya da sınıfı class_uses() ile inceleyin:

Yukarıdaki kalıp olağan olanıdır: Exportable arayüzü fonksiyonların tür ipucu olarak kullandığı ve instanceof ile kontrol edilen şeydir, ExportsProperties trait'i ise sınıfların kullanabileceği veya değiştirebileceği hazır bir uygulamadır. Tek başına bir trait sözleşmesi olmayan paylaşılan koddur; iş mantığında class_uses() kontrol ettiğinizi fark ettiğinizde trait yanında bir arayüz istiyordur. İlişkili sınıflardan oluşan bir ailenin paylaştığı kod için bir soyut sınıf daha basit bir seçim olabilir.

Sıkça Sorulan Sorular

PHP'de trait nedir?

Trait, trait Name { } ile tanımlanan ve bir sınıfın use Name; ile içeri aldığı adlandırılmış bir metot (ve özellik) grubudur. PHP trait'in üyelerini sınıfa kopyalar, böylece onları oraya siz yazmışsınız gibi davranırlar. Ortak bir üst sınıfı olmayan sınıflar arasında kod paylaşmanın bir yoludur.

Bir PHP sınıfı birden çok trait kullanabilir mi?

Evet: use Timestamps, SoftDeletes; ya da birkaç use satırı. İki trait aynı adla bir metot tanımlıyorsa birini insteadof ile seçmeniz gerekir, örneğin use A, B { A::hello insteadof B; }, ve diğerini B::hello as helloB; ile yeni bir adla tutabilirsiniz.

PHP'de trait ile interface arasındaki fark nedir?

Bir arayüz kodu olmayan bir türdür: bir sınıfın hangi metotlara sahip olması gerektiğini söyler ve instanceof onunla çalışır. Bir trait türü olmayan koddur: metot gövdelerini bir sınıfa yapıştırır, ama $obj instanceof SomeTrait her zaman false olur. Çoğu zaman birlikte kullanılırlar: tür için bir arayüz, varsayılan uygulama için bir trait.

Bir trait'in yapıcısı veya soyut metotları olabilir mi?

İkisine de evet. Bir trait, onu kullanan sınıfın o metodu sağlamasını şart koşmak için abstract public function name(): string; tanımlayabilir ve __construct tanımlayabilir; ancak bir trait içindeki yapıcı sınıfın kendi yapıcısıyla kolayca çakışır ve nadiren iyi bir fikirdir.

Bir sınıf ve bir trait aynı metodu tanımlarsa hangisi kazanır?

Sınıfın kendi metodu trait'inkini, trait'in metodu da üst sınıftan kalıtılan metodu yener. Yani sıra şudur: sınıf, sonra trait, sonra üst sınıf.

Coddy programlama dilleri çizimi

Coddy ile kodlamayı öğren

BAŞLA