tags:

views:

1574

answers:

9

Interfaces allow you to create code which defines the methods of classes that implement it. You cannot however add any code to those methods.

Abstract classes allow you to do the same thing, along with adding code to the method.

Now if you can achieve the same goal with abstract classes, why do we even need the concept of interfaces?

I've been told that it has to do with OO theory from C++ to Java, which is what PHP's OO stuff is based on. Is the concept useful in Java but not in PHP? Is it just a way to keep from having placeholders littered in the abstract class? Am I missing something?

Edit: @John: Couldn't you acheieve the same thing with an abstract class though?

+3  A: 

The concept is useful all around in object oriented programming. To me I think of an interface as a contract. So long my class and your class agree on this method signature contract we can "interface". As for abstract classes those I see as more of base classes that stub out some methods and I need to fill in the details.

John Downey
+1  A: 

Interfaces are essentially a blueprint for what you can create. They define what methods a class must have, but you can create extra methods outside of those limitations.

I'm not sure what you mean by not being able to add code to methods - because you can. Are you applying the interface to an abstract class or the class that extends it?

A method in the interface applied to the abstract class will need to be implemented in that abstract class. However apply that interface to the extending class and the method only needs implementing in the extending class. I could be wrong here - I don't use interfaces as often as I could/should.

I've always thought of interfaces as a pattern for external developers or an extra ruleset to ensure things are correct.

Ross
In PHP, interfaces contain only method declaration and not the actual implementation. Abstract classes, however, allow you to "add code" to the methods to be inherited by the classes that extend it. I believe this difference is what mk was referring to.
nocash
+9  A: 

The entire point of interfaces is to give you the flexability to have your class be forced to implement multiple interfaces, but still not allow multiple inheritance. The issues with inheriting from multiple classes are many and varied and the wikipeidia page page on it sums them up pretty well.

Interfaces are a compromise. Most of the problems with multiple inheritance don't apply to abstract base classes, so most modern languages these days disable multiple inheritance yet call abstract base classes interfaces and allows a class to "implement" as many of those as they want.

Craig H
+1  A: 

In my opinion, interfaces should be preferred over non-functional abstract classes. I wouldn't be surprised if there would be even a performance hit there, as there is only one object instantiated, instead of parsing two, combining them (although, I can't be sure, I'm not familiar with the inner workings of OOP PHP).

It is true that interfaces are less useful/meaningful than compared to, say, Java. On the other hand, PHP6 will introduce even more type hinting, including type hinting for return values. This should add some value to PHP interfaces.

tl;dr: interfaces defines a list of methods that need to be followed (think API), while an abstract class gives some basic/common functionality, which the subclasses refine to specific needs.

Henrik Paul
+2  A: 

I can't remember if PHP is different in this respect, but in Java, you can implement multiple Interfaces, but you can't inherit multiple abstract classes. I'd assume PHP works the same way.

Dan Herbert
A: 

Interfaces aren't just for making sure developers implement certain methods. The idea is that because these classes are guaranteed to have certain methods, you can use these methods even if you don't know the class's actual type. Example:

interface Readable {
  String read();
}

List<Readable> readables; // dunno what these actually are, but we know they have read();
for(Readable reader : readables)
  System.out.println(reader.read());

In many cases, it doesn't make sense to provide a base class, abstract or not, because the implementations vary wildly and don't share anything in common besides a few methods.

Dynamically typed languages have the notion of "duck-typing" where you don't need interfaces; you are free to assume that the object has the method that you're calling on it. This works around the problem in statically typed languages where your object has some method (in my example, read()), but doesn't implement the interface.

Outlaw Programmer
A: 

I can't remember if PHP is different in this respect, but in Java, you can implement multiple Interfaces, but you can't inherit multiple abstract classes. I'd assume PHP works the same way.

In PHP you can apply multiple interfaces by seperating them with a comma (I think, I don't find that a clean soloution).

As for multiple abstract classes you could have multiple abstracts extending each other (again, I'm not totally sure about that but I think I've seen that somewhere before). The only thing you can't extend is a final class.

Ross
A: 

Interfaces will not give your code any performance boosts or anything like that, but they can go a long way toward making it maintainable. It is true that an abstract class (or even a non-abstract class) can be used to establish an interface to your code, but proper interfaces (the ones you define with the keyword and that only contain method signatures) are just plain easier to sort through and read.

That being said, I tend to use discretion when deciding whether or not to use an interface over a class. Sometimes I want default method implementations, or variables that will be common to all subclasses.

Of course, the point about multiple-interface implementation is a sound one, too. If you have a class that implements multiple interfaces, you can use an object of that class as different types in the same application.

The fact that your question is about PHP, though, makes things a bit more interesting. Typing to interfaces is still not incredibly necessary in PHP, where you can pretty much feed anything to any method, regardless of its type. You can statically type method parameters, but some of that is broken (String, I believe, causes some hiccups). Couple this with the fact that you can't type most other references, and there isn't much value in trying to force static typing in PHP (at this point). And because of that, the value of interfaces in PHP, at this point is far less than it is in more strongly-typed languages. They have the benefit of readability, but little else. Multiple-implementation isn't even beneficial, because you still have to declare the methods and give them bodies within the implementor.

Brian Warshaw
A: 

The difference between using an interface and an abstract class has more to do with code organization for me, than enforcement by the language itself. I use them a lot when preparing code for other developers to work with so that they stay within the intended design patterns. Interfaces are a kind of "design by contract" whereby your code is agreeing to respond to a prescribed set of API calls that may be coming from code you do not have aceess to.

While inheritance from abstract class is a "is a" relation, that isn't always what you want, and implementing an interface is more of a "acts like a" relation. This difference can be quite significant in certain contexts.

For example, let us say you have an abstract class Account from which many other classes extend (types of accounts and so forth). It has a particular set of methods that are only applicable to that type group. However, some of these account subclasses implement Versionable, or Listable, or Editable so that they can be thrown into controllers that expect to use those APIs. The controller does not care what type of object it is

By contrast, I can also create an object that does not extend from Account, say a User abstract class, and still implement Listable and Editable, but not Versionable, which doesn't make sense here.

In this way, I am saying that FooUser subclass is NOT an account, but DOES act like an Editable object. Likewise BarAccount extends from Account, but is not a User subclass, but implements Editable, Listable and also Versionable.

Adding all of these APIs for Editable, Listable and Versionable into the abstract classes itself would not only be cluttered and ugly, but would either duplicate the common interfaces in Account and User, or force my User object to implement Versionable, probably just to throw an exception.

Sam McAfee