기본적인 형태는 이와 같습니다.
type 인터페이스명 interface{
메서드1
메서드2
}
메서드 같은 경우에는 구현이 빠져있는 메서드들을 적게 됩니다.
Fly()
= 입력과 출력이 없는 메서드
, Walk(distance int) int
= 입력과 출력이 하나있는 메서드
type Stringer interface {
String() string
}
type Student struct {
Name string
Age int
}
func (s Student) String() string {
return fmt.Sprintf("안녕 나는 %d살, %s라고해", s.Age, s.Name)
}
func main() {
student := Student{"호진", 12}
var stringer Stringer
stringer = student
fmt.Printf("%s\n", stringer.String())
}
이런식으로 활용이 가능합니다.
student라는 변수를 Strudent라는 구조체를 통해서 만들어 줍니다.
이후 stringer이라는 인터페이스 변수를 만들어 주고 student를 할당합니다.
이후 인터페이스 안에 있는 메서드를 실행시켜줌으로써 작동시킬수 있습니다.
fmt.Sprintf는 해당 글을 string형태로 바꿔주는 역할을 수행합니다.
인터페이스또한 일종의 제약조건으로 인식했고 인터페이스 안에 들어가있지 않은 메서드는 인터페이스 변수에서 실행이 불가능 합니다.
func (s Student) GetAge() int {
return s.Age
}
func main() {
student := Student{"호진", 12}
var stringer Stringer
stringer = student
fmt.Printf("%s\n", stringer.String())
fmt.Printf("%d\n", student.GetAge())
fmt.Printf("%d\n", stringer.GetAge())
}
GetAge()
라는 메서드를 적어주지 않았기 떄문입니다.인터페이스를 사용해야 하는 이유
간단하게 말하면 코드르 변경할떄 좀더 편리하게 하기 위해서 사용을 합니다.
만약 A와 B택배 업체가 있습니다.
사용자는 A의 업체를 사용을 하지만
후에 B의 업체를 사용하는 것이 좀더 수익적으로 이익이 된다면
코드를 수정하여 B의 업체를 사용하게 됩니다.
이런 상황이 발생을 하였을떄 인터페이스를 사용하게 되면 좀더 원활하게 사용이 가능합니다.
- using.go
package main
import "test/post"
type Sender interface {
Send(parcel string)
}
func SendBook(name string, sender Sender) {
sender.Send(name)
}
func main() {
var sender Sender = &post.PostSender{}
SendBook("어린왕자", sender)
SendBook("test", sender)
}
-- fedex.go
package fedex
import "fmt"
type FedexSender struct {
// ...
}
func (f *FedexSender) Send(parcel string) {
fmt.Printf("Fedex sending... %s", parcel)
}
-- post.go
package post
import "fmt"
type PostSender struct {
}
func (k *PostSender) Send(parcel string) {
fmt.Printf("post sending... %s\n", parcel)
}
이론적으로 간단하게 적어보자면
인터페이스를 통해서 추상화기능을 제공할수 있고 이런 과정을 통해 서비스 제공자와, 사용자가 모두 자유롭게 사용을 할수 있는 기능을 제공할 수 있습니다.
인터페이스를 포함하는 인터페이스
type Reader interface{
Read()
Close()
}
type Writer interface{
Write()
Close()
}
type ReadWriter interface{
Reader
Writer
}
이런 형태로 인터페이스 안에 인터페이스를 선언한 경우를 말합니다.
이떄 ReadWriter
인터페이스가 사용할수 잇는 메서드는 Read()
, Close()
, Write()
가 됩니다.
빈 인터페이스
아무런 타입이 적혀있지 않은 인터페이스는 모든 부분에 적용이 가능하다는 의미 입니다.
func prinVal(v interface{}){
switch t := v.(type){
case int :
~~~
case float65:
~~~
}
}
func main(){
prinVal(10)
prinVal(20)
prinVal("hello")
}
이런식으로 빈 인터페이스를 인자로 줌으로써 활용이 가능합니다.