go언어에도 인터페이스(interface)를 제공합니다.


interface를 사용하면 객체가 서로 달라도 같은 이름의 메소드를 호출할 수 있습니다.

예를 들어 보겠습니다. 원(Circle) 객체를 생성하고 면적을 구하는 area() 메소드를 추가하겠습니다.


type Circle struct {
    x, y, r float64
}

func (c *Circle) area() float64 {
    return math.Pi * c.r*c.r
}


좌표 x, y에서 지름 r인 원에 대한 면적을 구하는 area() 메소드를 추가했습니다.


이번에는 사각형을 만들겠습니다.


type Rectangle struct {
    lft, top, rht, btm float64
}

func (r *Rectangle) area() float64 {
    return ( r.rht -r.btm) * ( r.btm -r.top)
}


좌표 lft, top, rht, btm 사각형에 역시 면적을 구하는 area() 메소드를 추가해서 만들었습니다.


원과 사각형의 객체는 속성은 달라도 면적을 구하는 같은 이름의 area() 메소드를 가지고 있습니다.


여기서 어떤 함수가 원이든 사각형이든 인수로 넣어 주면 모든 면적을 구해주는 함수를 만들려면 어떻게 해야할까요?


우선 원이든 사각형이든 이라는 명제에 주의해야겠습니다. 어떤 함수든 인수에 대해서는 정확한 형(Type)을

지정해 주어야 합니다. 즉, Circle를 받다가 Rectangle를 받을 수 있는 변수를 만들어야 하는데

어떻게 해야할까요? 


func(  obj Rectangle Circle)) 이런 식으로 해야할까요? 당연히 안 되지요. 그래서 나온 것이 interface입니다.

Rectangle와 Circle을 받을 수 있는 interface를 생성해 보겠습니다.


type Shape interface {
    area() float64
}


이 interface에는 공통 메소드 area()를 가지고 있다는 것에 주목해 주십시오.


func totalArea(shapes ... Shape) float64 {
    var area float64
    for _, s := range shapes {
        area += s.area()
    }
    return area
}


그리고 Shape 인터페이스를 인수로 받는 함수를 만들었습니다. 어떻습니까? 자연스러운 모습이죠?

이제 Rectangle이든 Circle을 전송해 주면 됩니다.


func main(){
   c := Circle{ 100, 100, 50}
   r := Rectangle{ 0, 0, 100, 50};
   fmt.Println( totalArea( &c, &r))

}


main() 함수를 실행하면 인수로 전달한 Rectangle과 Circle의 전체 면적이 화면에 출력됩니다.