더북(TheBook)

메서드 오버라이딩

임베디드 필드에 정의된 메서드를 오버라이딩(Overriding)할 수도 있다.

func (t DiscountItem) Cost() float64 {
    return t.Item.Cost() * (1.0 - t.discountRate/100)
}
 
func main() {
    shoes := Item{"Women's Walking Shoes", 30000, 2}
    eventShoes := DiscountItem{
        Item{"Sports Shoes", 50000, 3},
        10.00,
    }
           
    fmt.Println(shoes.Cost())           // 60000
    fmt.Println(eventShoes.Cost())      // 135000
    fmt.Println(eventShoes.Item.Cost()) // 150000
}

Item 타입에 정의된 Cost() 메서드와 이름이 같은 메서드를 DiscountItem 타입에 추가했다. 이로써 ItemCost() 메서드는 오버라이딩되었다. DiscountItemCost() 메서드에서 t.Item.Cost()ItemCost() 메서드를 사용한다. 물론 eventShoes.Item.Cost()처럼 ItemCost() 메서드를 직접 호출할 수도 있다.

 

Note 오버로딩(Overloading)

Go는 이름이 같은 메서드를 생성할 수 없다. 즉, 오버로딩(이름은 같지만 매개변수가 다른 메서드)을 지원하지 않는다. 매개변수가 다르면 메서드 이름도 다르게 지정해야 한다.

예를 들어 기본 라이브러리에 있는 strings.Reader 타입은 매개변수에 따라 다른 메서드 세 개를 제공한다.

func (r *Reader) Read(b []byte) (n int, err error)
func (r *Reader) ReadByte() (b byte, err error)
func (r *Reader) ReadRune() (ch rune, size int, err error)

메서드의 매개변수 타입 앞에 생략 부호(...)를 표기하여 가변 인자로 정의하면 오버로딩과 유사한 효과를 줄 수 있다.

func main() {
    shoes := Item{"Women's Walking Shoes", 30000, 2}
    eventShoes := DiscountItem{
        Item{"Sports Shoes", 50000, 3},
        10.00,
    }
    display(shoes.name)
    display(shoes.name, eventShoes.name)
}
 
func display(values ...string) {
    for i := 0; i < len(values); i++ {
        fmt.Println(values[i])
    }
}
신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.