traits

Cecha to funkcjonalność, która została stworzona, z myślą o tych wszystkich programistach, którym bardzo brakuje możliwości oferowanych przez mechanizm wielokrotnego dziedziczenia. Może się bowiem zdarzyć sytuacja, w której implementowana klasa powinna dziedziczyć, nie po jednej, a po większej ilości klas. Dotychczas rozwiązanie to było niedostępne w PHP, jak i w większości nowoczesnych języków programowania. Cel takiego zagrania wydaje się być oczywisty. Zyskujemy zmniejszenie komplikacji tworzonych projektów, dzięki czemu zdecydowanie łatwiej prześledzić powiązania między klasami i zrozumieć całą strukturę aplikacji. Traits są więc panaceum na problemy związane z brakiem wielokrotnego dziedziczenia i będą one dostępne wraz z wydaniem PHP w wersji 5.4.

definicja

Trait to struktura, która formą deklaracji w dużym stopniu przypomina definicję klasy. Spójrzmy na poniższy przykład:

trait Write {

    public function write () {

        if (isset($this->myName))
            echo $this->myName;

    }

}

Słowo kluczowe trait służy do tworzenia cechy. Wewnątrz niej można umieszczać metody i atrybuty. Jak widać na powyższym skrypcie, istnieje tylko jedna funkcja z modyfikatorem dostępu – publicznym, która wysyła na wyjście wartość zmiennej $this->myName, o ile taką zdefiniowano w klasie, która z cechy korzysta. Sposób użycia ilustruje poniższy fragment kodu:

class Duck {
    use Write;

    private $myName;

    public function __construct ($name) {

        $this->myName = $name;

    }

}

$obj = new Duck ('Donald');
echo $obj->write();

Aby klasa mogła w pełni rozkoszować się zaletami cechy Write korzystamy ze słówka kluczowego use.

przykład praktyczny

Aby lepiej zrozumieć i wyjaśnić sobie niuanse nowej funkcjonalności napiszmy parę cech, które będą implementować metody o takich samych nazwach:

trait Duck {

    public function write ($message) {

        echo 'Duck ',$message;

    }

}

trait Monkey {

    public function write ($message) {

        echo 'Monkey ',$message;

    }
}

trait Frog {

    public function write ($message) {

        echo 'Frog ',$message;

    }
}

class Animal {
    use Frog,Monkey,Duck;

}

$obj = new Animal();

Wykonanie powyższego skryptu skazane jest na porażkę, ponieważ niedozwolone jest korzystanie z wielu cech posiadających takie same nazwy metod. W taki wypadku programista jest zmuszony do wybrania konkretnej funkcji (słowo insteadof), a dla pozostałych skorzystanie z mechanizmu aliasów (słowo as):

//insteadof PRZYKLAD

class Animal {
    use Frog,Monkey,Duck {Monkey::write insteadof Frog,Duck;}

}

$obj = new Animal();
$obj->write('test');
// mozemy uzyc tylko jednej z trzech metod

// as PRZYKLAD

class Animal {
    use Frog,Monkey,Duck {
        Monkey::write insteadof Duck,Frog;
        Duck::write as writeDuck;
        Frog::write as writeFrog;
    }

}

$obj = new Animal();
$obj->writeFrog('test');
$obj->writeDuck('test');
$obj->write('test');
// mozemy skorzystac ze wszystkich trzech metod

Oczywiście nic nie stoi na przeszkodzie, by sama klasa Animal posiadała metodę write. W takiej sytuacji w pierwszej kolejności zostanie wywołana właśnie ona. Warto jeszcze wspomnieć o sposobności zmiany modyfikatora dostępu dla cechy. Prezentuje to poniższy przykład:

trait Duck {

    private function write ($message) {

        echo 'Duck ',$message;

    }

}

trait Monkey {

    private function write ($message) {

        echo 'Monkey ',$message;

    }
}

trait Frog {

    private function write ($message) {

        echo 'Frog ',$message;

    }
}

class Animal {
    use Frog,Monkey,Duck {
        Monkey::write insteadof Duck,Frog;
        Duck::write as public writeDuck;
        Frog::write as public writeFrog;
        Monkey::write as public;
    }

}

$obj = new Animal();
$obj->write('test');
$obj->writeFrog('test');
$obj->writeDuck('test');

Wypada także zapamiętać, iż nie uda się nam utworzyć obiektu cechy lub skorzystać w jej przypadku z type hinting. Zainteresowanych zachęcam do własnych eksperymentów.

1 Odpowiedź : “traits”

  1. PHP 5.4 wyszło, więc trzeba zacząć zabawę z nowinkami.

Pozostaw Odpowiedź