Golang Interfaces
What is the interface in OOP?
An interface defines the behavior of an object. It only specifies what the object is supposed to do. It is actually a concept of abstraction and encapsulation. see here.
- Abstraction is selecting data from a larger pool to show only the relevant details to the object. It helps to reduce programming complexity and effort.
- Encapsulation describes the idea of bundling data and methods that work on that data within one unit, e.g., a class in Java.
Interfaces in Golang
In Go, an interface is a set of method signatures. And all methods defined then we should say that the interface is implemented. An interface specifies what methods a type should have and the type decides how to implement these methods.
The interface required all methods should get implemented otherwise program gets panic.
The interface is abstract, so you are not allowed to create an instance of the interface.
Real-life example of the interface is like LivingCreature is an abstract interface where the walk can be a method to be implemented. So man and dog can be walked with 2 and 4 legs. So simply structure for an interface is like below.
package mainimport (
"fmt"
"strconv"
)// LivingCreature ...
type LivingCreature interface {
Walk() string
}// Man ...
type Man struct {
Legs int
}// Dog ...
type Dog struct {
Legs int
}// Walk ...
func (m *Man) Walk() string {
return "Man walked on " + strconv.Itoa(m.Legs) + " legs"
}// Walk ..
func (d *Dog) Walk() string {
return "Dog walked on " + strconv.Itoa(d.Legs) + " legs"
}// func main
func main() {
man := Man{
Legs: 2,
}
fmt.Println("Man ==", man.Walk())
fmt.Println("---------------------------------")
dog := Dog{
Legs: 4,
}
fmt.Println("Dog ==", dog.Walk())
}
In the above example, Man and Dog are two structs that implement the interface LivingCreature. So you can see the output as the man walked on 2 legs and the dog walked on 4 legs. So different struct uses the same abstract structure called LivingCreature interface.
Empty Interfaces
Interfaces with no methods call an empty interface. It is written like interface{}. Since the empty interface has zero methods, all types implement the empty interface. So you can assign any type of variable to an empty interface.
package mainimport (
"fmt"
)// CaptureValue ...
func CaptureValue(i interface{}) {
fmt.Println(i)
}// func main
func main() {
CaptureValue("Mayur")
CaptureValue(50)
data := struct {
name string
}{
name: "Mayur",
}
CaptureValue(data)
}
In above code many different types of data (string, int and struct type variables) given to interface.
Type Assertion
Type assertion is nothing but identifying the value of an interface. i.(type) is a simple syntax to identify the type.
package mainimport (
"fmt"
)// getType ...
func getType(i interface{}) {
v, ok := i.(int)
fmt.Println(v, ok)
}// func main ...
func main() {
var s interface{} = 100
getType(s)
}
In above code v, ok := i.(int) checks whether given value is int or not. v reprsents value of a variable and ok represents bool value i.e. If that value is int then ok is true else false.
Embedding Interfaces
Go does not offer inheritance, But it is possible to create a new interface by embedding interfaces to a new interface. Let's see the program.
package mainimport "fmt"// AttendanceCalculator ...type AttendanceCalculator interface {Calculate()}// DisplayAttendance ...type DisplayAttendance interface {DisplayAttendancePercentage()}// StudentOperations ...type StudentOperations interface {AttendanceCalculatorDisplayAttendance}// Student ...type Student struct {Name stringAttendanceDays intAttendancePercentage float32}// DisplayAttendancePercentage ...func (s *Student) DisplayAttendancePercentage() {fmt.Println(s.Name, " has", s.AttendancePercentage, "% attendance")}// Calculate ...func (s *Student) Calculate() {// forget about formula it uses just for purposes.AttendancePercentage = float32(s.AttendanceDays*30) / float32(100)}func main() {s := Student{Name: "Mayur",AttendanceDays: 24,}s.Calculate()s.DisplayAttendancePercentage()}
In the above code, Simple two interfaces are embedded into another struct called StudentOperations. And those methods from both interfaces are not accessible and implemented by StudentOperations interface.
You can download the source code from my Github page.
Hope you’ve enjoyed reading :)