Skip to main content
  1. Posts/

How to Do Encapsulation, Abstraction, Inheritance, Polymorphism, Classes, and Interfaces in Golang

·635 words·3 mins
nenjo.tech
Author
nenjo.tech
I’m a developer specializing in trading and AI automation — helping traders turn ideas into Expert Advisor, Pine Script, Python, or Go bots with smart, production-ready workflows.

Understanding OOP concepts in Go is a great way to write clearer, safer, and more reusable code. Golang takes a different approach to Object Oriented Programming (OOP) compared to classical OOP languages like Java or C#. It does not have traditional classes or inheritance but achieves the same principles through structs, interfaces, composition, and embedding. This post explores how to implement the core OOP principles and use classes and interfaces idiomatically in Go.

landscape
Photos by nenjo

Classes and Structs in Go
#

In Go, the closest equivalent to a class is a struct.

  • A struct is a composite data type that groups together fields.
  • Methods can be added to structs, giving them behaviors.
  • Go does not have constructors like other languages; instead, constructors are typically factory functions returning initialized structs.

Example:

type Person struct {
    Name string
    age  int // unexported field
}

func NewPerson(name string, age int) *Person {
    return &Person{Name: name, age: age}
}

func (p *Person) GetAge() int {
    return p.age
}

Interfaces in Go
#

Interfaces in Go define a set of method signatures but do not implement them. Unlike Java or C#, Go interfaces are implemented implicitly:

  • If a struct has all the methods in an interface, it automatically implements that interface without any explicit declaration.
  • This makes interfaces extremely flexible and decouples implementations from definitions.

Example:

type Speaker interface {
    Speak() string
}

func Greet(s Speaker) {
    fmt.Println(s.Speak())
}

type Dog struct {
    Name string
}

func (d Dog) Speak() string {
    return d.Name + " says Woof"
}

The Dog struct implicitly implements the Speaker interface because it has a Speak() method.

Encapsulation
#

Go uses exported and unexported fields and methods to enforce encapsulation:

  • Capitalized names are exported (public).
  • Lowercase names are unexported (private to the package). You control access by exposing or hiding struct fields and providing getter/setter methods.
type Account struct {
    Owner   string
    balance float64 // unexported
}

func (a *Account) Deposit(amount float64) {
    if amount > 0 {
        a.balance += amount
    }
}

func (a *Account) Balance() float64 {
    return a.balance
}

Abstraction
#

Abstraction in Go is achieved via interfaces, exposing only what is necessary:

  • Consumers work with interfaces, not concrete types.
  • This hides implementation details and promotes loose coupling.
type Database interface {
    Save(data string) error
}

func Store(db Database, data string) error {
    return db.Save(data)
}

Any type implementing Save adheres to Database, abstracting away its details.

Inheritance (Composition & Embedding)
#

Go does not support traditional class inheritance. Instead, it encourages composition through embedding:

  • Embed structs to reuse fields and methods.
  • Promotes a “has-a” relationship rather than “is-a.”
type Animal struct {
    Name string
}

func (a Animal) Speak() string {
    return a.Name + " makes a sound"
}

type Dog struct {
    Animal // embedded struct
}

func (d Dog) Speak() string {
    return d.Name + " says Woof"
}

Dog embeds Animal and can override methods to customize behavior.

Polymorphism
#

Polymorphism happens with interfaces:

  • Different types can be treated uniformly if they implement the same interface.
  • Go’s implicit interface satisfaction reduces boilerplate.
func MakeItSpeak(s Speaker) {
    fmt.Println(s.Speak())
}

MakeItSpeak(Dog{Name: "Buddy"})
MakeItSpeak(Cat{Name: "Kitty"})

Summary Table: Go OOP Features vs Classical OOP
#

ConceptClassical OOPGo’s ApproachNotes
ClassClass keywordStructStructs with methods
InterfaceExplicit implementsImplicit implementationVery flexible and decoupled
Encapsulationprivate/public specifierExported/unexported based on capitalizationPackage-level visibility
AbstractionAbstract classes, interfacesInterfacesInterfaces to hide implementation details
InheritanceClass inheritanceComposition and embeddingPromotes composition over inheritance
PolymorphismInheritance + interfacesInterfacesInterface-based polymorphism

Final thoughts
#

While Go’s approach differs from traditional OOP languages, it embraces the core OOP principles effectively but encourages simplicity and composition. Understanding structs as “classes” and interfaces as contracts, combined with embedding, will help you build idiomatic Go applications that are clean, maintainable, and extensible.