Go
Programación orientada a objetos
Buscar..
Observaciones
La interfaz no se puede implementar con receptores de puntero porque *User
no es User
Estructuras
Go admite tipos definidos por el usuario en forma de estructuras y alias de tipo. Las estructuras son tipos compuestos, los elementos componentes de los datos que constituyen el tipo de estructura se denominan campos . un campo tiene un tipo y un nombre que debe ser unqiue.
package main
type User struct {
ID uint64
FullName string
Email string
}
func main() {
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
fmt.Println(user) // {1 Zelalem Mekonen [email protected]}
}
Esta es también una sintaxis legal para definir estructuras.
type User struct {
ID uint64
FullName, Email string
}
user := new(User)
user.ID = 1
user.FullName = "Zelalem Mekonen"
user.Email = "[email protected]"
Estructuras embebidas
Debido a que una estructura es también un tipo de datos, se puede usar como un campo anónimo, la estructura externa puede acceder directamente a los campos de la estructura incorporada incluso si la estructura proviene de un paquete diferente. este comportamiento proporciona una manera de derivar parte o la totalidad de su implementación de otro tipo o conjunto de tipos.
package main
type Admin struct {
Username, Password string
}
type User struct {
ID uint64
FullName, Email string
Admin // embedded struct
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
admin,
}
fmt.Println(admin) // {zola supersecretpassword}
fmt.Println(user) // {1 Zelalem Mekonen [email protected] {zola supersecretpassword}}
fmt.Println(user.Username) // zola
fmt.Println(user.Password) // supersecretpassword
}
Métodos
En Go un método es
una función que actúa sobre una variable de cierto tipo, llamada el receptor
el receptor puede ser cualquier cosa, no solo structs
sino incluso una function
, tipos de alias para tipos integrados como int
, string
, bool
puede tener un método, una excepción a esta regla es que las interfaces
(que se explican más adelante) no pueden tener métodos, ya que interfaz es una definición abstracta y un método es una implementación, al intentar generar un error de compilación.
combinando structs
y methods
puede obtener un equivalente cercano de una class
en programación orientada a objetos.
Un método en Go tiene la siguiente firma.
func (name receiverType) methodName(paramterList) (returnList) {}
package main
type Admin struct {
Username, Password string
}
func (admin Admin) Delete() {
fmt.Println("Admin Deleted")
}
type User struct {
ID uint64
FullName, Email string
Admin
}
func (user User) SendEmail(email string) {
fmt.Printf("Email sent to: %s\n", user.Email)
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
admin,
}
user.SendEmail("Hello") // Email sent to: [email protected]
admin.Delete() // Admin Deleted
}
Puntero Vs Valor receptor
El receptor de un método suele ser un puntero por motivos de rendimiento porque no haríamos una copia de la instancia, como sería el caso en el receptor de valores, esto es especialmente cierto si el tipo de receptor es una estructura. Otra razón para hacer que el receptor escriba un puntero sería para que pudiéramos modificar los datos a los que apunta el receptor.
se utiliza un receptor de valor para evitar la modificación de los datos que contiene el receptor, un receptor de vara puede causar un impacto en el rendimiento si el receptor es una estructura grande.
package main
type User struct {
ID uint64
FullName, Email string
}
// We do no require any special syntax to access field because receiver is a pointer
func (user *User) SendEmail(email string) {
fmt.Printf("Sent email to: %s\n", user.Email)
}
// ChangeMail will modify the users email because the receiver type is a ponter
func (user *User) ChangeEmail(email string) {
user.Email = email;
}
func main() {
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
user.SendEmail("Hello") // Sent email to: [email protected]
user.ChangeEmail("[email protected]")
fmt.Println(user.Email) // [email protected]
}
Interfaz y polimorfismo
Las interfaces proporcionan una manera de especificar el comportamiento de un objeto, si algo puede hacer esto, se puede usar aquí. una interfaz define un conjunto de métodos, pero estos métodos no contienen código, ya que son abstractos o se deja en manos del usuario de la interfaz. a diferencia de la mayoría de los lenguajes, las interfaces orientadas a objetos pueden contener variables en Go.
El polimorfismo es la esencia de la programación orientada a objetos: la capacidad de tratar objetos de diferentes tipos de manera uniforme siempre que se adhieran a la misma interfaz. Las interfaces Go proporcionan esta capacidad de una manera muy directa e intuitiva.
package main
type Runner interface {
Run()
}
type Admin struct {
Username, Password string
}
func (admin Admin) Run() {
fmt.Println("Admin ==> Run()");
}
type User struct {
ID uint64
FullName, Email string
}
func (user User) Run() {
fmt.Println("User ==> Run()")
}
// RunnerExample takes any type that fullfils the Runner interface
func RunnerExample(r Runner) {
r.Run()
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
RunnerExample(admin)
RunnerExample(user)
}