08.07.2007 / Object-oriented PHP :: A guide for fellow ISys junkies
Interfaces
If you don’t remember what interfaces are, I’ll do my best to explain. Work with me here. Oddly enough, interfaces in programming have some similarities to interfaces in the real world. Take the buttons on my TV for example. Wait, no, take the buttons on my remote instead. You know I haven’t touched the buttons on the TV since I bought the thing. I need at minimum five buttons on my remote to ensure that I can enjoy the latest episodes of Mythbusters, Glenn Beck, and Cops: power button, channel up, channel down, volume up, and volume down. Sure, I’d love a TiVo with all it’s recording abilities, but I’m too cheap for that. Right now, the five buttons will do, but nothing less. Now, give me a remote for a different TV. As crazy as it is, I still have at least the five buttons that I need! Why? Because the manufacturer of the TV knows there are five operations that I have to have to qualify for my membership renewal in The Bedsore Club.
Interfaces in programming are similar. I have a class that can call the functions power(), channelUp(), channelDown(), volumeUp(), and volumeDown() of whatever class that you give me. I don’t know exactly what you’re going to do once I call those functions, but to make sure nothing breaks between my class and your class, I’m going to require that you expose those five functions: power(), channelUp(), channelDown(), volumeUp(), and volumeDown(). Here’s how:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | // I declare the interface - notice there's no "class" word on the next line interface Remote { public function power(); public function channelUp(); public function channelDown(); public function volumeUp(); public function volumeDown(); } // You implement the interface class SonyRemote implements Remote { public function power() { // Do something } public function channelUp() { // Do something } public function channelDown() { // Do something } public function volumeUp() { // Do something } public function volumeDown() { // Do something } public function record() { // Do something } } $myRemote = new SonyRemote(); |
To implement the interface, you just have to follow your implementing class name with implements and then the interface’s class name (class SonyRemote implements Remote {.) Remind you of Java? Also, as you can see, SonyRemote contains at least every method that is defined in the Remote interface. I also threw another method in the SonyRemote class just so you can see that you can and most likely will add other methods in addition to those defined by the interface. If you by chance don’t implement all the methods required by the interface, you’ll see this error:
[code]
Fatal error: Class SonyRemote contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Remote::power) in /mnt/backside/vol/navyblue/spunky/aaronius/aaronhardy.com/php_sandbox/index.php on line 73
[/code]
Before moving on, there are a few other things we can learn from interfaces. Interfaces themselves cannot be instantiated. In other words, if I try to instantiate the Remote interface like this:
1 | $myRemote = new Remote(); |
I get this:
[code]
Fatal error: Cannot instantiate interface Remote in /mnt/backside/vol/navyblue/spunky/aaronius/aaronhardy.com/php_sandbox/index.php on line 75
[/code]
So, an interface is really just instruction to the programmer saying, hey, if you want me to use your class, it must have at least these functions. I then enforce that instruction by only accepting your classes if they have implemented the interface.
Another thing to know is that you can also enforce the number and types (see the section on type hinting) of arguments that the methods must have. Here’s an example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // Declare the interface interface Remote { public function power(Dog $niner); public function channelUp(); public function channelDown(); public function volumeUp(); public function volumeDown(); } // Implement the interface class SonyRemote implements Remote { public function power(Cat $niner) { // Do something } public function channelUp() { // Do something } public function channelDown() { // Do something } public function volumeUp() { // Do something } public function volumeDown() { // Do something } } $myRemote = new SonyRemote(); |
The interface says that my Power() method must accept a dog, but my SonyRemote class’s Power() function is accepting a cat instead. I have no idea what a dog and cat have to do with power, but anyway we would get this error:
[code]
Fatal error: Declaration of SonyRemote::power() must be compatible with that of Remote::power() in /mnt/backside/vol/navyblue/spunky/aaronius/aaronhardy.com/php_sandbox/index.php on line 58
[/code]
One last thing: you can implement multiple interfaces by separating the interface names with commas, like this:
1 | class SonyRemote implements Remote, SomeOtherInterface |
Easy enough. You’re well on your way.

Nice site you have here Aaron! There’s just one small point that I think you might be interested in. You mentioned that PHP doesn’t support object overloading, but it actually does. Several special methods can be set up on objects, including __get, __set, and __call. This may not be the same implementation as is found in other languages, but it is overloading. Check it out.