Menu
Coddy logo textTech

인터페이스를 통한 다형성

Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 107개 중 41번째.

다형성은 공유된 인터페이스를 통해 서로 다른 타입을 일관되게 다룰 수 있도록 합니다. Go에서는 상속이나 클래스 계층 구조 없이 전적으로 인터페이스를 통해 이를 구현합니다.

function이 interface type을 매개변수로 accepts하면, 해당 interface를 구현하는 any concrete type을 전달할 수 있습니다. function은 구체적인 type을 알 필요가 없습니다. function은 interface에 의해 정의된 동작에만 관심이 있습니다:

type Speaker interface {
    Speak() string
}

type Dog struct{ Name string }
func (d Dog) Speak() string { return "Woof!" }

type Cat struct{ Name string }
func (c Cat) Speak() string { return "Meow!" }

func MakeSound(s Speaker) {
    fmt.Println(s.Speak())
}

이제 MakeSoundSpeak() method가 있는 모든 type에서 작동합니다:

func main() {
    dog := Dog{Name: "Rex"}
    cat := Cat{Name: "Whiskers"}
    
    MakeSound(dog)  // 멍!
    MakeSound(cat)  // 야옹!
}

동일한 function 호출은 전달된 실제 타입에 따라 서로 다른 동작을 생성합니다. 이것이 바로 polymorphism이 실제로 작동하는 모습입니다. MakeSound function은 한 번만 작성하지만, Speaker interface를 충족하는 한 무제한의 타입과 함께 작동합니다.

이 접근 방식은 코드를 유연하고 확장 가능하게 유지합니다. 말할 수 있는 새로운 유형을 추가할 때 기존 함수는 변경할 필요 없이 인터페이스를 구현하기만 하면 자동으로 작동합니다.

challenge icon

챌린지

쉬움

실제로 polymorphism을 보여 주는 차량 설명 시스템을 만들어 보겠습니다. 공통된 동작을 interface를 통해 공유하는 여러 vehicle type을 만들고, 어떤 vehicle과도 작동하는 단일 function을 작성합니다.

코드를 두 파일로 구성합니다:

  • vehicles.go: Describer interface를 Define하고 Describe() string method를 요구합니다. 그런 다음 이 interface를 각자의 방식으로 Implement하는 세 가지 vehicle type을 만듭니다:
    • Car에는 BrandModel fields가 있습니다. Describe()Car: [Brand] [Model]을 반환합니다.
    • Motorcycle에는 BrandEngineCC (int) fields가 있습니다. Describe()Motorcycle: [Brand] [EngineCC]cc를 반환합니다.
    • Bicycle에는 Type field가 있습니다("Mountain" 또는 "Road"와 같음). Describe()Bicycle: [Type]을 반환합니다.
  • main.go: 어떤 Describer든 accepts하고 Describe()를 calling한 결과를 출력하는 PrintDescription이라는 function을 만듭니다. input에서 vehicle details를 읽고, 각 vehicle type을 하나씩 Create한 다음, 세 가지 서로 다른 type 모두에서 같은 function이 작동한다는 것을 demonstrate하기 위해 각각을 PrintDescription에 전달합니다.

다음 input이 제공됩니다:

  • Line 1: Car Brand
  • Line 2: Car Model
  • Line 3: Motorcycle Brand
  • Line 4: Motorcycle Engine CC (integer)
  • Line 5: Bicycle Type

예를 들어 Toyota, Camry, Honda, 600, Mountain이 주어지면 output은 다음과 같아야 합니다:

Car: Toyota Camry
Motorcycle: Honda 600cc
Bicycle: Mountain

PrintDescription는 Car, Motorcycle 또는 Bicycle 중 무엇을 받는지 알 필요가 없다는 점에 주목하세요. 단순히 Describe()를 Call하면 각 type이 자신만의 고유한 output으로 응답합니다. 이것이 polymorphism입니다. 하나의 function, 여러 동작입니다.

직접 해보기

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

// TODO: 모든 Describer를 받아들이는 PrintDescription이라는 함수를 만들고
// Describe()를 호출한 결과를 출력한다

func main() {
	reader := bufio.NewReader(os.Stdin)

	// 자동차 세부 정보 읽기
	carBrand, _ := reader.ReadString('\n')
	carBrand = strings.TrimSpace(carBrand)
	carModel, _ := reader.ReadString('\n')
	carModel = strings.TrimSpace(carModel)

	// 오토바이 세부 정보 읽기
	motoBrand, _ := reader.ReadString('\n')
	motoBrand = strings.TrimSpace(motoBrand)
	motoEngineStr, _ := reader.ReadString('\n')
	motoEngineStr = strings.TrimSpace(motoEngineStr)
	motoEngine, _ := strconv.Atoi(motoEngineStr)

	// 자전거 세부 정보 읽기
	bicycleType, _ := reader.ReadString('\n')
	bicycleType = strings.TrimSpace(bicycleType)

	// TODO: 입력값을 사용하여 Car, Motorcycle, Bicycle을 생성한다

	// TODO: 각 차량에 대해 PrintDescription을 호출하여 다형성을 보여준다
	fmt.Println("TODO: Print vehicle descriptions")
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Go 컴파일러