BudiBadu Logo

Samplebadu

Code with Example
BudiBadu Logo
Samplebadu

Go by Example: Interfaces

Go 1.23

Explore Interfaces in Go, a powerful tool for defining behavior and achieving polymorphism. This example shows how to define interfaces, implement them implicitly with structs, and write flexible code that accepts any type satisfying an interface.

Code

package main

import "fmt"
import "math"

// Define interface
type geometry interface {
    area() float64
    perim() float64
}

// Implement on rect
type rect struct {
    width, height float64
}
func (r rect) area() float64 {
    return r.width * r.height
}
func (r rect) perim() float64 {
    return 2*r.width + 2*r.height
}

// Implement on circle
type circle struct {
    radius float64
}
func (c circle) area() float64 {
    return math.Pi * c.radius * c.radius
}
func (c circle) perim() float64 {
    return 2 * math.Pi * c.radius
}

// Generic function using interface
func measure(g geometry) {
    fmt.Println(g)
    fmt.Println(g.area())
    fmt.Println(g.perim())
}

func main() {
    r := rect{width: 3, height: 4}
    c := circle{radius: 5}

    measure(r)
    measure(c)
}

Explanation

Interfaces in Go are named collections of method signatures that define behavior without specifying how that behavior is implemented. Unlike many object-oriented languages, Go uses implicit interface satisfaction—a type automatically implements an interface simply by implementing all of its methods. There's no explicit implements keyword or inheritance declaration. This design promotes loose coupling and makes code more flexible and testable.

This implicit implementation is one of Go's most powerful features for achieving polymorphism and abstraction. You can write functions that accept interface types, and they'll work seamlessly with any concrete type that happens to implement the required methods. The compiler checks interface satisfaction at compile time, catching mismatches early.

  • Contract of Behavior: Interfaces define what a type can do, not what it is.
  • Implicit Satisfaction: Types implement interfaces automatically by implementing their methods.
  • Polymorphism: Code can be written to work with any type that satisfies an interface.
  • Empty Interface: interface{} (or any) has no methods and is satisfied by all types.

In the example, both rect and circle implement the geometry interface because they both provide area() and perim() methods with matching signatures. The measure function accepts any geometry value, demonstrating polymorphism.

Code Breakdown

7-10
Defining the "geometry" interface. Any type that has both area() and perim() methods returning float64 automatically satisfies this interface.
16-21
Implementing the interface methods for the "rect" struct. Note that we don't declare that rect implements geometry; it just happens automatically.
35-39
A function that accepts the geometry interface. It can call area() and perim() on "g" without knowing if "g" is a rectangle or a circle.
45-46
Passing both "rect" and "circle" instances to the measure function. Go checks at compile time that both types satisfy the geometry interface.