DEV Community

DIWAKARKASHYAP
DIWAKARKASHYAP

Posted on

Interfaces and Embedding in Golang (Go)

1. Interfaces in Go:

1.1. What are Interfaces?

In Go, an interface is a type that specifies a set of method signatures. When a concrete type provides definitions for all the methods in an interface, it is said to implement the interface.

1.2. Defining Interfaces:

You define an interface using the type keyword followed by the interface name and the interface keyword:

type Writer interface {
    Write([]byte) (int, error)
}
Enter fullscreen mode Exit fullscreen mode

1.3. Significance in Go's Type System:

Interfaces in Go allow you to:

  • Define behavior that types should fulfill.
  • Enable polymorphic behavior. You can write functions and methods that accept interface types, and then pass values of any concrete type that satisfies the interface.
  • Provide a way to define contracts. If a type implements an interface, it guarantees certain methods with defined signatures are present in the type.

1.4. Interface Values:

Interface values can hold any value that implements the specified methods. An interface value has two components: a value and a concrete type. When we call a method on an interface value, the method of its underlying type is executed.

var w Writer
w = os.Stdout
w.Write([]byte("Hello, Go!\n"))
Enter fullscreen mode Exit fullscreen mode

In the above example, os.Stdout implements the Writer interface, so we can assign it to the w variable. When we call w.Write, it calls os.Stdout.Write.

2. Embedding in Go:

2.1. What is Embedding?

Embedding allows one struct type to include another struct, inheriting the fields and methods of the embedded type. It is Go's mechanism to achieve composition over traditional inheritance.

2.2. How to Embed:

To embed a type, you declare a field in the struct without a field name, just the type:

type Address struct {
    Street, City, State string
}

type Person struct {
    Name string
    Address
}

p := Person{
    Name:    "Alice",
    Address: Address{"123 Main St", "Anytown", "CA"},
}
fmt.Println(p.Street)  // Output: 123 Main St
Enter fullscreen mode Exit fullscreen mode

In the above code, Person embeds Address. This means that a Person not only has a Name but also has Street, City, and State due to the embedded Address.

2.3. Inheritance-like Behavior:

Embedding provides a way to "inherit" methods. If the embedded type has methods, the embedding type will have those methods too, provided it doesn't define its own methods with the same name.

func (a Address) FullAddress() string {
    return a.Street + ", " + a.City + ", " + a.State
}

// Even though Person doesn't define FullAddress, it gains the method through embedding Address.
address := p.FullAddress()
Enter fullscreen mode Exit fullscreen mode

However, Go doesn't support classical inheritance where you can extend and override base class methods. Instead, Go promotes composition over inheritance, making systems easier to understand and maintain.

To summarize:

  • Interfaces in Go allow types to adhere to contracts and enable polymorphism.
  • Embedding allows structs to inherit fields and methods from other structs, giving a mechanism for composition over classical inheritance.

Thank you for reading. I encourage you to follow me on Twitter where I regularly share content about JavaScript and React, as well as contribute to open-source projects and learning golang. I am currently seeking a remote job or internship.

Twitter: https://twitter.com/Diwakar_766

GitHub: https://github.com/DIWAKARKASHYAP

Portfolio: https://diwakar-portfolio.vercel.app/

Top comments (0)