in PHP 5

What Interfaces Are For

A little while ago, I wrote an article discussing why interfaces rock and the way that interfaces work. However, a couple of comments made me realize that I didn’t discuss one of the key elements about interfaces: why you would use them.

One key rule about interfaces is that all methods must be defined as public. You cannot define protected or private methods, and you cannot define any members of any type. You may define constants, as these cannot be overridden by any class implementing the interface.

So why is an interface useful?

An interface is useful because it allows you to know what methods will be there. No matter what, when you get an object that implements a particular interface, it has to have implemented all the methods of that interface. What’s more, you also know that the interface is public, so each of those methods is public. Essentially, this means that an interface is for defining your public API.

Take the following example:

interface ActionI
    public function initialize();

    public function execute();

    public function getResult();

    public function setRequest();

Each and every one of those public methods will be available to every single object in our application. We know that any object implementing ActionI will have those methods defined, and they form the public API of our object. Regardless of what private or protected methods that we implement (the guts that make our object function properly), this is our public API.

An added benefit of doing this is that an interface definition allows you to document more effectively. Theoretically we can document just the four public API methods, and skip the protected or private methods (except for internal documentation), because anyone who is accessing our objects only needs to know about the four public ones. Only the developers who are modifying the internal workings of the objects care about the helper methods.

Interfaces make programming much easier, by allowing us to plan, and by giving us consistency in our public API, without requiring us to define much about the methods to do so.

It’s worth noting that this article contradicts something in my previous article, “Why Interfaces Rock”. That is that I defined a constructor method. When defining your public API, you do not want to define any methods that might be unnecessary in descendant objects. In practice, when you define your interface, make sure to only include the methods that will be necessary for all objects to implement; nothing more, nothing less.

  1. In addition to that the usage of interfaces make the code easier to test. Instead of relying on a certain base class your code relies on an interfaces which do not rely on other classes (at least if you got your API design right).

  2. Just a technical note, you have a single quote instead of a double quote in your HTML markup near …You may define interface is for defining your public API… which corrupts the rendering.

  3. It’s probably worth noting for those that aren’t aware of it, that an object created with a class that extends an interface will be an “instance of” that interface.

    This is extremely useful when coding “higher up” because once you’ve checked if ($myObject instanceof coolInterface) you can be sure that you have access to all the methods that interface defines.

    This is of course very useful when we talk about standard interfaces too – like testing if an object implements ArrayAccess for example.

    I also find that working in a large team, interfaces can be part of a design. Once I made an interface purely so another developer could “code to it”. I could continue with my work knowing that the class he was creating would satisfy all my needs.

  4. Although the documenting of a public API is often given as the reason for interfaces, I don’t think that is what makes them useful. Their utility lies in the ability to allow substitution of a different implementation that implements the same public API. It is in this flexibility that the power of interfaces lie. They can be used to prevent an annoying “method not found” fatal error, while providing flexibility to specify multiple implementations of the same public API.

    This can be used to approximate multiple inheritance. For instance, this code:

    Allows taking advantage of SPL’s UnexpectedValueException while also allowing users to perform a catch-all:

    or a more fine-grained approach:

    This essentially mimics something like the hypothetical:

    Using an interface for a class that is a base class with no intention of allowing implementation switching makes little sense, as type hints can simply use the base class.

  5. I second Greg’s point, as it fits right into the “program to an interface” mantra. By “hiding” your class hierarchy behind your interfaces, users of your code need only ever know about the interfaces themselves. If they program directly to said interfaces rather than attempting to use your classes directly, both they and you are insulated from being affected by you changing/refactoring your classes.

Comments are closed.