advanced20 min

Interfaces and Traits

Defining a contract with an interface, and sharing behavior across classes with traits.

What you'll learn

  • Define an interface as a contract of method signatures a class must implement
  • Use a trait to share method implementations across otherwise unrelated classes
  • Predict the output of a class that both implements an interface and uses a trait

Explanation

A PHP interface declares a set of method signatures a class promises to implement: interface Nameable { public function getName(): string; }. A class opts in explicitly with implements: class Person implements Nameable { ... } -- unlike Go's implicit interfaces, PHP requires this explicit declaration, and PHP will refuse to run if a class claims to implement an interface but is missing a required method.

PHP classes support only single inheritance (extends one parent class at most), which raises a real question: how do you share a chunk of reusable behavior across classes that aren't related by inheritance? PHP's answer is the trait: trait Greetable { public function greet(): string { return "Hello, I'm " . $this->name . "!"; } }, brought into a class with use Greetable; inside the class body. This copies the trait's methods directly into the class, as if you'd written them there yourself -- a form of horizontal code reuse that doesn't participate in the class hierarchy at all.

A trait's methods can reference $this and expect properties (like $name above) to exist on whatever class ultimately uses the trait -- the trait doesn't declare that property itself; it assumes the consuming class provides it, similar to how a mixin works in other languages.

A single class can implement multiple interfaces and use multiple traits at once, which is exactly the flexibility single inheritance alone can't offer -- interfaces describe what a class can do, traits provide how, reusably.

Guided lab

Predict: A trait and an interface together

PHPNot executed
This lab does not run in your browser or on VisaSparkSchools's servers. Read the code, predict what it does, then reveal the real expected output.

Read this script and predict exactly what it sends to the browser.

<?php
trait Greetable {
    public function greet(): string {
        return "Hello, I'm " . $this->name . "!";
    }
}

interface Nameable {
    public function getName(): string;
}

class Person implements Nameable {
    use Greetable;

    public function __construct(public string $name) {}

    public function getName(): string {
        return $this->name;
    }
}

$person = new Person("Grace");
echo $person->greet() . "\n";
echo $person->getName() . "\n";

Stuck? Get a hint.

Common mistakes

  • Forgetting the explicit `implements` keyword -- unlike Go's structural interfaces, PHP requires a class to explicitly declare which interfaces it implements.
  • Assuming a trait works like a base class you `extends` -- traits are brought in with `use` inside the class body and don't affect the class hierarchy or `instanceof` checks.
  • Writing a trait method that assumes a property exists on the consuming class, without documenting that expectation, leading to confusing errors when a class uses the trait without that property.

Knowledge check

Knowledge check

1. How does a PHP class declare that it implements an interface?
2. What problem do traits solve that single inheritance alone cannot?
3. How is a trait brought into a class?

Takeaway

Use `implements` to declare a contract a class fulfills, and `use` (with a trait) to share reusable method implementations across classes that don't share a common parent.

Summary

Interfaces declare method contracts a class must explicitly `implement`; traits (`use TraitName;`) copy reusable methods into a class as horizontal code reuse, independent of inheritance.

References

Your notes

Notes save automatically.

Finished this lesson?

Mark it complete to track your progress and schedule a future review.