Menu
Coddy logo textTech

Promoção de métodos

Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy. Lição 36 de 107.

Assim como a incorporação de structs promove os campos para a struct externa, o Go também promove métodos dos tipos incorporados. Isso significa que você pode chamar diretamente na struct externa os métodos definidos na struct incorporada.

type Engine struct {
    Horsepower int
}

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

type Car struct {
    Model string
    Engine  // embutido
}

Como Car incorpora Engine, o método Start() é promovido automaticamente:

func main() {
    c := Car{
        Model:  "Sedan",
        Engine: Engine{Horsepower: 200},
    }
    
    fmt.Println(c.Start())         // Motor ligado
    fmt.Println(c.Engine.Start())  // também funciona
}

Essa promoção tem uma consequência importante para as interfaces. Se o tipo incorporado satisfaz uma interface, o tipo externo também a satisfaz automaticamente:

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 satisfaz Starter através de Engine
}

O tipo Car nunca implementa explicitamente Starter, mas satisfaz a interface porque seu Engine incorporado tem o método necessário. É assim que Go alcança a reutilização de comportamento sem a herança tradicional.

challenge icon

Desafio

Fácil

Vamos criar um sistema de reprodução de música que demonstra como os métodos de tipos incorporados são promovidos para o tipo externo e como isso permite a satisfação de interfaces por meio de composição.

Você organizará seu código em dois arquivos:

  • audio.go: crie os componentes básicos do seu reprodutor de música:
    • Uma struct AudioPlayer com um campo Brand (string) e um método Play() string que retorna [Brand] playing audio
    • Uma interface Playable que exige um método Play() string
    • Uma struct Smartphone com um campo Model que incorpora AudioPlayer
    • Uma struct Tablet com um campo Model que incorpora AudioPlayer
  • main.go: crie uma função chamada StartPlayback que aceite qualquer Playable e retorne o resultado da chamada de Play(). Leia as informações dos dispositivos da entrada, crie um Smartphone e um Tablet e demonstre que ambos satisfazem a interface Playable por meio do AudioPlayer incorporado, embora nenhum dos dois tipos implemente explicitamente Play().

As seguintes entradas serão fornecidas:

  • Linha 1: nome do modelo do Smartphone
  • Linha 2: marca de áudio do Smartphone
  • Linha 3: nome do modelo do Tablet
  • Linha 4: marca de áudio do Tablet

Para cada dispositivo, imprima seu modelo seguido do resultado de passá-lo para StartPlayback.

Por exemplo, dadas as entradas iPhone 15, Apple Audio, iPad Pro e Beats, sua saída deverá ser:

iPhone 15
Apple Audio playing audio
iPad Pro
Beats playing audio

Observe como tanto Smartphone quanto Tablet podem ser passados para StartPlayback, porque o método Play() de AudioPlayer é automaticamente promovido para cada tipo externo, satisfazendo a interface Playable sem nenhum código adicional.

Experimente você mesmo

package main

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

// TODO: Crie uma função StartPlayback que aceita qualquer Playable
// e retorna o resultado de chamar Play()

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Ler o modelo do smartphone
	scanner.Scan()
	smartphoneModel := scanner.Text()
	
	// Ler a marca de áudio do smartphone
	scanner.Scan()
	smartphoneBrand := scanner.Text()
	
	// Ler o modelo do tablet
	scanner.Scan()
	tabletModel := scanner.Text()
	
	// Ler a marca de áudio do tablet
	scanner.Scan()
	tabletBrand := scanner.Text()
	
	// TODO: Crie um Smartphone com o AudioPlayer embutido
	
	// TODO: Crie um Tablet com o AudioPlayer embutido
	
	// TODO: Imprima o modelo do smartphone, depois chame StartPlayback com o smartphone
	
	// TODO: Imprima o modelo do tablet, depois chame StartPlayback com o tablet
	
	_ = smartphoneModel
	_ = smartphoneBrand
	_ = tabletModel
	_ = tabletBrand
	fmt.Println("TODO: Complete the implementation")
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de Go online