Desafio Go

Composição com interfaces e sobrescrita

Enunciado

Crie uma interface Falante com o método Falar() string. Crie uma struct Animal que implementa Falar() retornando "Som genérico". Crie uma struct Gato que embuta Animal e sobrescreva Falar() retornando "Miau". No main, crie um slice de Falante contendo um Animal e um Gato, e imprima o resultado de Falar() para cada um.

Requisitos

  • A interface Falante deve ter o método Falar() string.
  • Animal deve implementar Falar() retornando "Som genérico".
  • Gato deve embutir Animal e sobrescrever Falar() retornando "Miau".
  • O main deve iterar sobre um slice de Falante e imprimir os sons.

Código inicial

package main

import "fmt"

// Defina a interface e as structs aqui

func main() {
	// Crie o slice e itere
}

Saída esperada

Som genérico
Miau
Ver dica

Para sobrescrever, defina um método Falar com receptor Gato. O método do Animal embutido será ocultado.

Mostrar solução
package main

import "fmt"

type Falante interface {
	Falar() string
}

type Animal struct{}

func (a Animal) Falar() string {
	return "Som genérico"
}

type Gato struct {
	Animal // embedding
}

// Sobrescreve o método Falar do Animal
func (g Gato) Falar() string {
	return "Miau"
}

func main() {
	animais := []Falante{
		Animal{},
		Gato{},
	}
	for _, a := range animais {
		fmt.Println(a.Falar())
	}
}

Passo a passo

  1. Definimos a interface Falante com o método Falar() string.
  2. Criamos Animal com o método Falar que retorna "Som genérico".
  3. Criamos Gato embutindo Animal.
  4. Definimos um método Falar com receptor Gato que retorna "Miau". Isso sobrescreve o método promovido.
  5. No main, criamos um slice de Falante contendo um Animal e um Gato.
  6. Iteramos e chamamos Falar() em cada elemento, imprimindo o resultado.

Por que funciona

O embedding promove o método Falar de Animal para Gato, mas como definimos um método com o mesmo nome em Gato, ele tem precedência. Assim, Gato satisfaz Falante com seu próprio método, enquanto Animal usa o seu. A interface permite tratar ambos polimorficamente.

Erros comuns

  • Não sobrescrever corretamente: se o método em Gato tiver receptor de ponteiro (*Gato), então Gato{} (valor) não implementará Falante; seria necessário usar &Gato{}.
  • Esquecer de embutir: se Gato não embutir Animal, não herda o método Falar e precisaria implementá-lo do zero.
  • Confundir interface com herança: Gato não é um Animal; é um tipo que tem um Animal e pode sobrescrever métodos.

Outra forma de resolver

Poderia não usar embedding e simplesmente implementar Falar diretamente em Gato, mas perderia a reutilização de outros métodos de Animal.

Saída esperada

Som genérico
Miau