Go Tipos Intermediário
Embedding e composição
Em Go, não há herança de classes. Em vez disso, usamos composição e embedding de structs para reutilizar código e criar tipos mais complexos. O embedding permite que um tipo incorpore outro, promovendo automaticamente os campos e métodos do tipo embutido para o tipo externo.
Quando você embute um tipo em uma struct, os métodos do tipo embutido passam a fazer parte do conjunto de métodos do tipo externo. Isso é chamado de promoção de métodos. Assim, você pode chamar métodos do tipo embutido diretamente no tipo externo, como se fossem dele.
O embedding é uma forma de composição: o tipo externo tem um tipo embutido, não é um tipo embutido. Isso evita os problemas de hierarquias profundas de herança e favorece a flexibilidade.
Neste card, veremos como criar structs que embutem outras structs, como os métodos são promovidos e por que isso é preferível à herança tradicional.
Pontos-chave
- Embedding de structs promove campos e métodos do tipo embutido para o tipo externo.
- Métodos promovidos podem ser chamados diretamente no tipo externo.
- Composição expressa relação 'tem um', enquanto herança expressa 'é um'.
- É possível sobrescrever métodos promovidos definindo um método com o mesmo nome no tipo externo.
- Embedding também pode ser usado com interfaces para compor comportamentos.
package main
import "fmt"
// Animal é um tipo base com um método.
type Animal struct {
Nome string
}
func (a Animal) Falar() {
fmt.Printf("%s faz um som\n", a.Nome)
}
// Cachorro embute Animal. Os métodos de Animal são promovidos.
type Cachorro struct {
Animal // embedding
Raca string
}
// Método próprio do Cachorro.
func (c Cachorro) Latir() {
fmt.Printf("%s late: Au Au!\n", c.Nome)
}
func main() {
// Criando um Cachorro com embedding.
c := Cachorro{
Animal: Animal{Nome: "Rex"},
Raca: "Labrador",
}
// Chamando método promovido de Animal.
c.Falar() // Rex faz um som
// Chamando método próprio.
c.Latir() // Rex late: Au Au!
// Acessando campo promovido.
fmt.Println("Nome:", c.Nome) // Nome: Rex
fmt.Println("Raça:", c.Raca) // Raça: Labrador
}