Go > Structs and Interfaces > Interfaces > Defining interfaces
Defining and Implementing Interfaces in Go
This example demonstrates how to define and implement interfaces in Go. Interfaces define a set of methods that a type must implement to satisfy the interface. This promotes polymorphism and code reusability.
Defining an Interface
This code defines an interface called Shape
with two methods: Area()
and Perimeter()
. The Rectangle
and Circle
structs both implement the Shape
interface by providing implementations for the Area()
and Perimeter()
methods. The printShapeInfo
function accepts any type that implements the Shape
interface, demonstrating polymorphism.
package main
import "fmt"
// Shape interface defines the methods that a shape must implement.
type Shape interface {
Area() float64
Perimeter() float64
}
// Rectangle struct
type Rectangle struct {
Width float64
Height float64
}
// Circle struct
type Circle struct {
Radius float64
}
// Area method for Rectangle
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
// Perimeter method for Rectangle
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Height)
}
// Area method for Circle
func (c Circle) Area() float64 {
return 3.14159 * c.Radius * c.Radius
}
// Perimeter method for Circle
func (c Circle) Perimeter() float64 {
return 2 * 3.14159 * c.Radius
}
// Function that takes a Shape interface as an argument
func printShapeInfo(s Shape) {
fmt.Printf("Area: %.2f\n", s.Area())
fmt.Printf("Perimeter: %.2f\n", s.Perimeter())
}
func main() {
rect := Rectangle{Width: 5, Height: 10}
circ := Circle{Radius: 7}
printShapeInfo(rect)
printShapeInfo(circ)
}
Concepts Behind the Snippet
The core concepts here are interfaces and polymorphism. An interface defines a contract that types can fulfill. Polymorphism allows you to write code that works with any type that satisfies a given interface, without knowing the specific type at compile time. Go uses implicit interface satisfaction, meaning that a type automatically implements an interface if it defines all of the interface's methods.
Real-Life Use Case
Imagine you are building a system for processing different types of documents (e.g., PDFs, Word documents, text files). You could define an interface called Document
with methods like Parse()
, Validate()
, and ExtractText()
. Each specific document type would then implement the Document
interface, allowing your system to process any document type in a uniform way.
Best Practices
Interview Tip
Be prepared to explain the difference between interfaces and structs. Also, be ready to discuss the benefits of using interfaces for achieving loose coupling and testability. Understanding the concept of implicit interface satisfaction is crucial.
When to Use Them
Use interfaces when you want to:
Memory Footprint
Interfaces themselves have a small memory footprint. They typically consist of two words: one for the type information and one for the value. However, the memory footprint of the underlying concrete type will depend on its own structure.
Alternatives
While interfaces are the primary mechanism for abstraction in Go, you could potentially use type assertions or type switches in some limited scenarios. However, these approaches are generally less flexible and maintainable than using interfaces.
Pros
Cons
FAQ
-
What is implicit interface satisfaction?
In Go, a type automatically satisfies an interface if it implements all of the methods defined by the interface. There is no explicit declaration required. -
Can a struct implement multiple interfaces?
Yes, a struct can implement multiple interfaces. It simply needs to implement all of the methods defined by each interface. -
What happens if a struct only implements some of the methods of an interface?
The struct will not be considered to implement the interface. You will get a compile-time error if you try to use it as a value of that interface type.