views:

939

answers:

16

In static languages like Java you need interfaces because otherwise the type system just won't let you do certain things. But in dynamic languages like PHP and Python you just take advantage of duck-typing.

PHP supports interfaces. Ruby and Python don't have them. So you can clearly live happily without them.

I've been mostly doing my work in PHP and have never really made use of the ability to define interfaces. When I need a set of classes to implement certain common interface, then I just describe it in documentation.

So, what do you think? Aren't you better off without using interfaces in dynamic languages at all?

A: 

Well, first of all, it's right that Ruby does not have Interface as is, but they have mixin, wich takes somehow the best of both interfaces and abstract classes from other languages.

The main goal of interface is to ensure that your object SHALL implement ALL the methods present in the interface itself.

Of course, interface are never mandatory, even in Java you could imagine to work only with classes and using reflection to call methods when you don't know wich kind of object you're manipulating, but it is error prone and should be discouraged in many ways.

gizmo
+5  A: 

Yes, there is a point

If you don't explicitly use interfaces your code still uses the object as though it implemented certain methods it's just unclear what the unspoken interface is.

If you define a function to accept an interface (in PHP say) then it'll fail earlier, and the problem will be with the caller not with the method doing the work. Generally failing earlier is a good rule of thumb to follow.

Allain Lalonde
+1  A: 

I was under the impression that Python doesn't have interfaces. As far as I'm aware in Python you can't enforce a method to be implemented at compilation time precisely because it is a dynamic language.

There are interface libraries for Python but I haven't used any of them.

Python also has Mixins so you could have create an Interface class by defining a Mixin an having pass for every method implementation but that's not really giving you much value.

Dave Webb
Thanks for pointing this out, I did a web search before, found an article that discussed intefaces in Python and concluded that Python must have interfaces - actually the article discussed the question of adding interfaces to python.
Rene Saarsoo
A: 

Well, it would certainly be easier to check if a given object supported an entire interface, instead of just not crashing when you call the one or two methods you use in the initial method, for instance to add an object to an internal list.

Duck typing has some of the benefits of interfaces, that is, easy of use everywhere, but the detection mechanism is still missing.

Lasse V. Karlsen
+5  A: 

I think of it more as a level of convenience. If you have a function which takes a "file-like" object and only calls a read() method on it, then it's inconvenient - even limiting - to force the user to implement some sort of File interface. It's just as easy to check if the object has a read method.

But if your function expects a large set of methods, it's easier to check if the object supports an interface then to check for support of each individual method.

davidavr
A: 

Rene, please read my answer to "Best Practices for Architecting Large Systems in a Dynamic Language" question here on StackOverflow. I discuss some benefits of giving away the freedom of dynamic languages to save development effort and to ease introducing new programmers to the project. Interfaces, when used properly, greatly contribute to writing reliable software.

Michał Rudnicki
A: 

It's like saying you don't need explicit types in a dynamically-typed language. Why don't you make everything a "var" and document their types elsewhere?

It's a restriction imposed on a programmer, by a programmer. It makes it harder for you to shoot yourself in the foot; gives you less room for error.

aib
+2  A: 

I think use of interfaces is determined more by how many people will be using your library. If it's just you, or a small team then documentation and convention will be fine and requiring interfaces will be an impediment. If it's a public library then interfaces are much more useful because they constrain people to provide the right methods rather than just hint. So interfaces are definitely a valuable feature for writing public libraries and I suppose that lack (or at least de-emphasis) is one of the many reasons why dynamic languages are used more for apps and strongly-typed languages are used for big libraries.

marijne
+4  A: 

If you do not have hight security constraints (so nobody will access you data a way you don't want to) and you have a good documentation or well trained coders (so they don't need the interpreter / compiler to tell them what to do), then no, it's useless.

For most medium size projects, duck typing is all you need.

e-satis
+1  A: 

One use of the Java "interface" is to allow strongly-typed mixins in Java. You mix the proper superclass, plus any additional methods implemented to support the interface.

Python has multiple inheritance, so it doesn't really need the interface contrivance to allow methods from multiple superclasses.

I, however, like some of the benefits of strong typing -- primarily, I'm a fan of early error detection. I try to use an "interface-like" abstract superclass definition.

class InterfaceLikeThing( object ):
    def __init__( self, arg ):
        self.attr= None
        self.otherAttr= arg
    def aMethod( self ):
        raise NotImplementedError
    def anotherMethod( self ):
        return NotImplemented

This formalizes the interface -- in a way. It doesn't provide absolute evidence for a subclass matching the expectations. However, if a subclass fails to implement a required method, my unit tests will fail with an obvious NotImplemented return value or NotImplementedError exception.

S.Lott
Have you ever used the interface libraries in Plone or Trac? Trac in particular is a very approachable codebase and makes use of interfaces in its plugin architecture. The code might do things like querying for all IMainMenuItem implementations to populate the main menu.
joeforker
+1 for supplying to the lack of type checks with unit tests!
Paolo Tedesco
+4  A: 

Interfaces actually add some degree of dynamic lang-like flexibility to static languages that have them, like Java. They offer a way to query an object for which contracts it implements at runtime.

That concept ports well into dynamic languages. Depending on your definition of the word "dynamic", of course, that even includes Objective-C, which makes use of Protocols pretty extensively in Cocoa.

In Ruby you can ask whether an object responds to a given method name. But that's a pretty weak guarantee that it's going to do what you want, especially given how few words get used over and over, that the full method signature isn't taken into account, etc.

In Ruby I might ask

object.respond_to? :sync

So, yeah, it has a method named "sync", whatever that means.

In Objective-C I might ask something similar, i.e. "does this look/walk/quack like something that synchronizes?":

[myObject respondsToSelector:@selector(sync)]

Even better, at the cost of some verbosity, I can ask something more specific, i.e. "does this look/walk/quack like something that synchronizes to MobileMe?":

[myObject respondsToSelector:@selector(sync:withMobileMeAccount:)]

That's duck typing down to the species level.

But to really ask an object whether it is promising to implement synchronization to MobileMe...

[receiver conformsToProtocol:@protocol(MobileMeSynchronization)]

Of course, you could implement protocols by just checking for the presence of a series of selectors that you consider the definition of a protocol/duck, and if they are specific enough. At which point the protocol is just an abbreviation for a big hunk of ugly responds_to? queries, and some very useful syntactic sugar for the compiler/IDE to use.

Interfaces/protocols are another dimension of object metadata that can be used to implement dynamic behavior in the handling of those objects. In Java the compiler just happens to demand that sort of thing for normal method invocation. But even dynamic languages like Ruby, Python, Perl, etc. implement a notion of type that goes beyond just "what methods an object responds to". Hence the class keyword. Javascript is the only really commonly used language without that concept. If you've got classes, then interfaces make sense, too.

It's admittedly more useful for more complicated libraries or class hierarchies than in most application code, but I think the concept is useful in any language.

Also, somebody else mentioned mixins. Ruby mixins are a way to share code -- e.g., they relate to the implementation of a class. Interfaces/protocols are about the interface of a class or object. They can actually complement each other. You might have an interface which specifies a behavior, and one or more mixins which help an object to implement that behavior.

Of course, I can't think of any languages which really have both as distinct first-class language features. In those with mixins, including the mixin usually implies the interface it implements.

Robert Sanders
A: 

as a PHP programmer, the way I see it, an Interface is basically used as a contract. It lets you say that everything which uses this interface MUST implement a given set of functions.

I dunno if that's all that useful, but I found it a bit of a stumbling block when trying to understand what Interfaces were all about.

nickf
+1  A: 

In a language like PHP where a method call that doesn't exist results in a fatal error and takes the whole application down, then yes interfaces make sense.

In a language like Python where you can catch and handle invalid method calls, it doesn't.

thr
+2  A: 

Python 3000 will have Abstract Base Classes. Well worth a read.

James Hopkin
A: 

If you felt you had to, you could implement a kind of interface with a function that compares an object's methods/attributes to a given signature. Here's a very basic example:

file_interface = ('read', 'readline', 'seek')

class InterfaceException(Exception): pass

def implements_interface(obj, interface):
    d = dir(obj)
    for item in interface:
        if item not in d: raise InterfaceException("%s not implemented." % item)
    return True

>>> import StringIO
>>> s = StringIO.StringIO()
>>> implements_interface(s, file_interface)
True
>>> 
>>> fp = open('/tmp/123456.temp', 'a')    
>>> implements_interface(fp, file_interface)
True
>>> fp.close()
>>> 
>>> d = {}
>>> implements_interface(d, file_interface)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in implements_interface
__main__.InterfaceException: read not implemented.

Of course, that doesn't guarantee very much.

wbg
A: 

Stop trying to write Java in a dynamic language.

Geo
Well, I asked this question because I thought that Interfaces in PHP were kind of Java-ish... and I really dislike Java... haven't used it for years.
Rene Saarsoo