Aula 22 - Tutorial Golang - Embedding
Embedding
Go suporta a incorporação (
Embedding) de
estruturas e
interfaces para expressar uma composição de tipos mais perfeita.
Incorporando Interface em Outra Interface
Uma interface pode embutir qualquer número de interfaces nela, assim como pode ser embutida em qualquer interface.
Todos os métodos da interface incorporada tornam-se parte da interface.
É uma maneira de criar uma nova interface mesclando algumas pequenas interfaces.
Vamos entender com um exemplo.
Suponha que temos um animal de interface como abaixo
type animal interface {
breathe()
walk()
}
Digamos que haja
outra interface chamada
human que incorpora a interface animal.
type human interface {
animal
speak()
}
Então, se algum tipo precisa implementar a
interface human, ele deve definir o método:
- breathe() e walk() da interfaces animal, já que animal está embutido na human
- E o método speak() da interface human
Código Incorporando Interface Em Outra Interface
package main
import "fmt"
type animal interface {
breathe()
walk()
}
type human interface {
animal
speak()
}
type employee struct {
name string
}
func (e employee) breathe() {
fmt.Println("Employee breathes")
}
func (e employee) walk() {
fmt.Println("Employee walk")
}
func (e employee) speak() {
fmt.Println("Employee speaks")
}
func main() {
var h human
h = employee{name: "John"}
h.breathe()
h.walk()
h.speak()
fmt.Println(h)
}
E pra executar é só entrar na pasta onde tá o arquivo embedding.go
go run embedding.go
Saída:
Employee breathes
Employee walk
Employee speaks
{John}
Incorporando interface em uma estrutura
Uma interface também pode ser incorporada em uma estrutura.
Todos os métodos da interface incorporada podem ser chamados por meio dessa estrutura.
Como esses métodos serão chamados dependerá se a interface incorporada é um campo nomeado ou um campo sem nome/anônimo.
Se a interface incorporada for um campo nomeado, os métodos da interface devem ser chamados por meio do nome da interface nomeada.
Se a interface incorporada for um campo sem nome/anônimo, os métodos da interface podem ser referidos diretamente ou por meio do nome da interface.
Vamos ver um programa ilustrando os pontos acima.
Declaramos duas struct
pet1 e
pet2.
A estrutura
pet1 nomeou a interface animal nele.
type pet1 struct {
a animal
name string
}
O
pet2 tem uma interface de animal sem
nome/anônima incorporada.
type pet2 struct {
animal
name string
}
Para uma instância da estrutura
pet1, chamamos o método
breath() e
walk() assim:
p1.a.breathe()
p1.a.walk()
Chamando diretamente esses métodos vai dá erro de compilação.
//p1.breathe()
//p1.walk()
p1.breathe undefined (type pet1 has no field or method breathe)
p1.walk undefined (type pet1 has no field or method walk)
Para uma instância da estrutura
pet2, podemos chamar o método
breathe() e
walk() como diretamente
p2.breathe()
p2.walk()
Podemos acessar diretamente os métodos da interface incorporada se a interface incorporada for anônima ou sem nome.
O jeito abaixo também é válido para chamar interface incorporada sem nome/anônima.
p2.animal.breathe()
p2.animal.walk()
Observe também que, ao criar a instância da estrutura
pet1 ou
pet2, a interface incorporada, ou seja,
animal, é inicializada com um tipo que a implementa, por exemplo,
dog .
p1 := pet1{name: "Milo", a: d}
p2 := pet2{name: "Oscar", animal: d}
Se não inicializarmos a interface incorporada
animal, ela será inicializada com o valor zero na interface que é
nil.
Chamar o método
breath() e
walk() em tal instância da estrutura
pet1 ou
pet2 criará um
pânico.
Incorporando interface em uma estrutura
package main
import "fmt"
type animal interface {
breathe()
walk()
}
type dog struct {
age int
}
func (d dog) breathe() {
fmt.Println("Dog breathes")
}
func (d dog) walk() {
fmt.Println("Dog walk")
}
type pet1 struct {
a animal
name string
}
type pet2 struct {
animal
name string
}
func main() {
d := dog{age: 5}
p1 := pet1{name: "Milo", a: d}
fmt.Println(p1.name)
// p1.breathe()
// p1.walk()
p1.a.breathe()
p1.a.walk()
p2 := pet2{name: "Oscar", animal: d}
fmt.Println(p2.name)
p2.breathe()
p2.walk()
p1.a.breathe()
p1.a.walk()
}
E pra executar é só entrar na pasta onde tá o arquivo embedding.go
go run embedding.go
Saída:
Milo
Dog breathes
Dog walk
Milo
Dog breathes
Dog walk
Dog breathes
Dog walk
É isso pessoal, fico por aqui!
Até mais. :)
página do Código Fluente no
Facebook
Esse é o link do código fluente no Pinterest
Meus links de afiliados:
Obrigado e bons estudos. ;)