Thursday, June 2, 2011

Interfaces in Go

Interfaces are contracts that exist between an expected implementation of a functionality and its actual implementation. In real life there are innumerable interfaces that we are implicitly bound to and that we expect of others. When we put money in a bank, we expect that the money is there the next day and if they have promised us a daily interest, then that we have the additional amount. How the bank keeps the money safe and how it generates the amount for the interest is not something we usually concern ourselves with. This implicit contract is our interface with the bank, and also therefore, the bank’s interface with us.

In programming, interfaces follow a similar model. We will work out an example that uses Go’s idea of interfaces, which is different from interfaces in programming languages like Java, C++, C#, etc. which have object oriented constructs. Go being procedural implements it differently, but it works just as well and has many positive downstream implications.

Our example takes us through getting the area of various shapes. A rectangle is a shape, a square is a shape, a circle is a shape … and a shape has an area. So Shape, which is an abstract concept, can be an interface. And actual shapes like a circle, rectangle, triangle, etc. can provide its own area. And we can then have a unified way of getting the area of different shapes.

If you are new to programming, the impact of such an idea might not be clear right now, but it is very powerful. If you have traveled to places where you did not know the language, you might have struggled to get information as and when you needed it. "When will the train arrive?" - what if there was one consistent asking that irrespective of where you were in the world. Well, there isn’t, which is why we have to go through the shortened sentences, higher voices, hand waving, pointing at things, writing it out and so on and so forth. In computing too, we have to deal with various types of objects and in order that we may interact with them consistently, interfaces are used.

In the first step, we shall go through just creating a simple rectangle class and print its area. Full code

At this point, this code has no interfaces. As we proposed earlier, let us now add interfaces. The Area function is what we will abstract out into the interface called Shaper.

In Go, the convention is to "er" a type to indicate that it is an interface. Shape is best named Shaper when it is an interface. Convert is best named Converter when it is an interface. Not doing so won’t crash your program but it is useful to follow convention as it will be easier for others reading the code to understand what is intended.

In languages like Java and C#, a type or class that intends to provide implementation for an interface needs to explicitly state that. So in Java, one would have to do:

public class Rectangle implements Shaper { //implementation here }

In Go however, such explicit declaration of implementation is not required. And you can see that in the code. The Shaper interface is defined with a single method Area() int. The Rectangle type has a function with the same signature: func (r Rectangle) Area() int. So Go automatically understands that the Rectangle type implements the Shaper interface. Therefore you can cast a Rectangle type to be a Shaper type s := Shaper(r) and call the Area function on it: s.Area().

So far we have achieved only the same result as before. Let’s add a Square type now and see how interfaces can be used to make the Area call uniformly.

We now have a Square type also, and in a fashion similar to that of Rectangle, we are able to obtain its area. Let’s get similar output again, but using a loop which will give an indication how interfaces can produce cleaner, simpler, and more scalable code. In the below code we create an array of Shaper instances and then loop through them calling the Area function on each. Same effect as before, but now with improved possibilities.

18 comments:

Thanks for your poest, this help me how to use interface, but i still not sure when should I use it!!Can you show me more example that we need use innterface in my program.Let say in my web app, I have two main class that TOPIC (showing the post page) MEMBER (showing member info). I see they are the same as PAGE. They always have id, title with SetTiele, SetId method... so in this case PAGE should be an class or it should be an interface?