Interfaces & Methods - Composition in Go
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
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 **
- 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() .
- 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