Interface tutorial

3,928 views
Skip to first unread message

Johann Höchtl

unread,
Dec 17, 2011, 8:56:45 AM12/17/11
to golan...@googlegroups.com
The hardest part of Go for me are interfaces / structs and embedding. Is there a tutorial somewhere going more into details and applications? Effective Go is great and leaves nothing open, it's just me.

Johann

Andrew Gerrand

unread,
Dec 18, 2011, 6:36:10 PM12/18/11
to golan...@googlegroups.com
This is definitely an area where we could use more documentation, and it will certainly be the subject of future blog posts.

If you have specific questions feel free to ask them here.

Andrew

Rodrigo Moraes

unread,
Dec 18, 2011, 8:22:59 PM12/18/11
to golang-nuts
On Dec 17, 11:56 am, Johann Höchtl wrote:
> Is there a tutorial somewhere going more into details and applications?

This was great for me:

http://golangtutorials.blogspot.com/2011/05/table-of-contents.html

Interfaces part:

http://golangtutorials.blogspot.com/2011/06/interfaces-in-go.html

-- rodrigo

Rob 'Commander' Pike

unread,
Dec 19, 2011, 2:23:43 PM12/19/11
to Rodrigo Moraes, golang-nuts

It's a hoary example to use geometry as an example of abstract computations, but there's an important detail here. It's always bothered me in OO languages that we can make Circle, Square, etc. subclasses of Shape (say), but that's the one design decision we get to make. What if we want to align those things along other axes (so to speak), like topological genus or plant genus, if you're a landscaper? You might lose your way or dig yourself into a hole with multiple inheritance.

In Go, that's a non-issue: Circle can satisfy independent interfaces for TopologicalGenus or GrassGenus as well as Area or Perimeter or Symmetry or whatever. Moreover, you don't have to work them all out ahead of time; the whole design can evolve without invalidating early decisions.

This point is critical to interfaces in Go, but people coming from an OO background don't seem to get it. By stopping at one interface for shapes, the author misses a chance to say something vital.

Go's interfaces aren't a variant on Java or C# interfaces, they're much more. They are a key to large-scale programming and adaptable, evolutionary design.

-rob

John Asmuth

unread,
Dec 19, 2011, 3:17:15 PM12/19/11
to golan...@googlegroups.com


On Monday, December 19, 2011 2:23:43 PM UTC-5, r wrote:

In Go, that's a non-issue: Circle can satisfy independent interfaces for TopologicalGenus or GrassGenus as well as Area or Perimeter or Symmetry or whatever. Moreover, you don't have to work them all out ahead of time; the whole design can evolve without invalidating early decisions.

This is why I use Go for nearly everything I work on. Not concurrency primitives (though that is what drew me in the first place) or syntax (I don't really care what side of the variable the type appears on).

It's the fact that I don't have to spend time up front designing some sort of type hierarchy and then rearranging it two or three times before I finish. It's not even the fact that it's easy to do it right - it's the fact that I just don't have to worry about it and can get on with the actual algorithm.

Johann Höchtl

unread,
Dec 19, 2011, 3:23:05 PM12/19/11
to golan...@googlegroups.com, Rodrigo Moraes

@rodrigo I discovered these and in fact interfaces are much clearer now.

After following some discussion on this list I have the same sentiments as @robpike though, that Shapes are the canonical example coming from an OO language but an otherwise oversimplificating decision to explain the concepts.

Rodrigo Moraes

unread,
Dec 19, 2011, 4:18:41 PM12/19/11
to golang-nuts
On Dec 19, 6:23 pm, Johann Höchtl wrote:
> After following some discussion on this list I have the same sentiments as
> @robpike though, that Shapes are the canonical example coming from an OO
> language but an otherwise oversimplificating decision to explain the
> concepts.

He is right; I pretty much understand and agree.

It was a good introduction for me because it had the keywords I was
looking for. It helped me to get started, even though later I realized
that we don't translate concepts like that. Maybe Go needs a
definitive introduction for people coming from OO; I'm a slow learner
and that one filled a void for me.

-- rodrigo

Andrew Gerrand

unread,
Dec 19, 2011, 9:11:38 PM12/19/11
to golan...@googlegroups.com

Ziad Hatahet

unread,
Dec 20, 2011, 2:32:20 AM12/20/11
to Rob 'Commander' Pike, Rodrigo Moraes, golang-nuts
On Mon, Dec 19, 2011 at 11:23 AM, Rob 'Commander' Pike <r...@google.com> wrote:
In Go, that's a non-issue: Circle can satisfy independent interfaces for TopologicalGenus or GrassGenus as well as Area or Perimeter or Symmetry or whatever. Moreover, you don't have to work them all out ahead of time; the whole design can evolve without invalidating early decisions.
 -rob


Doesn't the first part apply to the more "traditional" languages as well (like C# or Java)? How is it more general in Go?

interface Shape {
    double Area();
    double Perimeter();
}

interface TopologicalGenus {
    int Rank();
}

class C implements Shape, TopologicalGenus {
  // Method implementations
}


David Symonds

unread,
Dec 20, 2011, 3:03:03 AM12/20/11
to Ziad Hatahet, Rob 'Commander' Pike, Rodrigo Moraes, golang-nuts

Now imagine that class C has a method that isn't in those interfaces
(e.g. Color), and you want to write some code that uses, say, the Area
and Color methods (e.g. to calculate the quantity of paint you need to
buy). In languages like C++, Java or C# you have to go edit the
definition of class C to say that it implements your new interface; in
Go, you simply define the interface and there's no need to change
class C.

That matters a huge amount in big programs, because you can happily
keep adding more and more interfaces without worrying that it's going
to make your class C look messy. It also means that you aren't at the
mercy of whoever owns class C. It also means you don't have to
recompile class C.

In Go, interfaces are *truly* independent. They aren't just a type
that you declare and then have to go modify all your code to say which
things implement that interface.


Dave.

Ziad Hatahet

unread,
Dec 20, 2011, 3:07:08 AM12/20/11
to David Symonds, Rob 'Commander' Pike, Rodrigo Moraes, golang-nuts
Makes sense. Thanks for the clarification :)


--
Ziad

Jesse McNelis

unread,
Dec 20, 2011, 3:09:46 AM12/20/11
to Ziad Hatahet, golang-nuts
On 20/12/11 18:32, Ziad Hatahet wrote:
> Doesn't the first part apply to the more "traditional" languages as well
> (like C# or Java)? How is it more general in Go?
>
> interface Shape {
> double Area();
> double Perimeter();
> }
>
> interface TopologicalGenus {
> int Rank();
> }
>
> class C implements Shape, TopologicalGenus {
> // Method implementations
> }

There are lots of limitations with this.
1. You have to convince whoever is in charge of "class C" to add this
interface to the implements list.

2. Having the implements list include more than a dozen interface names
gets problematic.

3. A subset of the methods of a class might have a completely different
meaning to you than someone else.

type CookieJar interface {
Get(key string)(value string,err error)
Put(key string,value string)(err error)
}

type AddressBook interface {
Get(key string)(value string,err error)
Put(key string,value string)(err error)
}
etc.

Both are satisfied by the KeyValueStore type, but it would be really
weird for KeyValueStore to say it implemented CookieJar and AddressBook.

For a reasonably sized class the number of possible interfaces it could
satisfy can be quite large.

- jessta

Lukasz

unread,
Dec 20, 2011, 9:04:58 AM12/20/11
to golan...@googlegroups.com, Rodrigo Moraes

Go's interfaces aren't a variant on Java or C# interfaces, they're much more. They are a key to large-scale programming and adaptable, evolutionary design.

How are they not just a variant of Java interfaces in the sense that you don't need to retrofit your existing classes to say "implements" the new interface, or is this the only difference? It seems that if I want to create a new interface in Go and I already have a bunch of classes that implement the methods of that interface then those classes are automatically implementations of that interface. In Java, you have to go around to all said classes and type "implements MyNewInterface". Is there any difference beyond this?

Volker Dobler

unread,
Dec 20, 2011, 9:35:53 AM12/20/11
to golang-nuts

To my understanding: Almost none. The only difference is that just
typing "implements MyNewInterface" is _not_ enough in Java: You have
to recompile the whole stuff (iff you have the sources...).

Steve McCoy

unread,
Dec 20, 2011, 10:19:08 AM12/20/11
to golan...@googlegroups.com, Rodrigo Moraes
This is a much larger difference than you're implying, though. One part of it is that, in Java, you can't compose interfaces except though inheritance, and this only saves some effort in the definition of the interface, not the classes that implement it. For example, consider a Java function that wants an object that's both Comparable and Serializable. I don't think this is an unusual situation. (I'm going to omit some details with generics, but take my word for it that the overall message would remain the same if I kept them.) Step one is to make a special interface:

interface Storable extends Comparable, Serializable{ }

And then the function can take one of those:

void storeInOrder(Storable item){ … }

Next, the class (or classes) to be stored have to fulfill this interface. Unfortunately, if a class already implements Comparable and Serializable, there's going to be trouble.

class Kitten implements Comparable, Serializable{ … }

An instance of Kitten cannot be assigned to a Storable because Kitten doesn't implement that interface, even though the interface's methods have the same names and signatures of Kitten's methods and Storable is defined in terms of the interfaces that Kitten implements. This is basically an implementation detail, a broken abstraction of this style of object-oriented design. Additionally, Java doesn't allow a class to implement an interface if any of its methods are the same as another implemented interface's methods. The only option now is to write a wrapper class:

class StorableKitten implements Storable{
Kitten k;
StorableKitten(Kitten k){ this.k = k; }
int compareTo(Object o){ return k.compareTo(o); }
}

And then wrap all instances of Kitten:

Kitten k = …;
storeInOrder(new StorableKitten(k));

Go eliminates this frustrating tedium. Any type that fits the Comparable and Serializable interfaces can be assigned to this interface:

type Storable interface {
Comparable
Serializable
}

No wrapper classes need to be defined and invoked by the programmer.

Sathish VJ

unread,
Dec 20, 2011, 1:12:08 PM12/20/11
to golan...@googlegroups.com, Rodrigo Moraes
Hello rob, thank you for the feedback.  I am the author of these articles at http://golangtutorials.blogspot.com, and I agree that what you said has not been addressed in this particular article.  Based on the feedback here, I shall attempt that in a second writeup.  Leaving this one as it is though, as I see that this is one of the more visited pages and could indicate that there are beginners to Go or crossovers from OOP (like myself).  

thanks again
sathish


Adam Logghe

unread,
Dec 21, 2011, 11:41:58 AM12/21/11
to golan...@googlegroups.com
Thanks for those tutorials Satish.

The way you mapped traditional OO to Go was really helpful to me and I think your Go articles are one of the best introductions out there.

I look forward to your take on this thread.

Adam

Sathish VJ

unread,
Jan 3, 2012, 3:39:52 AM1/3/12
to golan...@googlegroups.com
Hello, to address the feedback here I have added another article at http://golangtutorials.blogspot.com/2012/01/interfaces-in-go-part-2-aiding.html.  As before, in keeping the target audience in mind, I've kept the illustrations and explanations as simple as possible.  

Wish you all a wonderful 2012!

thank you
Sathish
Reply all
Reply to author
Forward
0 new messages