2

Can you help to clarify PHP Interface for me. I get that the main point is so that multiple classes can implement some of the same functions.

abstract class Plane {
     public function openDoors();
}


interface Fliers {
     public function fly();
}

now lets use them

class Boeing747 extends Plane implements Fliers {
  public function fly() {
     // some stuff
  }

  public function openDoors() {
    // do something
  }

}

and

class Tweety implements Fliers{
    public function fly() {
    // some stuff
    }
}

In this case both Boeing747 and Tweety can implement the interface Fliers to access the public function fly(). However, in all examples that I am seeing, no functionality is actually defined in the interface, but rather when it is called inside of the class method itself.

Why would I not just define fly() as a separate function in each of Boeing747 and Tweety, instead of using the interface? Can you provide a concrete, basic example where it would be advantageous? Thanks!

user2694306
  • 3,832
  • 10
  • 47
  • 95
  • Interfaces separate what the class does, from how it does it. Is like a contract, it defines what the client can expect, but the developer implement it as he wants. So, we can have multiple implementations of the same contract, and you can always use the interface without knowing how is implemented. – JosEduSol Oct 18 '14 at 07:43
  • So both child are Plane classes and can use polymorphism to do different things with same func call? – Botea Florin Jan 16 '18 at 20:36

1 Answers1

3

It's a technique known as Design by Contract. Essentially, the interface serves as a contract, or a promise that any class that implements the interface will exhibit a particular set of behaviours. It allows your code to check capabilities of an object passed to it without having to worry about details that don't matter in the current context. For example, your openDoors() method could equally apply to a house, an aircraft, a canal lock, a car or anything else with doors, but other than having doors all of these things have very little in common. Even if they do all support the idea of having doors that can be opened, they may actually perform the door opening actions in wildly different ways.

The interface allows you to tell calling code that all these things have doors that you can open, without having to impose any artificial relationship between them when none exists. The instanceof keyword lets you check if an object meets certain criteria (if it's an instance of a particular class or subclass, or if it implements a particular interface).

interface ThingWithDoors {
    public function openDoors ();
}

class House implements ThingWithDoors {
    // Implement openDoors here
}

class CanalLock implements ThingWithDoors {
    // Implement openDoors here
}

class Boeing747 extends Aircraft implements ThingWithDoors {
    // Implement openDoors here
}

// Calling code

if ($object instanceof ThingWithDoors) {
    // We don't know exactly what class we have, but we do know it has an openDoors method
    $object -> openDoors ();
}

You could in theory achieve the same thing with other PHP functionality such as method_exists or Reflection, but those techniques are far from ideal because there's no contract to enforce anything (two different classes could implement door opening but have completely different names for the methods that do it, and you'd have to check for both with method_exists calls). Then, suppose, some other programmer adds a new class to the system that implements door opening in a completely different way from the ones you already check for. All the code where doors could be opened throughout the program would have to be updated to account for this new method too! If you add a new class to the system and it implements the ThingWithDoors interface, however, then all the code that opens doors will automatically work with the new class as it did with the old class without any modification at all (provided the new class implements the interface properly and respects return values that, sadly, aren't enforced by PHP interfaces).

Another nice thing about this for the programmer is that they don't have to keep looking up in the documentation/source code how to invoke certain behaviours in an object. If they know what the ThingWithDoors interface looks like then they know that everything that implements ThingWithDoors can have its doors opened, and that the method call for doing it is always going to be openDoors (). That can save you a fair bit of time as a developer, especially on a big project!

GordonM
  • 31,179
  • 15
  • 87
  • 129
  • I know this is 2 years old but I Recently come across `Interfaces`. My question is, why would you need to check if a Object had a certain Method or property inside it if you made it? Surely, you'd know it was in there or could check. Where would integrating a interface be needed? – Jaquarh Mar 11 '16 at 16:28
  • 1
    Like I said, the interface is essentially a contract, a promise to provide certain functionality through a uniform API. The usefulness of that cannot be understated. First and foremost in testing. e.g., if you have a database class that implements an interface then you can make a mock class that implements the same interface but always returns the data you want it to, so you don't have to worry that your real database is returning the right data for your tests to work. It's also hugely useful for allowing other developers to write plugins for your code and that's just for starters. – GordonM Mar 11 '16 at 18:37
  • 1
    And what if you didn't make the class? Big projects rarely have one programmer working on them (Sorry for the two replies but I ran out of space for just one comment). – GordonM Mar 11 '16 at 18:42
  • Thats very much appreciated! – Jaquarh Mar 14 '16 at 17:58