GoLang provides us a type called Interface type, which specifies a method set called its interface. Any type whose method set is a superset of the interface is said to implement the interface. So lets learn to use interfaces in Go.
You must be familiar with the interface keyword from Object-Oriented Language. The concept is the same, but its intended use in Go is different from how we have been using interfaces in our Object-Oriented languages like Java, C# and more. So before we deep dive into interfaces, lets clear up some concepts.
Is Go an Object Oriented language?
Yes and No. We can use Object oriented concepts in Go, but it’s not really intended to be used as an Object-Oriented language. From official go docs
Yes and no. Although Go has types and methods and allows an object-oriented style of programming, there is no type hierarchy. The concept of “interface” in Go provides a different approach that we believe is easy to use and in some ways more general. There are also ways to embed types in other types to provide something analogous—but not identical—to subclassing. Moreover, methods in Go are more general than in C++ or Java: they can be defined for any sort of data, even built-in types such as plain, “unboxed” integers. They are not restricted to structs (classes).
Also, the lack of a type hierarchy makes “objects” in Go feel much more lightweight than in languages such as C++ or Java.
How’s interfaces in Go are different from other Object Oriented languages?
From offical go lang docs
Object-oriented programming, at least in the best-known languages, involves too much discussion of the relationships between types, relationships that often could be derived automatically. Go takes a different approach.
Rather than requiring the programmer to declare ahead of time that two types are related, in Go a type automatically satisfies any interface that specifies a subset of its methods. Besides reducing the bookkeeping, this approach has real advantages …
How to declare interfaces in Go?
An interface is a type just like struct e.g
Above is an example of
So how’s that different from Object-Oriented languages?
The difference lies in two key things
Let’s see an example of how inbuilt os/file implements the inbuilt Closer interface.
That’s it! We don’t have to explicitly define that File implements Closer interface. So, if any method of a struct has the
Okay, that’s fine, but what advantages do interfaces in Go have over Object–oriented interface?
From the top view, it seems like the same thing but Go interface gives us a lot more flexibility. Let’s understand it with an example.
Let’s say we want to close the file and if there is an error, log it
We can write a method like
So, this method closes the file and logs the error. As a general thumb rule in Go, your method should accept an interface and return a struct. In our case, we are not returning anything. We can call this method as
Focus here on defer Close(r). Now, let’s modify this Close
So without any change, our main function will run since file implements Closer interface. But now lets make this method more interesting.
Let’s say you are establishing a connection to the database and when you are done, you want to close that connection. So we are talking about the package database/
That means I can do something like
Note: defer Close(db) and Close (associated with *DB) both are different methods. defer Close() is a custom method that we created above that accepts Closer interface as an argument
Focus on defer Close(
Go provides Flexibility
As these structs were defined before writing out the
Now we want to close this fake Resource also when we are done. So why don’t we take advantage of our Close
Now, out FakeResource type implements Closer. Now I can pass the value of FakeResource in the Close method to close it. So that’s what
Rather than requiring the programmer to declare ahead of time that two types are related, in Go a type automatically satisfies any interface that specifies a subset of its methods
This gives us a lot more flexibililty than conventional Object Oriented interfaces.
Difference in thinking philosophy
While using interfaces in Go, the design philosophy is different as that from conventional
We have a struct Square, and we have a method area defined.
Now lets say we want to have a method that will double the area of the square as under
We can call the above as
Now lets say we have one more requirement. We have one more struct rectangle and we need to find the double of Area for rectangle also. So we can create one interface here. I have named it Arear
So whole program will be like
Notice how we create interface Arear when needed. We didn’t think before about creating interface, but as when required
You can also run this example in go playground https://play.golang.org/p/pQIpBjzoCXV
There are some further readings that I recommend