인터페이스 사용하기

이재홍 http://www.pyrasis.com 2014.12.17 ~ 2015.02.07

덕 타이핑

이렇게 각 값이나 인스턴스의 실제 타입은 상관하지 않고 구현된 메서드로만 타입을 판단하는 방식을 덕 타이핑(Duck typing)이라 합니다. 이 용어는 다음과 같은 덕 테스트(오리 테스트)에서 유래되었습니다.

“만약 어떤 새가 오리처럼 걷고, 헤엄치고, 꽥꽥거리는 소리를 낸다면 나는 그 새를 오리라 부르겠다.”

Go 언어로는 다음과 같이 덕 타이핑을 구현할 수 있습니다.

package main

import "fmt"

type Duck struct { // 오리(Duck) 구조체 정의
}

func (d Duck) quack() {     // 오리의 quack 메서드 정의
	fmt.Println("꽥~!") // 오리 울음 소리
}

func (d Duck) feathers() { // 오리의 feathers 메서드 정의
	fmt.Println("오리는 흰색과 회색 털을 가지고 있습니다.")
}

type Person struct { // 사람(Person) 구조체 정의
}

func (p Person) quack() {                           // 사람의 quack 메서드 정의
	fmt.Println("사람은 오리를 흉내냅니다. 꽥~!") // 사람이 오리 소리를 흉내냄
}

func (p Person) feathers() { // 사람의 feathers 메서드 정의
	fmt.Println("사람은 땅에서 깃털을 주워서 보여줍니다.")
}

type Quacker interface { // quack, feathers 메서드를 가지는 Quacker 인터페이스 정의
	quack()
	feathers()
}

func inTheForest(q Quacker) {
	q.quack()    // Quacker 인터페이스로 quack 메서드 호출
	q.feathers() // Quacker 인터페이스로 feathers 메서드 호출
}

func main() {
	var donald Duck // 오리 인스턴스 생성
	var john Person // 사람 인스턴스 생성

	inTheForest(donald) // 인터페이스를 통하여 오리의 quack, feather 메서드 호출
	inTheForest(john)   // 인터페이스를 통하여 사람의 quack, feather 메서드 호출
}

먼저 Duck, Person 구조체와 Quacker 인터페이스를 그림으로 표현하면 다음과 같습니다.


그림 32-2 Quacker 인터페이스

Quacker 인터페이스는 quack, feathers 함수를 정의하고 있습니다. 그리고 오리(Duck)와 사람(Person) 모두 quack, feathers 함수를 구현했습니다.

실제로 사용할 때는 다음과 같이 inTheForest 함수에서 Quacker 인터페이스를 매개변수로 받습니다. 여기에 오리든 사람이든 inTheForest 함수에 넣을 수 있으며 quack, feathers 메서드를 호출합니다. 오리는 진짜 “꽥~”하고 울것이고, 사람이라면 오리를 흉내내어 소리를 낼 것입니다.

func inTheForest(q Quacker) {
	q.quack()    // Quacker 인터페이스로 quack 메서드 호출
	q.feathers() // Quacker 인터페이스로 feathers 메서드 호출
}

func main() {
	var donald Duck // 오리 인스턴스 생성
	var john Person // 사람 인스턴스 생성

	inTheForest(donald) // 인터페이스를 통하여 오리의 quack, feather 메서드 호출
	inTheForest(john)   // 인터페이스를 통하여 사람의 quack, feather 메서드 호출
}

실행 결과

꽥~!
오리는 흰색과 회색 털을 가지고 있습니다.
사람은 오리를 흉내냅니다. 꽥~!
사람은 땅에서 깃털을 주워서 보여줍니다.

오리든 사람이든 상관없이 꽥(quack)과 깃털(feathers) 메서드만 가졌다면 모두 같은 인터페이스로 처리할 수 있습니다.

덕 타이핑
다른 언어로 작성된 덕 타이핑 예제코드는 다음 링크를 참조하기 바랍니다.

타입이 특정 인터페이스를 구현하는지 검사하려면 다음과 같이 사용합니다.

  • interface{}(인스턴스).(인터페이스)
var donald Duck

if v, ok := interface{}(donald).(Quacker); ok {
	fmt.Println(v, ok)
}

실행 결과

{} true

Duck 타입의 인스턴스 donald를 빈 인터페이스에 넣은 뒤 Quacker 인터페이스와 같은지 확인합니다. 첫 번째 리턴값은 검사했던 인스턴스이며 두 번째 리턴값은 인스턴스가 해당 인터페이스를 구현하고 있는지 여부입니다. 구현하고 있다면 true 그렇지 않으면 false입니다.


저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.

Published

01 June 2015