Interfaces & Methods - Composition in Go

Ashok VangaAshok Vanga
3 min read

In Go, Interfaces are named collections of method signatures. Similar to Java, you just declare methods Since there is no class in Go, we need to use "structs" Go does not support inheritance in its type system, but it supports composition of types

gophercises_j.gif

Let's see how to implement in the following

If you want to implement an interface into a struct type, you don’t need to explicitly implement the interface type along with the struct type definition. Instead, you just need to implement the methods defined in the interface into the struct type.

**Eg: Flow Diagram **

image.png

  1. Declare an interface type named “Loan” with method – emi()
type loan interface{
    emi() float32
}

Now define 2 structs named HosuingLoan , PersonalLoan to implement

type HousingLoan struct{

    principal float32
    roi float32
}


type PersonalLoan struct{
    principal float32
    roi float32
}

In Short we had first declared an interface type named “Loan” with a method - emi() . And We create a struct type HousingLoan and add method emi() .

  1. Next define the struct methods to implement emi()
HousingLoan method

func (h1 HousingLoan) emi() float32 {
    fmt.Println("emi method invokd for Housing Loan")
    return h1.principal + h1.roi
}
PersonaLoan Method

func (h1 PersonalLoan) emi() float32 {
    fmt.Println("emi method invoked for Personal loan")
    return h1.principal + h1.roi // here emi() will have differennt logic for hosuingloan and personla loan
}

Comparison In Java

public class HosingLoan implements Loan{
//implementations here
}

In Go, explicit declaration of interface implementation is not required

you just need to implement the methods defined in the interface into your struct type where you want to implement it.

This gives us a simplicity to building loosely-coupled systems.

type Loan interface {
    emi() float32
}

type HousingLoan struct {
    principal float32
    roi       float32
}

type PersonalLoan struct {
    principal float32
    roi       float32
}

func (h1 HousingLoan) emi() float32 {
    fmt.Println("emi method invokd for Housing Loan")
    return h1.principal + h1.principal*h1.roi
}

func (h1 PersonalLoan) emi() float32 {
    fmt.Println("emi method invoked for Personal loan")
    return h1.principal + h1.principal*h1.roi // here emi() will have differennt logic for hosuingloan and personla loan
}

func calculateEmi(l Loan) { // generic function "calculateEmi()" that takes a variable of *** "Loan" type***. it can housing or personal
    fmt.Println("Generic method is invoked")
    fmt.Println(l.emi())
}

// Now implement emi method on housingloan
func main() {

    fmt.Println("Welcome to Optum Bank")
    h1 := HousingLoan{principal: 100000, roi: 0.08}
    calculateEmi(h1)

    p1 := PersonalLoan{principal: 100000, roi: 0.15}
    calculateEmi(p1)
}

**Composition in Go **: Whenever one struct field is embedded in another, Go gives us the option to access the embedded fields

It helps to write re-usable segments of code. Larger objects with a wider functionality are embedded with smaller objects with specific behaviors. Ultimately the goal of composition is the same as that of inheritance, however, instead of inheriting features from a parent class/object, larger objects in this regard are composed of the other objects and can thereby use their functionality.

As the code majorly around using structs and interfaces, composition is a key to implement.

Implementation in below:

Composition gives the option to access the embedded fields as if they were part of the outer struct. In below b.person.fullName() is same as to b.fullName()

type person struct {
    firstName string
    lastName  string
    bio       string
}

func (a person) fullName() string {
    return fmt.Sprintf("%s %s", a.firstName, a.lastName)
}

type developer struct {
    designation string
    company     string
    person
}

func (b developer) details() {
    fmt.Println("designation: ", b.designation)
    fmt.Println("company: ", b.company)
    fmt.Println("person: ", b.fullName())
    fmt.Println("Bio: ", b.bio)
}

func main() {
    p1 := person{
        "Ashok",
        "V",
        "Gopher",
    }
    d1 := developer{
        "Solution Expert",
        "AVG Consulting",
        p1,
    }
    d1.details()
}

For More suggestions and interesting topics Contact me Email me at : askrv.chn@gmail.com

www.linkedin.com/in/ashokvanga

0
Subscribe to my newsletter

Read articles from Ashok Vanga directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ashok Vanga
Ashok Vanga

Golang Developer and Blockchain certified professional