Sobes.tech
Middle

Čo robiť, ak majú dva traits metódu s rovnakým názvom?

sobes.tech AI

Odpoveď od AI

Keď dôjde ku kolízii názvov metód v traits, existuje niekoľko možností riešenia:

  1. Operátor predpony insteadof: Umožňuje vybrať metódu z určitého traitu, ktorá bude použitá, ignorujúc rovnakú metódu z iného traitu.

    <?php
    trait TraitA {
        public function doSomething() {
            echo "Z TraitA";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "Z TraitB";
        }
    }
    
    class MyClass {
        use TraitA, TraitB {
            TraitA::doSomething insteadof TraitB; // Používame metódu z TraitA
        }
    }
    
    $obj = new MyClass();
    $obj->doSomething(); // Vypíše "Z TraitA"
    

    Môžete špecifikovať viac výnimiek:

    <?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. Operátor predpony as: Umožňuje premenovanie jednej z konfliktujúcich metód.

    <?php
    trait TraitA {
        public function doSomething() {
            echo "Z TraitA";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "Z TraitB";
        }
    }
    
    class MyClass {
        use TraitA, TraitB {
            TraitB::doSomething as doSomethingFromB; // Premenujeme metódu z TraitB
        }
    
        public function callBoth() {
            $this->doSomething();        // Zavolá metódu z TraitA
            $this->doSomethingFromB(); // Zavolá premenovanú metódu z TraitB
        }
    }
    
    $obj = new MyClass();
    $obj->callBoth(); // Vypíše "Z TraitAZ TraitB"
    

    Operátor as možno použiť v kombinácii s insteadof a umožňuje zmeniť viditeľnosť metódy.

    <?php
    trait TraitA {
        private function internalMethod() {
            echo "Súkromná z TraitA";
        }
    }
    
    class MyClass {
        use TraitA {
            internalMethod as public externalMethod; // Premenujeme a sprístupníme
        }
    }
    
    $obj = new MyClass();
    $obj->externalMethod(); // Vypíše "Súkromná z TraitA"
    
  3. Explicitné definovanie metódy v triede: Ak trieda, ktorá používa traits, explicitne definuje metódu s rovnakým názvom, má táto metóda triedy prednosť pred metódami traits.

    <?php
    trait TraitA {
        public function doSomething() {
            echo "Z TraitA";
        }
    }
    
    trait TraitB {
        public function doSomething() {
            echo "Z TraitB";
        }
    }
    
    class MyClass {
        use TraitA, TraitB;
    
        public function doSomething() { // Trieda definuje vlastnú metódu
            echo "Z MyClass";
        }
    }
    
    $obj = new MyClass();
    $obj->doSomething(); // Vypíše "Z MyClass"
    

Bez explicitného riešenia konfliktu pomocou insteadof alebo as, alebo prepísania metódy v triede, PHP spôsobí chybu E_STRICT pri pokuse o použitie triedy s konfliktujúcimi metódami traits.