Menu
Coddy logo textTech

메서드 프로모션

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

struct 임베딩이 필드를 바깥쪽 struct로 승격하는 것처럼, Go는 임베드된 타입의 method도 승격합니다. 즉, 임베드된 struct에 정의된 method를 바깥쪽 struct에서 직접 호출할 수 있습니다.

type Engine struct {
    Horsepower int
}

func (e Engine) Start() string {
    return "Engine started"
}

type Car struct {
    Model string
    Engine  // 임베디드
}

CarEngine을 임베드하므로 Start() 메서드는 자동으로 승격됩니다:

func main() {
    c := Car{
        Model:  "Sedan",
        Engine: Engine{Horsepower: 200},
    }
    
    fmt.Println(c.Start())         // 엔진 시작됨
    fmt.Println(c.Engine.Start())  // 또한 작동함
}

이 승격은 interface에 중요한 결과를 가져옵니다. embedded type이 interface를 satisfies하면, 외부 타입도 자동으로 이를 satisfies합니다:

type Starter interface {
    Start() string
}

func Ignite(s Starter) {
    fmt.Println(s.Start())
}

func main() {
    c := Car{Model: "Sedan", Engine: Engine{Horsepower: 200}}
    Ignite(c)  // Car는 Engine을 통해 Starter를 만족합니다
}

Car 타입은 Starter를 명시적으로 구현하지 않지만, 내장된 Engine에 필요한 method가 있으므로 인터페이스를 충족합니다. 이것이 Go가 전통적인 상속 없이 동작 재사용을实现하는 방식입니다.

challenge icon

챌린지

쉬움

임베드된 타입의 method가 외부 타입으로 승격되는 방식과, 이를 통해 composition으로 interface를 만족할 수 있는 방식을 보여 주는 music player 시스템을 만들어 보겠습니다.

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

  • audio.go: music player의 구성 요소를 만듭니다:
    • AudioPlayer struct에 Brand field(string)와 [Brand] playing audio를 returns하는 Play() string method를 정의합니다.
    • Playable interface에 Play() string method를 requiring하도록 정의합니다.
    • AudioPlayer를 embedded하는 Model field가 있는 Smartphone struct를 정의합니다.
    • AudioPlayer를 embedded하는 Model field가 있는 Tablet struct를 정의합니다.
  • main.go: any Playable을 accepts하고 Play()을 calling한 result를 returns하는 StartPlayback이라는 function을 만듭니다. input에서 device 정보를 Read하고, Smartphone과 Tablet을 모두 Create한 다음, 두 타입 모두 자체적으로 Play()를 명시적으로 구현하지 않았지만 embedded AudioPlayer를 통해 Playable interface를 만족한다는 것을 보여 줍니다.

다음 input이 제공됩니다:

  • Line 1: Smartphone model 이름
  • Line 2: Smartphone audio brand
  • Line 3: Tablet model 이름
  • Line 4: Tablet audio brand

각 device에 대해 해당 device의 model을 출력한 후, 해당 device를 StartPlayback에 전달한 result를 출력합니다.

예를 들어 iPhone 15, Apple Audio, iPad Pro, Beats가 주어지면 output은 다음과 같아야 합니다:

iPhone 15
Apple Audio playing audio
iPad Pro
Beats playing audio

AudioPlayerPlay() method가 각 외부 타입으로 자동으로 승격되므로, 추가 code 없이 Playable interface를 만족하여 SmartphoneTablet 모두 StartPlayback에 전달할 수 있다는 점에 주목하세요.

직접 해보기

package main

import (
	"bufio"
	"fmt"
	"os"
)

// TODO: 어떤 Playable이든 받아들이는 StartPlayback 함수를 생성하세요
// 그리고 Play()를 호출한 결과를 반환합니다

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// 스마트폰 모델 읽기
	scanner.Scan()
	smartphoneModel := scanner.Text()
	
	// 스마트폰 오디오 브랜드 읽기
	scanner.Scan()
	smartphoneBrand := scanner.Text()
	
	// 태블릿 모델 읽기
	scanner.Scan()
	tabletModel := scanner.Text()
	
	// 태블릿 오디오 브랜드 읽기
	scanner.Scan()
	tabletBrand := scanner.Text()
	
	// TODO: 임베디드 AudioPlayer가 있는 Smartphone을 생성하세요
	
	// TODO: 임베디드 AudioPlayer가 있는 Tablet을 생성하세요
	
	// TODO: 스마트폰 모델을 출력한 다음, 스마트폰으로 StartPlayback을 호출하세요
	
	// TODO: 태블릿 모델을 출력한 다음, 태블릿으로 StartPlayback을 호출하세요
	
	_ = smartphoneModel
	_ = smartphoneBrand
	_ = tabletModel
	_ = tabletBrand
	fmt.Println("TODO: Complete the implementation")
}
quiz icon실력 점검

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

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

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