Study Memory Work
[Go Lang] 인터페이스 본문
인터페이스
- 객체의 동작을 표현, 골격
- 단순히 동작에 대한 방법만 표기
- 추상화 제공
- 인터페이스의 메소드를 구현한 타입은 이터페이스로 사용 가능
- Go 언어를 유연하게 사용 가능
- 덕타이핑 : Go언어의 독창적인 특성
- 인터페이스를 왜 사용하는지??
-> 자바의(전략패턴, 템플릿메소드, 팩토리메소드패턴, 어댑터패턴 .....) 디자인 패턴 측면에서볼 때,
메소드를 호출하는 클라이언트 입장에서 사용하는 메소드의 구체적인 클래스를 몰라도
인터페이스에 정의된 메소드를 사용하는 객체 보장.
클래스의 수정이 일어나도 메소드를 따로 수정할 필요 없음.
==> 클래스 간의 결합도를 낮춰줌 -> 유지보수 용이, 추가개발 용이, 독립적인 프로그래밍 가능
인터페이스 선언 기본
type 인터페이스명 interface {
메소드1() 반환 값(타입 형)
메소드2() //반환 값 없을 경우
}
package main
import "fmt"
type test interface{} // 빈 인터페이스
func main() {
var t test
fmt.Println("ex : ", t)
}
ex : <nil> |
인터페이스 사용 기본
package main
import "fmt"
type Dog1 struct {
name string
weight int
}
// Behavier1 인터페이스의 bite() 메소드를 Dog1구조체릐 리시버 메소드로 구현
func (d Dog1) bite() {
fmt.Println(d.name, "bites!")
}
// 행동 인터페이스
type Behavier1 interface {
bite()
}
func main() {
dog1 := Dog1{"poll", 10}
// 방법 1
var inter1 Behavier1
inter1 = dog1 // 인터페이스에 인스턴스 대입
inter1.bite()
// 방법 2
dog2 := Dog1{"marry", 7}
inter2 := Behavier1(dog2) // 많이쓰이는 방법
inter2.bite()
// 복수개 초기화 사용 방법
// slice 타입 interface
inters := []Behavier1{dog1, dog2}
for _, i := range inters {
fmt.Printf(" > ")
i.bite()
}
}
덕타이핑
- 인터페이스에정의된 메소드 사용 유도
- 코드의 가독성 및 유지보수 증가
- 덕타이핑 : 구조체 및 변수의 값이나 타입은 상관하지 않고 오로지 구현된 메소드로만 판단하는 방식.
- Go의 독보적이고 중요한 덕타이핑 특징 : 오리랑 같은 메소드(인터페이스)를 구현하여 사용할 수 있다면 다 오리다...!
- A, B 구조체가 C인터페이스의 모든 메소드를 리시버메소드로 가지고 있다면, A,B는 C이다!! 가 성립.
자동형변환 되어 C 인터페이스를 받는 모든 곳에 쓰일 수 있다.
package main
import "fmt"
// Dog, Cat 구조체 선언
type Dog2 struct {
name string
weight int
}
type Cat struct {
name string
weight int
}
// Dog 리시버메소드 선언 (Behavier2 인터페이스 implement)
func (d Dog2) bite2() {
fmt.Println(d.name, "Dog bites!")
}
func (d Dog2) sounds() {
fmt.Println(d.name, "Dog barks!")
}
func (d Dog2) run() {
fmt.Println(d.name, "Dog is running!")
}
// Cat 리시버메소드 선언 (Behavier2 인터페이스 implement)
func (d Cat) bite2() {
fmt.Println(d.name, "Cat 할퀴다!")
}
func (d Cat) sounds() {
fmt.Println(d.name, "Cat cries!")
}
func (d Cat) run() {
fmt.Println(d.name, "Cat is running!")
}
// 행동 인터페이스
type Behavier2 interface {
bite2()
sounds()
run()
}
// 인터페이스 규격화
// 인터페이스를 파라미터로 받는 형식
func act(animal Behavier2) {
animal.bite2()
animal.sounds()
animal.run()
}
func main() {
dog := Dog2{"poll", 5}
cat := Cat{"bob", 8}
// Behavier2 메소드를 전부 가지고 있기 때문에
// 바로 형변환이 이루어지고 act의 매개변수로 넣을 수 있는 것이다.
act(dog)
act(cat)
}
인터페이스 익명 선언
- 메소드의 매개변수를 받아 바로 인터페이스를 생성하는 방식.
- 매개변수가 들어오면 인터페이스 내의 메소드가 있는지 체크하고 내부 로직 실행시킴.
type Dog3 struct {
name string
weight int
}
func (d Dog3) run2() {
fmt.Println(d.name, "Dog is running!")
}
// 행동 인터페이스
type Behavier3 interface {
run2()
}
// 인터페이스 익명 선언.
func act2(animal interface{ run2() }) {
animal.run2()
}
func main() {
dog := Dog3{"bob", 3}
act2(dog)
}
빈 인터페이스 (만능 매개변수)
- 함수내에서 어떠한 타입이라도 유연하게 매개변수로 받을 수 있다. (만능) -> 모든 타입 지정 가능
type Dog4 struct {
name string
weight int
}
type Cat3 struct {
name string
weight int
}
// interface{} 는 어떠한 타입이라도 매개변수로 받을 수 있어서 많이 씀.
func printValue(s interface{}) {
fmt.Println("ex1 : ", s)
}
func main() {
dog := Dog4{"poll", 100}
cat := Cat3{"bob", 5}
printValue(dog)
printValue(cat)
printValue(15)
printValue("Animal")
printValue(10.2)
printValue([]Dog4{})
printValue([5]Cat3{})
}
'Programing > Go' 카테고리의 다른 글
[Go Lang] 채널 Channel (0) | 2023.03.06 |
---|---|
[Go Lang] 고루틴 - 멀티코어, 클로저 사용하기 (0) | 2023.03.06 |
[Go Lang] 구조체 - 임베디드 패턴, 메소드 상속 활용, 오버라이딩 (0) | 2023.03.02 |
[Go Lang] 구조체 - 생성자 패턴 (0) | 2023.03.02 |
[Go Lang] 구조체 - 선언, 활용 (0) | 2023.03.02 |