Summary - Traits
Build logging-capable classes with trait, use and multiple traits.
Summary: Traits
In this group you learned traits. In short:
- You declare a reusable method set with
trait Name { ... }. - Inside a class,
use Name;includes the trait and injects its methods. use A, B;combines multiple traits.- On same-name method conflicts,
insteadofpicks one andasaliases another. - A trait is horizontal reuse; inheritance is a vertical 'is-a' relationship.
Exercise A logging-capable UserService class
Define a Logger trait: its public function log(string $msg): string method does return "[LOG] " . $msg;. Define a Tagger trait: its public function tag(string $t): string method does return "#" . $t;. Then a UserService class uses both with use Logger, Tagger;. Create an instance with $s = new UserService() and call echo $s->log("signin") . "\n" and echo $s->tag("admin") . "\n".
Show example solution
Write trait Logger { ... } and trait Tagger { ... }. Add class UserService { use Logger, Tagger; }. With $s = new UserService(); call log() and tag().
Example solution:
<?php
// Combine Logger and Tagger traits in the UserService class
trait Logger {
public function log(string $msg): string {
return "[LOG] " . $msg;
}
}
trait Tagger {
public function tag(string $t): string {
return "#" . $t;
}
}
class UserService {
use Logger, Tagger;
}
$s = new UserService();
echo $s->log("signin") . "\n";
echo $s->tag("admin") . "\n";
Tips for using traits
A few tips when using traits:
- A trait cannot be instantiated with
new; it is only included viause. - Keep traits small and single-responsibility; don't cram dozens of methods into one.
- A trait property is injected into the class; watch for collisions.
- Prefer inheritance for a real 'is-a' relationship; traits are for sharing behavior.
The design question 'is this a ...' versus 'can this ...' guides your choice.
Test yourself
-
What is the correct syntax to add both Logger and Notifier to a class?
- use Logger extends Notifier;
- extends Logger, Notifier;
- implements Logger, Notifier;
- use Logger, Notifier;
Show answer
use Logger, Notifier; — Correct. use Logger, Notifier; joins two traits with a comma and includes them in the class.
-
Match the keyword to its job
- trait
- reusable method set
- use
- include trait in class
- insteadof
- pick conflicting method
- as
- rename a method
-
Alias a method with as
trait Printer { public function output(): string { return "output"; } } class Report { use Printer { output ____ asText; } } $r = new Report(); echo $r->asText() . "\n";Show answer
trait Printer { public function output(): string { return "output"; } } class Report { use Printer { output as asText; } } $r = new Report(); echo $r->asText() . "\n";