No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Herencia

9/30
Recursos

Aportes 18

Preguntas 2

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Go no permite la herencia, go utiliza la composicion.
la composicion, a diferencia de la herencia, no es una clase hija de… sino que contiene los metodos de las clases indicadas.

codigo:

package main

import "fmt"

type Person struct {
	name string
	age  int
}

type Employee struct {
	id int
}

type FullTimeEployee struct {
	Person
	Employee
}

func main() {
	ftEmployee := FullTimeEployee{}
	ftEmployee.id = 1
	ftEmployee.name = "Maria"
	ftEmployee.age = 27
	fmt.Printf("%v", ftEmployee)
}

La siguiente función es un método para que FullTimeEmployee imprima sus atributos de forma más ✨ bonita ✨:

func (employee FullTimeEmployee) String() string {
	return fmt.Sprintf("\nid: %d, name: %s, age: %d ", employee.id, employee.name, employee.age)
}
  • No entiendo por que usa otros lenguajes para explicar, explica todo en Golang, vengo aprender GO, no typescript, para eso me voy al curso de typescript, Entiendo que quiere explicar las diferencias, pero cuando yo explico python no voy con ejemplos de Java, se confunde la gente y se enredan mas, los primeros 7min es de typescript, increible

Cuando se tienen receiver functions asociadas a un struct y se forma otro struct a partir de este, los métodos también funcionan con el nuevo struct.
Creo que esto se parece más a la herencia en Go hablando de métodos.
Y aún contando con esa herencia de métodos puedo reescribir la receiver function en el nuevo struct solo creando una función con el mismo nombre y recibiendo el struct. Así tendría polimorfismo.

package main

import "fmt"

type Person struct {
	Name string
	Age int
}

type Employee struct {
	Person
	Position string
	Salary int
}

func (p Person) SayHello() {
	fmt.Printf("Hi, my name is %s\n", p.Name)
}

func main() {
	me := Person{Name: "Edwin", Age: 30}
	developer := Employee{
		Person: Person{Name: "Lorena", Age: 27},
		Position: "Developer",
		Salary: 2000,
	}

	person.SayHello() // Hi, my name is Edwin
	developer.SayHello() // Hi, my name is Lorena
}

Ahora reescribiendo el método SayHello

package main

import "fmt"

type Person struct {
	Name string
	Age int
}

type Employee struct {
	Person
	Position string
	Salary int
}

func (p Person) SayHello() {
	fmt.Printf("Hi, my name is %s\n", p.Name)
}

func (e Employee) SayHello() {
	fmt.Printf("Hi, I am a %s and my name is %s\n", e.Position,  e.Name)
}

func main() {
	me := Person{Name: "Edwin", Age: 30}
	developer := Employee{
		Person: Person{Name: "Lorena", Age: 27},
		Position: "Developer",
		Salary: 2000,
	}

	person.SayHello() // Hi, my name is Edwin
	developer.SayHello() // Hi, I am a developer and my name is Lorena
}

Podemos usar esta funcion como un constructor

func CreateFullTimeEmployee(name string, age int, id int) *FullTimeEmployee {
	newEmployee := FullTimeEmployee{}
	newEmployee.name = name
	newEmployee.age = age
	newEmployee.id = id

	return &newEmployee
}
func main() {
	ftEmployee := CreateFullTimeEmployee("Alex", 20, 0)
	fmt.Println(*ftEmployee)
}

definitivamente platzi es horrible para la teoria…

De hecho en el ejemplo la función que acepta una persona, si se puede ocupar, por el empleado a tiempo completa. ya que Persona es parte de FullTimeEmployee, simplemente hay que usar persona de FullTimeEmployee.

package main

import (
	"fmt"
)

type Person struct {
	name string
	age  int
}

type Employee struct {
	id int
}
type FullTimeEmployee struct {
	Person
	Employee
}

func GetMessage(p Person) {
	fmt.Printf("%s, tu edad es %d", p.name, p.age)
}

func main() {
	var ftEmployee FullTimeEmployee
	ftEmployee.age = 36
	ftEmployee.id = 1233
	ftEmployee.name = "Jose"
	GetMessage(ftEmployee.Person)
}```
package main

import "fmt"

type Person struct {
	name string
	age  int
}

type Employee struct {
	id int
}

// Inheritance tipo anonimo
type FullTimeEmployee struct {
	Person
	Employee
}

// Composicion sobre herencia
func GetMessage(p Person) string {
	return fmt.Sprintf("Hi %s, you are %d years old", p.name, p.age)
}

func main() {
	f := FullTimeEmployee{}
	f.name = "John"
	f.age = 30
	f.id = 1
	fmt.Printf("%+v\n", f)

	fmt.Println(GetMessage(f))
}

Aqui implemete un cosntructor y un metodo que regresa un informacion ```js package main import "fmt" type Person struct { name string age int } type Employee struct { id int } // Composicion de herencia, se agrega el tipo de objeto type FullTimeEmployee struct { Person Employee } //Metodo func NewFullTimeEmployee(name string, age int, id int) *FullTimeEmployee { return &FullTimeEmployee{ Person: Person{ name: name, age: age, }, Employee: Employee{ id: id, }, } } func (ftEmployee *FullTimeEmployee) GetMesagge() { fmt.Printf("FullTimeEmployee's Name :%s with a age %d and him/her id is %d\n", ftEmployee.name, ftEmployee.age, ftEmployee.id) } func main() { ft := NewFullTimeEmployee("Axel", 22, 1) ft.GetMesagge() } ```
Aqui implemete un constructor y un metodo donde regresa informacion ```js package main import "fmt" type Person struct { name string age int } type Employee struct { id int } // Composicion de herencia, se agrega el tipo de objeto type FullTimeEmployee struct { Person Employee } //Metodo func NewFullTimeEmployee(name string, age int, id int) *FullTimeEmployee { return &FullTimeEmployee{ Person: Person{ name: name, age: age, }, Employee: Employee{ id: id, }, } } func (ftEmployee *FullTimeEmployee) GetMesagge() { fmt.Printf("FullTimeEmployee's Name :%s with a age %d and him/her id is %d\n", ftEmployee.name, ftEmployee.age, ftEmployee.id) } func main() { ft := NewFullTimeEmployee("Axel", 22, 1) ft.GetMesagge() } ```package main import "fmt" type Person struct {    name string    age  int} type Employee struct {    id int} // Composicion de herencia, se agrega el tipo de objetotype FullTimeEmployee struct {    Person    Employee} //Metodo func NewFullTimeEmployee(name string, age int, id int) \*FullTimeEmployee {    return \&FullTimeEmployee{        Person: Person{            name: name,            age:  age,        },        Employee: Employee{            id: id,        },    }} func (ftEmployee \*FullTimeEmployee) GetMesagge() {    fmt.Printf("FullTimeEmployee's Name :%s  with a age %d and him/her id is %d\n", ftEmployee.name, ftEmployee.age, ftEmployee.id)}func main() {    ft := NewFullTimeEmployee("Axel", 22, 1)    ft.GetMesagge()}
Aqui implemete el constructor y un metodopackage main import "fmt" type Person struct {    name string    age  int} type Employee struct {    id int} // Composicion de herencia, se agrega el tipo de objetotype FullTimeEmployee struct {    Person    Employee} //Metodo func NewFullTimeEmployee(name string, age int, id int) \*FullTimeEmployee {    return \&FullTimeEmployee{        Person: Person{            name: name,            age:  age,        },        Employee: Employee{            id: id,        },    }} func (ftEmployee \*FullTimeEmployee) GetMesagge() {    fmt.Printf("FullTimeEmployee's Name :%s  with a age %d and him/her id is %d\n", ftEmployee.name, ftEmployee.age, ftEmployee.id)}func main() {    ft := NewFullTimeEmployee("Axel", 22, 1)    ft.GetMesagge()} ```js package main import "fmt" type Person struct { name string age int } type Employee struct { id int } // Composicion de herencia, se agrega el tipo de objeto type FullTimeEmployee struct { Person Employee } //Metodo func NewFullTimeEmployee(name string, age int, id int) *FullTimeEmployee { return &FullTimeEmployee{ Person: Person{ name: name, age: age, }, Employee: Employee{ id: id, }, } } func (ftEmployee *FullTimeEmployee) GetMesagge() { fmt.Printf("FullTimeEmployee's Name :%s with a age %d and him/her id is %d\n", ftEmployee.name, ftEmployee.age, ftEmployee.id) } func main() { ft := NewFullTimeEmployee("Axel", 22, 1) ft.GetMesagge() } ```
Aqui implemente el constructor ```js package main import "fmt" type Person struct { name string age int } type Employee struct { id int } // Composicion de herencia, se agrega el tipo de objeto type FullTimeEmployee struct { Person Employee } func newFullTimeEmployee(name string, age int, id int) *FullTimeEmployee { return &FullTimeEmployee{ Person: Person{ name: name, age: age, }, Employee: Employee{ id: id, }, } } func main() { ft := newFullTimeEmployee("Axel", 22, 1) fmt.Println(*ft) } ```package main import "fmt" type Person struct {    name string    age  int} type Employee struct {    id int} // Composicion de herencia, se agrega el tipo de objetotype FullTimeEmployee struct {    Person    Employee} func newFullTimeEmployee(name string, age int, id int) \*FullTimeEmployee {    return \&FullTimeEmployee{        Person: Person{            name: name,            age:  age,        },        Employee: Employee{            id: id,        },    }} func main() {    ft := newFullTimeEmployee("Axel", 22, 1)    fmt.Println(\*ft)}

Yo pienso que herencia es un problema de diseño, aunque parece fácil en sintaxis para el programador.
Ejemplo, si escribiéramos el código ej. de java que usa herencia en C y tuviéramos que implementar la herencia a mano, podemos ver la magnitud de la ineficiencia de usar herencia muy fácil, tendríamos 2000 punteros, punteros de punteros que apuntan a punteros, mallocs/free’s de memoria y uniones
Al usar composición y agregación se evitan esos problemas desde el principio y esto está disponible en todos los lenguajes, incluso Orientados a objetos.

Excelente clase!!! Muy clara la distinción entre la herencia clásica en otros lenguajes y la implementación que realiza golang por medio de la composición.

herencia: la clase hija ES la clase padre
composición: la clase hija TIENE la(s) clase(s) padre

package main

import "fmt"

type Person struct {
	name string
	age  uint8
	sex  string
}

type Employee struct {
	id uint64
}

type FullTimeEmployee struct {
	Person
	Employee
}

func main() {
	ftEmployee := FullTimeEmployee{}
	ftEmployee.name = "Carlos"
	ftEmployee.age = 25
	ftEmployee.id = 1
	ftEmployee.sex = "hombre"
	fmt.Printf("%+v\n", ftEmployee)
}

Les dejo lo que seria el método constructor de FullTimeEmployee:

func newFullTimeEmployee(name string, age int, id int) *FullTimeEmployee {
	return &FullTimeEmployee{
		Person{Name: name, Age: age},
		Employee{Id: id},
	}
}

El ejemplo final se puede llegar a hacer pero pasando de que struct viene dicho dato. Ejemplo

func GetMessage(p Person, e Employee) {
	fmt.Printf("El Id es %d %s with age %d\n", e.id, p.name, p.age)
}
func main () {
GetMessage(ftEmployee.Person, ftEmployee.Employee)
}

Para hacer funcionar el método GetMessage, he probado que pueden pasar la persona que corresponde a ese un empleado, de esta forma:

GetMessage(ftEmployee.Person)