Specifying Interfaces






Specifying Interfaces

Problem

You want to ensure a class implements one or more methods with specific names, visibilities, and prototypes.

Solution

Define an interface and declare that your class will implement that interface:

interface Nameable {
    public function getName();
    public function setName($name);
}

class Book implements Nameable {
    private $name;

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

    public function setName($name) {
        return $this->name = $name;
    }
}

The Nameable interface defines two methods necessary to name an object. Since books are nameable, the Book class says it implements the Nameable interface, and then defines the two methods in the class body.

Discussion

In object-oriented programming, objects must work together. Therefore, you should be able to require a class (or more than one class) to implement methods that are necessary for the class to interact properly in your system.

For instance, an e-commerce application needs to know a certain set of information about every item up for sale. These items may be represented as different classes: Book, CD, DVD, etc. However, at the very minimum you need to know that every item in your catalog has a name, regardless of its type. (You probably also want them to have a price and maybe even an ID, while you're at it.)

The mechanism for forcing classes to support the same set of methods is called an interface. Defining an interface is similar to defining a class (see Figure).

Defining an interface

interface Nameable {
    public function getName();
    public function setName($name);
}

Instead of using the keyword class, an interface uses the keyword interface . Inside the interface, define your method prototypes, but don't provide an implementation.

This creates an interface named Nameable. Any class that's Nameable must implement the two methods listed in the interface: getName( ) and setName( ).

When a class supports all the methods in the interface, it's said to implement the interface. You agree to implement an interface in your class definition (see Figure).

Implementing an interface

class Book implements Nameable {
    private $name;

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

    public function setName($name) {
        return $this->name = $name;
    }
}

Failing to implement all the methods listed in an interface, or implementing them with a different prototype, causes PHP to emit a fatal error.

A class can agree to implement as many interfaces as you want. For instance, you may want to have a Listenable interface that specifies how you can retrieve an audio clip for an item. In this case, the CD and DVD classes would also implement Listenable, whereas the Book class wouldn't. (Unless, of course, it is an audio book.)

When you use interfaces, it's important to declare your classes before you instantiate objects. Otherwise, when a class implements interfaces, PHP 5 can sometimes become confused. To avoid breaking existing applications, this requirement is not enforced, but it's best not to rely on this behavior.

To check if a class implements a specific interface, use class_implements( ), as shown in Figure.

Checking if a class implements an interface

class Book implements Nameable {
    // .. Code here
}

$interfaces = class_implements('Book');
if (isset($interfaces['Nameable'])) {
    // Book implements Nameable
}

You can also use the Reflection classes, shown in Figure.

Checking if a class implements an interface using the Reflection classes

class Book implements Nameable {
// .. Code here
}
$rc = new ReflectionClass('Book');
if ($rc->implementsInterface('Nameable')) {
  print "Book implements Nameable\n";
}

See Also

Recipe 7.19 for more on the Reflection classes; documentation on class_implements( ) at http://www.php.net/class_implements and interfaces at http://www.php.net/interfaces.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows