DEV Community

Aneesh Makala
Aneesh Makala

Posted on

7 3

Golang for Object Oriented People

To start off with, in golang, there are no classes, only structs.

To add fuel to the fire, there is no type hierarchy, (i.e. no inheritance). This is probably the biggest difference as compared to other object oriented languages. Actually, it can't be truly considered an object-oriented language.

Ok, let's talk about type hierarchy.

Not having a type hierarchy was an intentional design choice in golang. Type hierarchies result in brittle code. The hierarchy must be designed early, often as the first step of designing the program, and early decisions can be difficult to change once the program is written. As a consequence, the model encourages early overdesign as the programmer tries to predict every possible use the software might require, adding layers of type and abstraction just in case. This is upside down. The way pieces of a system interact should adapt as it grows, not be fixed at the dawn of time. - Source

Let's take a quick look at type embedding. At first, it seems to be a mechanism for implementing inheritance, but upon close inspection, it becomes clear that it is not. It's simply a tool to borrow pieces of an implementation.

For example, take a look at the below code:

type Animal struct {
   Name string
}

type Dog struct{
   Animal
}

// Firstly, you can't just instantiate a Dog struct by
// passing in the field "Name".
//     d := Dog{Name:"dog"}

// This is the proper way to instantiate a Dog struct
d := Dog{Animal: Animal{Name: "dog"}}

// Next, you might want to employ polymorphism by
// creating a variable of type Animal, 
// and assigning the dog struct to it.
// Again, doesn't work. Just because you "embedded" 
// the Animal struct inside the Dog struct 
// doesn't create a type hierarchy.
//     var a Animal;
//     a = Dog{Animal : Animal{Name:"dog"}}

Enter fullscreen mode Exit fullscreen mode

It's clear that embedding doesn't create a type hierarchy. Note that you can still access the Name field by doing d.Name. That's because embedded fields and methods are "promoted" to the outer struct.

Ok, so if there is no type hierarchy, embedding seems like it creates one, but doesn't, how do you then group structs together to represent an abstraction? For example, how do you group together a cat and a dog as an "Animal" abstraction as you would in other OOP languages by creating an Animal super class and a Cat, Dog subclass?

Answer: You group structs not by their type, but by their behavior, i.e. interfaces.

Interfaces

An interface is just a set of methods. Any type that implements these methods satisfies this interface implicitly. The idea is that you can create an abstraction of different concrete type values and work with the values through their common behavior, without having to define a type hierarchy. Here's a nice example that explains how.

Further, Interfaces allow you to embody the dependency inversion principle. It is a recommended practice in go to accept interfaces and return structs. This way your code depends on abstractions rather than concrete implementations.

Unlike interfaces in other languages, rather than declaring the interface in the package where you're implementing a concrete type that satisfies that interface, it is recommended to declare interfaces in the package where you're using that interface.

It's an interesting and fundamental shift in how programmers
should think - You group structs not by their type, but by their behavior.

Sure, but every OOP language has interfaces. How do I reuse code in golang?

Composition over inheritance

You reuse code in golang using embedding and composition. There's a famous principle in object-oriented programming to favour composition over inheritance.
Here's a nice article that describes how go embodies that principle.

Neon image

Build better on Postgres with AI-Assisted Development Practices

Compare top AI coding tools like Cursor and Windsurf with Neon's database integration. Generate synthetic data and manage databases with natural language.

Read more →

Top comments (0)

Neon image

Set up a Neon project in seconds and connect from a Go application

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Get started →

👋 Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay