Menu
Coddy logo textTech

Ocultação de métodos incorporados

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

Às vezes, você precisa que a struct externa forneça sua própria implementação de um método que o tipo incorporado já possui. Isso é chamado de sombreamento e permite substituir métodos promovidos por um comportamento personalizado.

Quando você define um método na estrutura externa com o mesmo nome de um método incorporado, o método externo tem precedência:

type Animal struct {
    Name string
}

func (a Animal) Speak() string {
    return "Some sound"
}

type Dog struct {
    Animal
    Breed string
}

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

Agora, quando você chama Speak() em um Dog, o método externo é usado:

func main() {
    d := Dog{Animal: Animal{Name: "Rex"}, Breed: "Labrador"}
    
    fmt.Println(d.Speak())        // Woof! - método de Dog
    fmt.Println(d.Animal.Speak()) // Algum som - método de Animal
}

O método incorporado não desapareceu. Você ainda pode acessá-lo explicitamente por meio do nome do tipo incorporado. Esse padrão é útil quando você quer personalizar o comportamento mantendo a implementação original disponível, talvez para chamá-la de dentro do seu método sobrescrito:

func (d Dog) Speak() string {
    return d.Animal.Speak() + " (but actually Woof!)"
}

O shadowing oferece controle sobre qual comportamento é exposto, mantendo o acesso ao original por meio de qualificação explícita.

challenge icon

Desafio

Fácil

Vamos criar um sistema de notificações em que diferentes canais de notificação possam personalizar a forma como formatam e entregam mensagens. Você usará o sombreamento de métodos para permitir que canais específicos substituam o comportamento padrão, ainda podendo acessar a implementação original quando necessário.

Você organizará seu código em três arquivos:

  • base.go: Crie uma struct BaseNotification com os campos Title e Priority (ambos strings). Dê a ela um método Format() string que retorne a notificação em um formato padrão: [Priority] Title.
  • channels.go: Crie dois tipos de canais de notificação que incorporem BaseNotification e façam sombreamento do método Format com suas próprias implementações:
    • EmailNotification com um campo Recipient. Seu método Format() deve retornar Email to [Recipient]: [Priority] Title
    • SlackNotification com um campo Channel. Seu método Format() deve chamar o método BaseNotification.Format() incorporado e adicionar #[Channel]: ao início do resultado
  • main.go: Leia os detalhes da notificação da entrada, crie os dois tipos de notificações e demonstre o sombreamento imprimindo:
    1. A saída formatada de EmailNotification (usando seu método sombreado)
    2. O formato base de EmailNotification (chamando explicitamente o método incorporado)
    3. A saída formatada de SlackNotification (que usa internamente o método base)

As seguintes entradas serão fornecidas:

  • Linha 1: Título da notificação
  • Linha 2: Nível de prioridade
  • Linha 3: Destinatário do e-mail
  • Linha 4: Nome do canal do Slack

Por exemplo, dadas as entradas Server Alert, HIGH, admin@company.com e ops-alerts, sua saída deverá ser:

Email to admin@company.com: HIGH Server Alert
[HIGH] Server Alert
#ops-alerts: [HIGH] Server Alert

Observe como EmailNotification substitui completamente a formatação base, enquanto SlackNotification a aprimora chamando o método original e adicionando o contexto do canal. Ambas as abordagens demonstram diferentes formas de usar o sombreamento de métodos de maneira eficaz.

Experimente você mesmo

package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Ler o título da notificação
	scanner.Scan()
	title := scanner.Text()
	
	// Ler o nível de prioridade
	scanner.Scan()
	priority := scanner.Text()
	
	// Ler o destinatário do email
	scanner.Scan()
	recipient := scanner.Text()
	
	// Ler o nome do canal do Slack
	scanner.Scan()
	channel := scanner.Text()
	
	// TODO: Crie um EmailNotification com a notificação base, title, priority e recipient
	
	// TODO: Crie um SlackNotification com a notificação base, title, priority e channel
	
	// TODO: Imprima a saída formatada do EmailNotification (usando seu método sombreado)
	
	// TODO: Imprima o formato base do EmailNotification (chamando explicitamente o método embutido)
	
	// TODO: Imprima a saída formatada do SlackNotification
	
	fmt.Println() // Placeholder - remova ao implementar
}
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