Menu
Coddy logo textTech

Type Hinting with Interfaces

Part of the Object Oriented Programming section of Coddy's PHP journey — lesson 31 of 91.

One of the most powerful uses of interfaces is type hinting. When you use an interface as a type hint in a function or method parameter, you're saying "this function accepts any object that implements this interface." This makes your code flexible and reusable.

<?php
interface Playable {
    public function play();
}

class Song implements Playable {
    public function play() {
        return "Playing song";
    }
}

class Video implements Playable {
    public function play() {
        return "Playing video";
    }
}

function startMedia(Playable $media) {
    return $media->play();
}

$song = new Song();
$video = new Video();

echo startMedia($song) . "\n";
echo startMedia($video);

Output:

Playing song
Playing video

The startMedia() function doesn't care whether it receives a Song or Video. It only cares that the object implements Playable and therefore has a play() method. This is the essence of programming to an interface rather than a concrete implementation.

You can also use interface type hints for return types:

<?php
function createMedia(string $type): Playable {
    if ($type === "song") {
        return new Song();
    }
    return new Video();
}

This guarantees the function always returns something that implements Playable, regardless of the specific class.

Key Point: Type hinting with interfaces lets you write functions that work with any class implementing that interface, making your code more flexible and easier to extend.

challenge icon

Challenge

Easy

Let's build a document processing system that demonstrates the power of type hinting with interfaces. You'll create a function that can process any document type — as long as it implements the right interface, your function will work with it seamlessly.

You'll organize your code across four files:

  • Exportable.php — Define an Exportable interface with a single method signature: export(). Any class implementing this interface promises it can export its content in some format.
  • Report.php — Create a Report class that implements Exportable. Include the interface file. The class should have a private $title property and a private $data property. The constructor accepts both values. Implement export() to return "Report: [title] - [data]".
  • Invoice.php — Create an Invoice class that also implements Exportable. Include the interface file. The class should have a private $invoiceNumber property and a private $amount property. The constructor accepts both values. Implement export() to return "Invoice #[invoiceNumber]: $[amount]".
  • main.php — Include both the Report and Invoice files. Create a function called processDocument that accepts an Exportable parameter and returns the result of calling export() on it. This function uses interface type hinting — it works with any object that implements Exportable.

You'll receive four inputs: a report title, report data, an invoice number, and an invoice amount. Create a Report and an Invoice with these values. Pass each one to your processDocument() function and print the results — the report first, then the invoice, each on its own line.

The beauty of this approach is that processDocument() doesn't know or care whether it's handling a Report or an Invoice. It only knows the object can be exported — that's the contract the interface guarantees.

Try it yourself

<?php
// Include the class files
require_once 'Report.php';
require_once 'Invoice.php';

// Read inputs
$reportTitle = trim(fgets(STDIN));
$reportData = trim(fgets(STDIN));
$invoiceNumber = trim(fgets(STDIN));
$invoiceAmount = trim(fgets(STDIN));

// TODO: Create a function called processDocument
// - It should accept an Exportable parameter (use type hinting)
// - It should return the result of calling export() on the parameter

// TODO: Create a Report object with the report title and data

// TODO: Create an Invoice object with the invoice number and amount

// TODO: Pass each object to processDocument() and print the results
// Print the report result first, then the invoice result (each on its own line)
?>
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming