PHP OOP'de Trait Metot Çakışmalarının Çözümü
Bir sınıf birden fazla trait kullanabileceğinden, iki trait'in aynı isimde metotlara sahip olması durumunda ortaya çıkabilecek bir problemle karşılaşabiliriz.
Bu durumda PHP ölümcül bir hata verecektir. Durumu düzeltmek için, isim çakışmasını açıkça çözmemiz gerekecek. Bunun nasıl yapıldığını pratikte görelim.
İki trait'imiz olduğunu ve her ikisinin de
method adında bir metodu olduğunu varsayalım:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
Ayrıca, her iki trait'imizi de kullanan bir
Test sınıfımız olduğunu varsayalım. Eğer
sadece her iki trait'i sınıfımıza bağlarsak,
PHP trait'lerin çakışan metotları olduğu için
bir hata verecektir:
<?php
// Bu kod hata verecektir!
class Test
{
use Trait1, Trait2; // trait'leri bağlıyoruz
}
?>
Şimdi trait'lerimizin isim çakışmasını çözelim.
Bunun için özel bir operatör olan insteadof
kullanılır. Bu operatörü kullanarak, Trait2
trait'inin aynı isimli metodu yerine Trait1
trait'inin method metodunu kullanacağız:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
Gördüğünüz gibi, sözdizimi şu şekildedir: önce
trait'in adı, sonra iki nokta üst üste, sonra
metodun adı, sonra insteadof operatörümüz
ve ikinci trait'in adı.
Hadi test edelim:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // 1 yazdıracak, çünkü bu birinci trait'in metodudur
}
}
new Test;
?>
Sonuç olarak, sınıfımızda method metodu
kullanılırsa, bunun ilk trait'ten alınması
gerektiğini belirttik. Tam tersi de yapılabilir
- ikinci trait'in metodunu almak:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // 2 yazdıracak, çünkü bu ikinci trait'in metodudur
}
}
new Test;
?>
Her durumda, bir trait'in metodunu kullanacağımızı
belirtirsek, ikinci trait'in metodu erişilemez
hale gelir. İkinci trait'in metodunu da
as anahtar kelimesiyle yeniden adlandırarak
kullanabiliriz, işte şu şekilde:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // 3 yazdıracak
}
}
new Test;
?>
İstenirse, ilk trait'in metodu da yeniden adlandırılabilir:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2(); // 3 yazdıracak
}
}
new Test;
?>
insteadof ile ana metodu tanımlamadan
sadece as anahtar kelimesini kullanmak
mümkün değildir, bu bir hata verecektir:
<?php
// Bu sınıf hata verecektir:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
Trait1, Trait2 ve Trait3
adlarında 3 trait yapın. İlk trait'te
1 döndüren method metodu,
ikinci trait'te aynı isimde 2 döndüren
bir metot ve üçüncü trait'te aynı isimde
3 döndüren bir metot olsun.
Oluşturduğumuz üç trait'i de kullanan bir
Test sınıfı yapın. Bu sınıfta, bağlanan
trait'lerin metotlarının sonuçlarının toplamını
döndüren getSum adında bir metot yapın.