CHAPTER 4 ■ ADVANCED FEATURES
//...
}
knows nothing at all of the ShopProduct or CdProduct types. This method is only concerned with whether
the $item argument contains a getPrice() method.
Because any class can implement an interface (in fact, a class can implement any number of
interfaces), interfaces effectively join types that are otherwise unrelated. I might define an entirely new
class that implements Chargeable:
class Shipping implements Chargeable {
public function getPrice() {
//...
}
}
I can pass a Shipping object to the addChargeableItem() method just as I can pass it a ShopProduct
object.
The important thing to a client working with a Chargeable object is that it can call a getPrice()
method. Any other available methods are associated with other types, whether through the object’s own
class, a superclass, or another interface. These are irrelevant to the client.
A class can both extend a superclass and implement any number of interfaces. The extends clause
should precede the implements clause:
class Consultancy extends TimedService implements Bookable, Chargeable {
// ...
}
Notice that the Consultancy class implements more than one interface. Multiple interfaces follow
the implements keyword in a comma-separated list.
PHP only supports inheritance from a single parent, so the extends keyword can precede a single
class name only.
Late Static Bindings: The static Keyword
Now that you’ve seen abstract classes and interfaces, it’s time to return briefly to static methods.
You saw that a static method can be used as factory, a way of generating instances of the containing
class. If you’re as lazy a coder as me, you might chafe at the duplication in an example like this:
abstract class DomainObject {
}
class User extends DomainObject {
public static function create() {
return new User();
}
}
class Document extends DomainObject {
public static function create() {
return new Document();
}
}