tags:

views:

227

answers:

9

I've never been able to figure this out. If your language doesn't type-check, what benefits do interfaces provide you?

+8  A: 

Interfaces cause your program to fail earlier and more predictably when a subclass "forgets" to implement some abstract method in its parent class.

In PHP's traditional OOP, you had to rely on something like the following to issue a run-time error:

class Base_interface {
    function implement_me() { assert(false); }
}

class Child extends Base_interface {
}

With an interface, you get immediate feedback when one of your interface's subclasses doesn't implement such a method, at the time the subclass is declared rather than later during its use.

meagar
There's no "compile time" in php. All errors you get are runtime errors. If you don't implement an interface method, you get an error. If you just call a method that isn't implemented, you get an error. What exactly is the difference?
stereofrog
PHP will give you an error immediately after loading the class if there is an unimplemented method.
AlReece45
@AlReece45, yes, but this "loading" still takes place at run time.
stereofrog
@stereofrog: You just answered your own question. When you use an interface and you forget to implement a method, the error is thrown during compilation. If you do it as above, you have to actually call the method to get the error. That's the difference. And yes, PHP does have a compilation phase. It still has to compile it down to opcodes. Just because it doesn't create an executable doesn't mean it doesn't have a compilation phase. It isn't interpreted.
ryeguy
@ryeguy This is indeed the compile time I was referring to, but it turns out that method-not-defined errors aren't raised during this phase after all. They occur at the point the interpreter encounters your subclass declaration.
meagar
@ryeguy: whether it "compiles" to bytecodes or not are implementation details of how the interpreter _runs_ your program. It's not possible to "compile" a program without actually running it, at least, with the standard php. In that sense, every error you get is a runtime error and my question is still valid - why do people prefer one kind of runtime errors over the others?
stereofrog
@stereofrog Are you asking why people prefer errors that are raised when the class is defined vs errors that *may* be raised much later depending on how a class is used? I thought "fail early" was universally accepted best practice these days.
meagar
Yes, what if you only test the portion of the code that implements the methods, and then it blows up when you put it in production because it tried to execute an unimplemented method that wasn't executed during testing? That's obviously a problem of its own, but using a real interface would have caught this early. Like meagar said, how is "failing early" not an apparent benefit?
ryeguy
A: 

You get errors if you haven't added the required methods with the exact same signature.

dnagirl
A: 

Interfaces often used with unit-testing (test-driven design).

it also offers you more stable code. the interfaces are also used to support iterators (eg. support for foreach on objects) and comparators.

Bernd Ott
+4  A: 

Taken from this link (sums it up nicely):

  • Interfaces allow you to define/create a common structure for your classes – to set a standard for objects.
  • Interfaces solves the problem of single inheritance – they allow you to inject ‘qualities’ from multiple sources.
  • Interfaces provide a flexible base/root structure that you don’t get with classes.
  • Interfaces are great when you have multiple coders working on a project ; you can set up a loose structure for programmers to follow and let them worry about the details.
ChristopheD
Right. There are _design_ benefits to interfaces! If they were just a way to catch typos and forgotten methods, they'd be near useless in any language!
grossvogel
+2  A: 

I personally find interfacing a neat solution when building a DataAccess layer which has to support multiple DBMS's. Each DBMS implementation must implement the global DataAccess-interface with functions like Query, FetchAssoc, FetchRow, NumRows, TransactionStart, TransactionCommit, TransactionRollback etc. So when you're expanding your data-acccess posibilities you are forced to use a generic defined functionschema so you're application won't break at some point because you figured the function Query should now be named execQuery.

Interfacing helps you develop in the bigger picture :)

Ben Fransen
A: 

In my opinion, there's no point, no need and no sense. Things like interfaces, visibility modifiers or type hints are designed to enforce program "correctness" (in some sense) without actually running it. Since this is not possible in a dynamic language like php, these constructs are essentially useless. The only reason why they were added to php is make it look more like java, thus making the language more attractive for the "enterprise" market.

Forgot to add: uncommented downvoting sucks. ;//

stereofrog
Interfaces, visibility modifiers and "abstract" for example fulfill the exact same purpose in PHP as in Java. The object model has not much to do with the dynamic nature of PHP. Objects still have a more or less static type (their class) exactly as in Java. Of course they are there for "correctness" in both languages. That's why they're NOT useless.
Techpriester
Attempting to publicly access a private member, or forgetting to define an Interface's methods in a subclass are supposed to cause errors. Allowing PHP to fail early in these cases is unequivocally a good thing. These features are not only possible in PHP, they are already implemented, so your "answer" is demonstratively wrong. Hence the downvote. Just because you can circumvent these features doesn't mean you should, nor does it render them useless or senseless.
meagar
@meagar, the point is that php doesn't fail "early".
stereofrog
@stereofrog But it does. It fails early and reliably when you don't define methods of an interface or access a protected member. It tells you exactly what you've done wrong. Without this protection, you're inviting subtle logic errors that PHP may or may not be able to detect, which may crop up far later in seemingly unrelated code.
meagar
A: 

It may be weakly typed, but there is type hinting for methods: function myFunc(MyInterface $interface) Also, interfaces do help with testing and decoupling code.

blockhead
A: 

Type hinting in function/method signatures allows you to have much more control about the way a class interfaces with it's environment.

If you'd just hope that a user of your class will only use the correct objects as method parameters, you'll probably run into trouble. To prevent this, you'd have to implement complicated checks and filters that would just bloat your code and definitely have would lower your codes performance.

Type hinting gives you a tool to ensure compatibility without any bloated, hand written checks. It also allows your classes to tell the world what they can do and where they'll fit in.

Especially in complex frameworks like the Zend Framework, interfaces make your live much easier because they tell you what to expect from a class and because you know what methods to implement to be compatible to something.

Techpriester
+1  A: 

Types serve three distinct functions:

  • design
  • documentation
  • actual type checking

The first two don't require any form of type checking at all. So, even if PHP did no checking of interfaces, they would still be useful just for those two reasons.

I, for example, always think about my interfaces when I'm doing Ruby, despite the fact that Ruby doesn't have interfaces. And I often wish I could have some way of recording those design decisions in the source code.

On the other hand, I have seen plenty of Java code that used interfaces, but clearly the author never thought about them. In fact, in one case, one could see from the indentation, whitespace and some leftover comments in the interface that the author had actually just copied and pasted the class definition and deleted all method bodies.

Now to the third point: PHP actually does type check interfaces. Just because it type checks them at runtime doesn't mean it doesn't type check them at all.

And, in fact, it doesn't even check them at runtime, it checks them at load time, which happens before runtime. And isn't "type checking doesn't happen at runtime but before that" pretty much the very definition of static type checking?

Jörg W Mittag