Sobes.tech
Middle

Ի՞նչ անել, եթե երկու trait ունեն նույն անունով մեթոդ։

sobes.tech AI

Պատասխան AI-ից

Երբ տեղի է ունենում մեթոդների անունների բախում traits-ներում, գոյություն ունեն մի քանի լուծումներ.

  1. insteadof նախածանց օպերատորը: Դա թույլ է տալիս ընտրել որոշ trait-ից մեթոդը, որը կօգտագործվի, անտեսելով մյուս trait-ից նույնանուն մեթոդը:

    <?php
    trait TraitA {
        public function doSomething() {
            echo "TraitA- ից";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "TraitB- ից";
        }
    }
    
    class MyClass {
        use TraitA, TraitB {
            TraitA::doSomething insteadof TraitB; // Օգտագործում ենք TraitA- ի մեթոդը
        }
    }
    
    $obj = new MyClass();
    $obj->doSomething(); // Տպում է "TraitA- ից"
    

    Կարող եք նշել մի քանի բացառություններ:

    <?php
    trait TraitA {
        public function methodA() { echo "A_a"; }
        public function methodB() { echo "A_b"; }
    }
    
    trait TraitB {
        public function methodA() { echo "B_a"; }
        public function methodB() { echo "B_b"; }
    }
    
    class MyClass {
        use TraitA, TraitB {
            TraitA::methodA insteadof TraitB;
            TraitB::methodB insteadof TraitA;
        }
    }
    
  2. as նախածանց օպերատոր: Դա թույլ է տալիս վերանվանել բախվող մեթոդներից մեկը:

    <?php
    trait TraitA {
        public function doSomething() {
            echo "TraitA- ից";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "TraitB- ից";
        }
    }
    
    class MyClass {
        use TraitA, TraitB {
            TraitB::doSomething as doSomethingFromB; // Վերանվանում ենք TraitB- ի մեթոդը
        }
    
        public function callBoth() {
            $this->doSomething(); // Կոչ է անում TraitA- ի մեթոդը
            $this->doSomethingFromB(); // Կոչ է անում վերանվանված մեթոդը TraitB- ից
        }
    }
    
    $obj = new MyClass();
    $obj->callBoth(); // Տպում է "TraitA- իցTraitB- ից"
    

    as օպերատորը կարող է օգտագործվել insteadof-ի հետ համատեղ և թույլ է տալիս փոփոխել մեթոդի տեսանելիությունը:

    <?php
    trait TraitA {
        private function internalMethod() {
            echo "Անհատական TraitA- ից";
        }
    }
    
    class MyClass {
        use TraitA {
            internalMethod as public externalMethod; // Վերանվանում և դարձնում հանրային
        }
    }
    
    $obj = new MyClass();
    $obj->externalMethod(); // Տպում է "Անհատական TraitA- ից"
    
  3. Մեթոդի հստակ սահմանում դասում: Եթե trait-ները օգտագործող դասը հստակ սահմանում է նույն անունով մեթոդ, ապա այդ մեթոդը դասի կողմից կլինի առաջնահերթ՝ trait-ների մեթոդների նկատմամբ:

    <?php
    trait TraitA {
        public function doSomething() {
            echo "TraitA- ից";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "TraitB- ից";
        }
    }
    
    class MyClass {
        use TraitA, TraitB;
    
        public function doSomething() { // Դասը սահմանում է սեփական մեթոդը
            echo "MyClass- ից";
        }
    }
    
    $obj = new MyClass();
    $obj->doSomething(); // Տպում է "MyClass- ից"
    

Եթե առանց հստակ լուծման insteadof կամ as-ի կամ մեթոդի վերագրածության, PHP-ն կհայտարարի սխալ E_STRICT՝ փորձելով օգտագործել բախվող trait մեթոդներով դասը։