Reputation: 7210
I'm going through An Introduction to Programming in Go and trying to grasp interfaces. I feel like I have an ok idea of what they are and why we would need them but I'm having trouble using them. At the end of the section they have
Interfaces can also be used as fields:
type MultiShape struct { shapes []Shape }
We can even turn MultiShape itself into a Shape by giving it an area method:
func (m *MultiShape) area() float64 { var area float64 for _, s := range m.shapes { area += s.area() } return area }
Now a MultiShape can contain Circles, Rectangles or even other MultiShapes.
I don't know how to use this. My understanding of this is MultiShape
can have a Circle
and Rectangle
in it's slice
This is the example code I'm working with
package main
import ("fmt"; "math")
type Shape interface {
area() float64
}
type MultiShape struct {
shapes []Shape
}
func (m *MultiShape) area() float64 {
var area float64
for _, s := range m.shapes {
area += s.area()
}
return area
}
// ===============================================
// Rectangles
type Rectangle struct {
x1, y1, x2, y2 float64
}
func distance(x1, y1, x2, y2 float64) float64 {
a := x2 - x1
b := y2 - y1
return math.Sqrt(a*a + b*b)
}
func (r *Rectangle) area() float64 {
l := distance(r.x1, r.y1, r.x1, r.y2)
w := distance(r.x1, r.y1, r.x2, r.y1)
return l*w
}
// ===============================================
// Circles
type Circle struct {
x, y, r float64
}
func (c * Circle) area() float64 {
return math.Pi * c.r*c.r
}
// ===============================================
func totalArea(shapes ...Shape) float64 {
var area float64
for _, s := range shapes {
area += s.area()
}
return area
}
func main() {
c := Circle{0,0,5}
fmt.Println(c.area())
r := Rectangle{0, 0, 10, 10}
fmt.Println(r.area())
fmt.Println(totalArea(&r, &c))
//~ This doesn't work but this is my understanding of it
//~ m := []MultiShape{c, r}
//~ fmt.Println(totalArea(&m))
}
Can someone help me with this? I have a python background so if there is some kind of link between the two that would help.
Thanks
Upvotes: 2
Views: 269
Reputation: 166529
For example,
package main
import (
"fmt"
"math"
)
type Shape interface {
area() float64
}
type MultiShape struct {
shapes []Shape
}
func (m *MultiShape) area() float64 {
var area float64
for _, s := range m.shapes {
area += s.area()
}
return area
}
type Rectangle struct {
x1, y1, x2, y2 float64
}
func (s *Rectangle) area() float64 {
x := math.Abs(s.x2 - s.x1)
y := math.Abs(s.y2 - s.y1)
return x * y
}
func (s *Rectangle) distance() float64 {
x := s.x2 - s.x1
y := s.y2 - s.y1
return math.Sqrt(x*x + y*y)
}
type Circle struct {
x, y, r float64
}
func (s *Circle) area() float64 {
return math.Pi * s.r * s.r
}
func main() {
r1 := Rectangle{1, 1, 4, 4}
fmt.Println(r1.area())
r2 := Rectangle{2, 4, 3, 6}
fmt.Println(r2.area())
c := Circle{10, 10, 2}
fmt.Println(c.area())
m := MultiShape{[]Shape{&r1, &r2, &c}}
fmt.Println(m.area())
}
Output:
9
2
12.566370614359172
23.566370614359172
Upvotes: 3