Sobes.tech
Middle

Τι να κάνετε αν δύο traits έχουν μια μέθοδο με το ίδιο όνομα;

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. Ανακοίνωση μεθόδου ρητά στην κλάση: Αν η κλάση που χρησιμοποιεί traits ορίζει ρητά μια μέθοδο με το ίδιο όνομα, αυτή η μέθοδος της κλάσης θα έχει προτεραιότητα έναντι των μεθόδων των traits.

    <?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 κατά την προσπάθεια χρήσης μιας κλάσης με συγκρουόμενες μεθόδους traits.