PHP da OOP da treytlar metodlari nizolarini hal qilish
Bitta klass bir nechta treytlardan foydalanishi mumkin bo'lgani uchun, ikkita treyt bir xil nomdagi metodlarga ega bo'lganda muammo yuzaga kelishi mumkin.
Bunday holatda PHP fatal xatolik qaytaradi. Vaziyatni tuzatish uchun nomlar nizosini aniq hal qilish kerak bo'ladi. Buni qanday amalga oshirishni amalda ko'rib chiqamiz.
Faraz qilaylik, bizda bir xil method metodiga ega bo'lgan ikkita treyt mavjud:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
Faraz qilaylik, bizda shuningdek, ikkala treytimizdan foydalanadigan Test klassi mavjud. Agar shunchaki ikkala treytni klassimizga ulasak, PHP xatolik qaytaradi, chunki treytlarda bir xil metodlar mavjud:
<?php
// Ushbu kod xatolik qaytaradi!
class Test
{
use Trait1, Trait2; // treytlarni ulaymiz
}
?>
Keling, treytlarimizning nomlar nizosini hal qilaylik. Buning uchun maxsus insteadof operatori mavjud. Ushbu operator yordamida Trait2 treytining bir xil metodining o'rniga Trait1 treytining method metodidan foydalanamiz:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
Ko'rib turganingizdek, sintaksis quyidagicha: avval treyt nomi, keyin ikkita nuqta ustun, keyin metod nomi, keyin bizning insteadof operatorimiz va ikkinchi treytning nomi.
Keling tekshiramiz:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // 1 ni chiqaradi, chunki bu birinchi treytning metodi
}
}
new Test;
?>
Shunday qilib, biz klassimizda agar method metodi ishlatilsa, uni birinchi treytdan olish kerakligini aytdik. Aksincha ham qilish mumkin - ikkinchi treytning metodini olish:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // 2 ni chiqaradi, chunki bu ikkinchi treytning metodi
}
}
new Test;
?>
Har qanday holatda, agar biz bitta treytning metodidan foydalanishni ko'rsatadigan bo'lsak, ikkinchi treytning metodiga kirish imkonsiz bo'ladi. Ikkinchi treytning metodidan ham foydalanish mumkin, uni as kalit so'zi orqali qayta nomlab, mana shunday:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // 3 ni chiqaradi
}
}
new Test;
?>
Istasangiz, birinchi treytning metodini ham qayta nomlashingiz mumkin:
<?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 ni chiqaradi
}
}
new Test;
?>
insteadof orqali asosiy metodni belgilamasdan, as kalit so'zidan foydalanish mumkin emas, bu xatolik qaytaradi:
<?php
// Ushbu klass xatolik qaytaradi:
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 va Trait3 nomlariga ega 3 ta treyt yarating. Birinchi treytda 1 ni qaytaradigan method metodi, ikkinchi treytda - 2 ni qaytaradigan bir xil nomdagi metod, uchinchi treytda esa - 3 ni qaytaradigan bir xil nomdagi metod bo'lsin.
Biz yaratgan uchala treytdan foydalanadigan Test klassini yarating. Ushbu klassda ulangan treytlar metodlari natijalari yig'indisini qaytaradigan getSum metodini yarating.