Table of contents
1.
Introduction
2.
Embedding interface in another interface
3.
Embedding interface in a struct
4.
Frequently Asked Questions
4.1.
What are embedded interfaces?
4.2.
What is embedding in Golang?
4.3.
What is polymorphism in Golang?
4.4.
What is dependency injection in Golang?
5.
Conclusion
Last Updated: Mar 27, 2024

Embedding Interfaces in Go

Author Aman Thakur
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

The Interface is a set of method signatures and a type in the Go programming language, which implies you can create a variable of an interface type.We already know that the Go language does not enable inheritance, but the Go interface does. An interface can incorporate other interfaces or the method signatures of other interfaces in it when embedding.

In addition to being embedded in another interface, an interface can also be embedded in a struct. Let's take a closer look at each one separately.

Embedding interface in another interface

Any number of interfaces can be contained in a single interface, and any interface can be embedded in another. The embedding interface inherits all of the embedded interface's methods. It's a method of combining several tiny interfaces to create a new one.Let’s understand it with an example

Imagine that we have an interface animal as below

type animal interface {
    breathe()
    walk()
}

 

Let's imagine there's a human interface that contains the animal interface.

type human interface {
    animal
    speak()
}

 

If a type has to implement a human interface, it must specify the animal interfaces' breathe() and walk() methods.

The animal is incorporated in the human interface's talk() function.

package main

import "fmt"

type animal interface {
    breathe()
    walk()
}

type human interface {
    animal
    speak()
}

type student struct {
    name string
}

func (e student) breathe() {
    fmt.Println("student breathes")
}

func (e student) walk() {
    fmt.Println("student walk")
}

func (e student) speak() {
    fmt.Println("student speaks")
}

func main() {
    var h human

    h = student{name: "Aman Thakur"}
    h.breathe()
    h.walk()
    h.speak()
}

Output

student breathes
student walk
student speaks

Embedding interface in a struct

struct can also have an interface incorporated in it.That struct may be used to invoke all of the embedded interface's functions.

We will see how these methods are called depends on whether the embedded interface is a named field or an unnamed/anonymous field.

1. If the embedded interface is a named field, the named interface name must be used to invoke interface methods.
2. Interface methods can be referenced to directly or via the interface name if the embedded interface is unnamed/anonymous.

 

Let’s see a program illustrating above points

package main

import "fmt"

type animal interface {
    breathe()
    walk()
}

type dog struct {
    age int
}

func (d dog) breathe() {
    fmt.Println("Dog breathes")
}

func (d dog) walk() {
    fmt.Println("Dog walk")
}

type pet1 struct {
    a    animal
    name string
}

type pet2 struct {
    animal
    name string
}

func main() {
    d := dog{age: 5}
    p1 := pet1{name: "Miko", a: d}

    fmt.Println(p1.name)
    // p1.breathe()
    // p1.walk()
    p1.a.breathe()
    p1.a.walk()

    p2 := pet2{name: "Rocky", animal: d}
    fmt.Println(p1.name)
    p2.breathe()
    p2.walk()
    p1.a.breathe()
    p1.a.walk()
}

Output

Miko
Dog breathes
Dod walk


Rocky
Dog breathes
Dog walk
Dog breathes
Dog walk

 

Pet1 and Pet2 are two structs we defined. The animal interface is named in the pet1 struct.

type pet1 struct {
    a    animal
    name string
}

 

pet2 has unnamed/anonymous animal interface embedded

type pet2 struct {
    animal
    name string
}

 

For an instance of pet1 struct we call the breathe() and walk() method like this

p1.a.breathe()
p1.a.walk()

 

Directly calling these methods with raise compilation error

// p1.breathe()
// p1.walk()

 

p1.breathe return undefined (type pet1 has no field or method breathe)

p1.walk return undefined (type pet1 has no field or method walk)

We may directly call the breathe() and walk() methods for a pet2 struct instance.

p2.breathe()
p2.walk()

 

We can directly access the methods of the embedded interface if the embedded interface is anonymous or unnamed.

Below is also valid and another way of called methods of unnamed/anonymous embedded interface

p2.animal.breathe()
p2.animal.walk()

 

Also, the embedded interface, i.e. animal, is initialised with a type implementing it, i.e. dog, when either the pet1 or pet2 struct is created.

p1 := pet1{name: "Miko", a: d}
p2 := pet2{name: "Rocky", animal: d}

 

If we don't initialise the embedded interface animal, it will be set to the interface's zero value, which is nil. Calling the breathe() and walk() methods on such a pet1 or pet2 struct instance will result in a panic.

Check out this article - Compile Time Polymorphism

Frequently Asked Questions

What are embedded interfaces?

The dynamic possibilities of embedded interfaces are the same as when the same interfaces are accessible via Tempo or sites. They vary from Tempo and sites in that they lack the surrounding navigation bar and backdrop, letting the host web page to offer its own navigation.

What is embedding in Golang?

Support for embedding files and directories into the programme binary at build time without the use of an external tool is one of the most eagerly awaited features of Go 1.16.

This functionality is also known as go:embed, and it takes its name from the compiler directive that enables it.

What is polymorphism in Golang?

Polymorphism refers to a message's ability to appear in several forms.Polymorphism is one of the most significant characteristics of Object-Oriented Programming, and it may be performed at runtime or at compile time.

What is dependency injection in Golang?

Dependency injection is a method that allows an item to receive dependencies from other objects. The receiving object is usually referred to as a client, whereas the passed-in ('injected') item is referred to as a service.

Conclusion

If you made till here, that means you enjoyed reading it. The article extensively covers the implementation of interface embedding in golang. You might be interested in articles such as Basic of Json with GolangRace condition in Golang and Function as a field in Golang.

Do upvote our blog to help other ninjas grow, and head over to our practice platform Coding Ninjas Studio to practise top problems, attempt mock tests, read interview experiences, and much more.

Happy Learning!

Live masterclass