Sobes.tech
Middle

Mida teha, kui kahe traits meetod on sama nimi?

sobes.tech AI

Vastus AI-lt

Kui traitide meetodite nimede kokkupõrge toimub, on mitu lahendusviisi:

  1. Eesliite operaator insteadof: võimaldab valida konkreetse traiti meetodi, mida kasutatakse, ignoreerides teise traiti sama nimega meetodi.

    <?php
    trait TraitA {
        public function doSomething() {
            echo "TraitA-st";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "TraitB-st";
        }
    }
    
    class MyClass {
        use TraitA, TraitB {
            TraitA::doSomething insteadof TraitB; // Kasutame TraitA meetodit
        }
    }
    
    $obj = new MyClass();
    $obj->doSomething(); // Kuvab "TraitA-st"
    

    Võib määrata mitu erandit:

    <?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. Eesliite operaator as: võimaldab ümber nimetada kokkupõrkeid tekitavat meetodit.

    <?php
    trait TraitA {
        public function doSomething() {
            echo "TraitA-st";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "TraitB-st";
        }
    }
    
    class MyClass {
        use TraitA, TraitB {
            TraitB::doSomething as doSomethingFromB; // Nimetame ümber TraitB meetodi
        }
    
        public function callBoth() {
            $this->doSomething();        // Kutsub TraitA meetodi
            $this->doSomethingFromB(); // Kutsub ümber nimetatud meetodi
        }
    }
    
    $obj = new MyClass();
    $obj->callBoth(); // Kuvab "TraitA-stTraitB-st"
    

    as operaatorit saab kasutada koos insteadof-ga ning see võimaldab muuta meetodi nähtavust.

    <?php
    trait TraitA {
        private function internalMethod() {
            echo "TraitA salajane";
        }
    }
    
    class MyClass {
        use TraitA {
            internalMethod as public externalMethod; // Nimetame ümber ja muudame avalikuks
        }
    }
    
    $obj = new MyClass();
    $obj->externalMethod(); // Kuvab "TraitA salajane"
    
  3. Meetodi selge määratlemine klassis: Kui klass, mis kasutab trait, määratleb selgelt sama nimega meetodi, siis see meetod on prioriteet trait meetodite ees.

    <?php
    trait TraitA {
        public function doSomething() {
            echo "TraitA-st";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "TraitB-st";
        }
    }
    
    class MyClass {
        use TraitA, TraitB;
    
        public function doSomething() { // Klass määratleb oma meetodi
            echo "MyClass-st";
        }
    }
    
    $obj = new MyClass();
    $obj->doSomething(); // Kuvab "MyClass-st"
    

Ilma selge lahenduseta insteadof, as või meetodi ülekirjutamisega klassis, annab PHP viga E_STRICT, kui üritatakse kasutada klassi koos konfliktsete trait meetoditega.