다형성 컬렉션
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 107개 중 44번째.
인터페이스의 가장 강력한 활용법 중 하나는 같은 컬렉션에 서로 다른 타입을 저장하는 것입니다. 인터페이스 타입의 슬라이스에는 해당 인터페이스를 만족하는 모든 값을 담을 수 있으므로, 서로 관련은 있지만 타입이 다른 값들을 함께 그룹화할 수 있습니다.
다양한 도형을 관리해야 하는 상황을 생각해 보세요. 각 유형마다 별도의 슬라이스를 사용하는 대신, 인터페이스 유형의 단일 슬라이스를 사용할 수 있습니다.
type Shape interface {
Area() float64
}
type Circle struct{ Radius float64 }
func (c Circle) Area() float64 { return 3.14159 * c.Radius * c.Radius }
type Rectangle struct{ Width, Height float64 }
func (r Rectangle) Area() float64 { return r.Width * r.Height }
func main() {
shapes := []Shape{
Circle{Radius: 5},
Rectangle{Width: 4, Height: 3},
Circle{Radius: 2},
}
for _, s := range shapes {
fmt.Printf("Area: %.2f\n", s.Area())
}
}
shapes 슬라이스에는 원과 직사각형이 모두 들어 있습니다. 반복할 때 각 요소는 실제 유형에 따라 Area()에 응답합니다. 이는 컬렉션에 다형성을 적용한 것으로, 같은 루프가 모든 도형 유형을 동일하게 처리합니다.
다형성 컬렉션은 다양한 항목을 처리하는 시스템을 구축할 때 필수적입니다. 이메일과 SMS 메시지를 보내는 알림 시스템, 여러 적 유형을 업데이트하는 게임, 여러 파일 형식을 처리하는 문서 처리기 등이 그 예입니다. 컬렉션은 구체적인 유형에는 신경 쓰지 않습니다. 각 요소가 필요한 동작을 제공하기만 하면 됩니다.
챌린지
쉬움통합된 인터페이스를 통해 다양한 유형의 작업을 처리하는 작업 관리 시스템을 만들어 봅시다. 여러 작업 유형을 만들고, 다형성 컬렉션에 모두 모아 함께 처리합니다.
세 개의 파일에 코드를 나누어 작성합니다.
task.go:Task인터페이스를 정의합니다. 이 인터페이스는Summary() string메서드를 요구합니다. 모든 작업 유형은 이 공통 계약을 충족해야 합니다.types.go: 각각Task인터페이스를 구현하는 세 가지 작업 유형을 만듭니다.BugFix에는ID(string) 필드와Severity(string) 필드가 있습니다.Summary()는Bug #[ID] ([Severity])를 반환합니다.Feature에는Name(string) 필드와Points(int) 필드가 있습니다.Summary()는Feature: [Name] - [Points] pts를 반환합니다.Documentation에는Topic(string) 필드가 있습니다.Summary()는Docs: [Topic]을 반환합니다.
main.go:Task슬라이스를 받아 각 작업의 요약을 한 줄씩 출력하는PrintBacklog함수를 만듭니다. 입력에서 작업 세부 정보를 읽고, 각 작업 유형의 인스턴스를 하나씩 만든 다음, 모두 하나의[]Task슬라이스에 담아PrintBacklog에 전달합니다.
다음 입력이 제공됩니다.
- 1번째 줄: 버그 ID
- 2번째 줄: 버그 심각도
- 3번째 줄: 기능 이름
- 4번째 줄: 기능 포인트(정수)
- 5번째 줄: 문서 주제
예를 들어 1042, critical, Themes, 8, API가 주어지면 출력은 다음과 같아야 합니다.
Bug #1042 (critical)
Feature: Themes - 8 pts
Docs: API여기서 중요한 점은 PrintBacklog에 버그, 기능 또는 문서별로 별도의 로직이 필요하지 않다는 것입니다. 단순히 슬라이스를 순회하면서 각 요소에 대해 Summary()를 호출합니다. 각 작업 유형은 고유한 형식으로 응답하며, 다형성 컬렉션을 사용하면 서로 다른 유형을 일관된 방식으로 처리할 수 있음을 보여 줍니다.
직접 해보기
package main
import (
"fmt"
)
// TODO: Task 슬라이스를 받는 PrintBacklog 함수를 만드세요
// 그리고 각 작업의 요약을 별도의 줄에 출력하세요
func main() {
// 입력 읽기
var bugID string
var bugSeverity string
var featureName string
var featurePoints int
var docTopic string
fmt.Scanln(&bugID)
fmt.Scanln(&bugSeverity)
fmt.Scanln(&featureName)
fmt.Scanln(&featurePoints)
fmt.Scanln(&docTopic)
// TODO: 각 작업 유형(BugFix, Feature, Documentation)별로 하나씩 만드세요
// TODO: 모든 작업을 하나의 []Task 슬라이스에 모으세요
// TODO: 작업 슬라이스를 전달하여 PrintBacklog를 호출하세요
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서직접 연습해 보세요: 온라인 Go 컴파일러