ტრეიტების მეთოდების კონფლიქტების გადაჭრა OOP-ში PHP-ში
რადგან ერთ კლასს შეუძლია რამდენიმე ტრეიტის გამოყენება, შეიძლება წარმოიშვას პრობლემა, როდესაც ორ ტრეიტს აქვს ერთიდაიგივე სახელის მეთოდები.
ამ შემთხვე�ვაში PHP ფატალურ შეცდომას აბრუნებს. სიტუაციის გამოსასწორებლად, საჭიროა სახელების კონფლიქტის მკაფიოდ გადაწყვეტა. როგორ ხდება ეს - პრაქტიკაში ვნახოთ.
დავუშვათ, გვაქვს ორი ტრეიტი ერთიდაიგივე
მეთოდით method:
<?php
trait Trait1
{
private function method()
{
return 1;
}
}
trait Trait2
{
private function method()
{
return 2;
}
}
?>
დავუშვათ, ასევე გვაქვს კლასი Test,
რომელიც იყენებს ჩვენი ორივე ტრეიტს. თუ უბრალოდ
დავაკავშირებთ ორივე ტრეიტს ჩვენს კლასს, მაშინ
PHP დააბრუნებს შეცდომას, რადგან ტრეიტებს აქვთ
დამთხვევის მეთოდები:
<?php
// ეს კოდი დააბრუნებს შეცდომას!
class Test
{
use Trait1, Trait2; // ვაკავშირებთ ტრეიტებს
}
?>
მოდით, გადავჭრათ ჩვენი ტრეიტების სახელების
კონფლიქტი. ამისთვის არსებობს სპეციალური
ოპერატორი insteadof. ამ ოპერატორის საშუალებით
გამოვიყენებთ ტრეიტის Trait1 მეთოდს method
ამავე სახელის ტრეიტის Trait2 მეთოდის ნაცვლად:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
}
new Test;
?>
როგორც ხედავთ, სინტაქსი ასეთია: თავიდან
ტრეიტის სახელი, შემდეგ ორი მსხვილი ნაწლავი, შემდეგ მეთოდის სახელი, შემდეგ ჩვენი ოპერატორი insteadof
და მეორე ტრეიტის სახელი.
მოდით, შევამოწმოთ:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
}
public function __construct()
{
echo $this->method(); // დააბრუნებს 1-ს, რადგან ეს არის პირველი ტრეიტის მეთოდი
}
}
new Test;
?>
ამრიგად, ჩვენს კლასში ვთქვით, რომ თუ
გამოიყენება მეთოდი method, მაშინ
უნდა იქნას აღებული ის პირველი ტრეიტიდან. ასევე შესაძლებელია პირიქით
- ავიღოთ მეორე ტრეიტის მეთოდი:
<?php
class Test
{
use Trait1, Trait2 {
Trait2::method insteadof Trait1;
}
public function __construct()
{
echo $this->method(); // დააბრუნებს 2-ს, რადგან ეს არის მეორე ტრეიტის მეთოდი
}
}
new Test;
?>
ყოველ შემთხვევაში, თუ ჩვენ მივუთითებთ, რომ გამოვიყენოთ
მეთოდი ერთი ტრეიტიდან, მაშინ მეორე ტრეიტის მეთოდი
ხდება მიუწვდომელი. ასევე შესაძლებელია მეორე ტრეიტის მეთოდის გამოყენება,
მისი სახელის შეცვლით
as საკვანძო სიტყვის საშუალებით, ასე:
<?php
class Test
{
use Trait1, Trait2 {
Trait1::method insteadof Trait2;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method() + $this->method2(); // დააბრუნებს 3-ს
}
}
new Test;
?>
სურვილის შემთხვევაში, შესაძლებელია პირველი ტრეიტის მეთოდის სახელის შეცვლაც:
<?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-ს
}
}
new Test;
?>
as საკვანძო სიტყვის გამოყენება
მთავარი მეთოდის insteadof-ის საშუალებით განსაზღვრის გარეშე
არ შეიძლება, ეს დააბრუნებს შეცდომას:
<?php
// ეს კლასი დააბრუნებს შეცდომას:
class Test
{
use Trait1, Trait2 {
Trait1::method as method1;
Trait2::method as method2;
}
public function __construct()
{
echo $this->method1() + $this->method2();
}
}
new Test;
?>
შექმენით 3 ტრეიტი სახელებით Trait1,
Trait2 და Trait3. პირველ
ტრეიტში იყოს მეთოდი method, რომელიც აბრუნებს
1-ს, მეორე ტრეიტში - ამავე სახელის
მეთოდი, რომელიც აბრუნებს 2-ს, ხოლო მესამე
ტრეიტში - ამავე სახელის მეთოდი,
რომელიც აბრუნებს 3-ს.
შექმენით კლასი Test, რომელიც იყენებს
ჩვენს მიერ შექმნილ სამივე ტრეიტს. ამ კლასში
შექმენით მეთოდი getSum, რომელიც აბრუნებს
შეკავშირებული ტრეიტების მეთოდების შედეგების ჯამს.