인터페이스 소개
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 107개 중 25번째.
Go의 인터페이스는 구현 없이 메서드 시그니처의 집합을 정의합니다. 이는 타입이 어떻게 수행하는지가 아니라 무엇을 할 수 있는지를 설명합니다. 인터페이스의 모든 메서드를 구현하는 모든 타입은 자동으로 해당 인터페이스를 충족합니다.
인터페이스를 정의하는 방법은 다음과 같습니다:
type Speaker interface {
Speak() string
}이 Speaker 인터페이스는 이를 구현하는 모든 타입이 문자열을 반환하는 Speak() 메서드를 가질 것을 요구합니다. 이제 이 메서드를 가진 모든 struct는 Speaker가 필요한 곳 어디에서나 사용될 수 있습니다.
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return d.Name + " says woof!"
}
type Cat struct {
Name string
}
func (c Cat) Speak() string {
return c.Name + " says meow!"
}Dog와 Cat 모두 올바른 시그니처를 가진 Speak() 메서드를 가지고 있으므로 Speaker 인터페이스를 충족합니다. 이제 어떤 Speaker든 받아들이는 함수를 작성할 수 있습니다:
func MakeSound(s Speaker) {
fmt.Println(s.Speak())
}
func main() {
dog := Dog{Name: "Buddy"}
cat := Cat{Name: "Whiskers"}
MakeSound(dog) // Buddy가 woof!라고 말합니다
MakeSound(cat) // Whiskers가 meow!라고 말합니다
}인터페이스를 사용하면 기본 구현에 관계없이 인터페이스의 요구 사항을 충족하는 모든 타입과 함께 작동하는 유연하고 재사용 가능한 코드를 작성할 수 있습니다.
챌린지
쉬움인터페이스를 통해 서로 다른 타입이 공통된 동작을 공유하는 방법을 보여주는 차량 설명 시스템을 구축해 보겠습니다. 여러 차량 타입이 충족할 수 있는 인터페이스를 만든 다음, 이를 사용하여 모든 차량을 일관되게 설명해 볼 것입니다.
코드는 두 개의 파일로 구성됩니다:
vehicles.go:Describe() string이라는 단일 메서드를 가진Describer인터페이스를 정의합니다. 그런 다음 이 인터페이스를 충족하는 두 개의 구조체를 만듭니다:Brand와Model필드(둘 다 문자열)를 가진CarType(문자열)과Gears(정수) 필드를 가진Bicycle
Describe()메서드를 가져야 합니다.main.go: 임의의Describer를 인자로 받아 해당Describe()메서드를 호출한 결과를 출력하는PrintDescription함수를 만듭니다. 입력으로부터 차량 정보를 읽어 Car와 Bicycle을 모두 생성하고, 함수를 사용하여 각각의 설명을 출력합니다.
다음과 같은 입력이 제공됩니다:
- 1행: 자동차 브랜드 (Car brand)
- 2행: 자동차 모델 (Car model)
- 3행: 자전거 타입 (Bicycle type)
- 4행: 기어 수 (정수)
Describe() 메서드는 다음과 같은 형식의 문자열을 반환해야 합니다:
- Car:
[Brand] [Model] - Bicycle:
[Type] bike with [Gears] gears
예를 들어, Toyota, Camry, Mountain, 21이 주어지면 출력은 다음과 같아야 합니다:
Toyota Camry
Mountain bike with 21 gears여기서 핵심은 PrintDescription 함수가 Describe() 메서드를 가진 모든 타입과 함께 작동한다는 점입니다. 이 함수는 자신이 다루는 대상이 Car인지, Bicycle인지, 아니면 나중에 추가될 다른 차량 타입인지 알 필요가 없습니다.
치트 시트
Go에서 인터페이스(interface)는 구현 없이 메서드 시그니처의 집합을 정의합니다. 모든 메서드를 구현하는 모든 타입은 자동으로 해당 인터페이스를 충족합니다.
인터페이스 정의하기:
type Speaker interface {
Speak() string
}필요한 메서드를 구현하는 타입은 인터페이스를 충족합니다:
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return d.Name + " says woof!"
}
type Cat struct {
Name string
}
func (c Cat) Speak() string {
return c.Name + " says meow!"
}함수는 인터페이스를 충족하는 모든 타입을 받아들일 수 있습니다:
func MakeSound(s Speaker) {
fmt.Println(s.Speak())
}
func main() {
dog := Dog{Name: "Buddy"}
cat := Cat{Name: "Whiskers"}
MakeSound(dog) // Buddy says woof!
MakeSound(cat) // Whiskers says meow!
}직접 해보기
package main
import (
"fmt"
)
// TODO: 모든 Describer를 수용하고 해당 인터페이스의 Describe() 메서드 호출 결과를
// 출력하는 PrintDescription 함수를 생성하세요.
func main() {
// 입력 읽기
var carBrand string
var carModel string
var bicycleType string
var gears int
fmt.Scanln(&carBrand)
fmt.Scanln(&carModel)
fmt.Scanln(&bicycleType)
fmt.Scanln(&gears)
// TODO: 입력받은 브랜드와 모델로 Car를 생성하세요.
// TODO: 입력받은 타입과 기어 수로 Bicycle을 생성하세요.
// TODO: PrintDescription을 사용하여 자동차의 설명을 출력하세요.
// TODO: PrintDescription을 사용하여 자전거의 설명을 출력하세요.
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서