Lets first define two types, circle and rectangle. Both types have the method area().
package main
import (
"fmt"
"math"
)
type circle struct {
radius float64
}
type triangle struct {
base float64
height float64
}
func (t triangle) area() float64 {
return 0.5 * t.base * t.height
}
func (c circle) area() float64 {
return math.Pi * c.radius * c.radius
}
func main() {
t := triangle{
base: 10.0,
height: 22.0,
}
c := circle{
radius: 10,
}
fmt.Printf("Triangle area = : %f\n", t.area())
fmt.Printf("Circle area = : %f", c.area())
}
In main() both objects t, c are created then the area() method is called on each.
What if we wanted to loop over those objects? We cannot create a slice as t, c are of different types, and a slice must contain objects of the same type. This is where interfaces come in.
We can define an interface shape as follows:
type shape interface {
area() float64
}
Now where ever we have a type that has an area() method we can say these types implement the interface. A better way to think of it -> think of the interface as a higher level type for, in this case, triangle and circle.
An interface then allows the following:
shapes := []shape{t, c}
for _, s := range shapes {
fmt.Println(s.area())
}
Extending this slightly, we can get to something like this -> the interface has been extended as have each of the types to include the getname() method. Then a slice of type shape is created, the objects are instantiated and then iterated over to get the object name and area.
package main
import (
"fmt"
"math"
)
type shape interface {
area() float64
getname() string
}
type circle struct {
radius float64
name string
}
type triangle struct {
base float64
height float64
name string
}
func (t triangle) area() float64 {
return 0.5 * t.base * t.height
}
func (t triangle) getname() string {
return t.name
}
func (c circle) area() float64 {
return math.Pi * c.radius * c.radius
}
func (c circle) getname() string {
return c.name
}
func main() {
shapes := []shape{
triangle{base: 10, height: 20, name: "my triangle"},
circle{radius: 10, name: "my circle"},
}
for _, s := range shapes {
fmt.Printf("%s has an area of %f\n", s.getname(), s.area())
}
}
And that’s it!
Leave a comment