Go 에서 인터페이스는 다른 언어에서와 마찬가지로 구현해야할 메소드 시그니처만 정의한다.
이때, 다른 모듈에서 사용할 메소드는 당연히 public 하게 만든다.
class 가 없는 대신, 이 인터페이스를 구현할 struct 를 정의한다.
type Person interface {
hello() string
}
interface 를 구현한 struct 예시를 들어보자.
마치 Java 에서 구체 클래스를 구현하는 형태와 유사하다.
다만 메소드 시그니처에 receiver 로 포인터를 받는다는점이 특징이다.
receiver 를 사용하는 순간 '함수'가 아니라 '메소드'가 된다.
즉, 자바의 클래스처럼 해당 struct의 상태관리를 직접 하겠다는 사인이 된다.
type American struct {
}
type Korean struct {
}
// 구현 메소드를 소문자로 정의하여 외부에서 직접 호출할 수 없다.
func (american *American) hello() string {
return "Hello my friend"
}
func (american *Korean) hello() string {
return "안녕하세요"
}
// Allow you writing functions that can work with many types.
// As long as those types implement the required methods.
func Greeting(person Person) string {
return person.hello()
}
인터페이스의 장점인 캡슐화를 보여주는 사례다.
Greeting()
을 호출할 순 있지만 Person interface의 hello()
구현을 들여다 볼 수는 없다.
즉, 구현체에 의존하지 않게하여 Dependency Injection도 가능하다.
그저 인터페이스에 명시된 모든 메소드를 struct 에서 구현하기만 하면된다.
implements
, extends
같은 키워드는 별도의 키워드도 필요없다.
func Test_Hello(t *testing.T) {
assert := assert2.New(t)
american := &interf.American{}
assert.Equal("Hello my friend", interf.Greeting(american))
korean := &interf.Korean{}
assert.Equal("안녕하세요", interf.Greeting(korean))
}