No tienes acceso a esta clase

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

No se trata de lo que quieres comprar, sino de quién quieres ser. Aprovecha el precio especial.

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

15 Días
11 Hrs
16 Min
0 Seg

Interfaces

10/30
Recursos

Aportes 15

Preguntas 5

Ordenar por:

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

Les comparto mis implementaciones de getMessage para FullTimeEmployee y TemporaryEmployee 😃:

func (ftEmployee FullTimeEmployee) getMessage() string {
	return fmt.Sprintf("\nFull Time Employee\nid: %d name: %s age: %d endDate: %s",
		ftEmployee.id,
		ftEmployee.name,
		ftEmployee.age,
		ftEmployee.endDate)
}
func (tEmployee TemporaryEmployee) getMessage() string {
	return fmt.Sprintf("\nTemporary Employee\nid: %d name: %s age: %d taxRate: %d",
		tEmployee.id,
		tEmployee.name,
		tEmployee.age,
		tEmployee.taxRate)
}

En lenguajes como Typescript o Java es necesario definir los métodos de la interfaz para poder implementarla y la implementación es explícita.
En cambio en Go, es suficiente definir los métodos para implementar la interfaz y la implementación es implícita.
En el polimorfismo se utiliza una interfaz (o una clase base) para determinar en tiempo de ejecución el método a utilizar, accediéndolo por medio de la interfaz en vez de hacerlo a través de un objeto en particular, porque en este último caso el método se determina en tiempo de compilación (esto no es polimorfismo).

// no se conoce p hasta el momento en que 
// se ejecuta esta función
// podría ser un FullTimeEmployee
// o un TemporaryEmployee
func getMessage(p PrintInfo) {
  fmt.Println(p.getMessage)
}

// aquí ya se conoce el método a usar
// antes de compilar
ftEmployee.getMessage()

Entonces con polimorfismo, podrías por ejemplo, estar recibiendo desde una BD o un JSON desde un front, los datos de un empleado en tiempo de ejecución y determinar en ese momento cual es el método apropiado para ese empleado en particular.

El tipado de Go respecto de las interfaces es una especie de duck typing. Como regla nmemotécnica: si camina como un pato y hace cuác como un pato, entonces debe ser un pato. La diferencia entre duck typing y el tipado en Go, es que en Go el chequeo sucede en tiempo de compilación, es tipado estático. Es por esto que lo llaman “tipado estructural”, el chequeo le da importancia a la estructura.

Apuntes y código:

  • Diferentes lenguajes de programación utilizan sintaxis explicita para decir que una clase implementa un interfaz
  • Go lo hace de manera implícita lo que permite la re utilización de código y polimorfismo
package main

import "fmt"

type Person struct {
	name string
	age  int
}

type Employee struct {
	id int
}

// De esta manera aplicamos la composicion sobre la herencia
type FullTimeEmployee struct {
	Person
	Employee
	endDate string
}

type TemporatyEmployee struct {
	Person
	Employee
	taxRate int
}
// Creamos la interfaz
type PrintInfo interface {
	getMessage() string
}
// Implementamos la interfaz
func (ftEmployee FullTimeEmployee) getMessage() string {
	return "Full Time Employee"
}

func (tEmployee TemporatyEmployee) getMessage() string {
	return "Temporary Employee"
}
// Creamos el metodo de la interfaz
func getMessage(p PrintInfo) {
	fmt.Println(p.getMessage())
}

func main() {
	ftEmployee := FullTimeEmployee{}
	ftEmployee.name = "Benjamin"
	ftEmployee.age = 20
	ftEmployee.id = 1
	fmt.Printf("%v\n", ftEmployee)
	tEmployee := TemporatyEmployee{}
	getMessage(tEmployee)
	getMessage(ftEmployee)
}

Go no implementa interfaces de manera explicita sino de manera implícita.

package main

import "fmt"

type Person struct {
	name string
	age  int
}

type Employee struct {
	id int
}

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

type TemproaryEmployee struct {
	Person
	Employee
	taxRate float64
}

type PrintInfo interface {
	getMessage() string
}

// Composicion sobre herencia
func (ft FullTimeEmployee) getMessage() string {
	return fmt.Sprintf("Hi %s, you are %d years old. And you are a full time employee", ft.name, ft.age)
}

func (te TemproaryEmployee) getMessage() string {
	return fmt.Sprintf("Hi %s, you are %d years old. And you are a temprary employee", te.name, te.age)
}

func GetMessage(pi PrintInfo) {
	fmt.Println(pi.getMessage())
}

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

	t := TemproaryEmployee{}
	t.name = "Mary"
	t.age = 25
	t.id = 2
	t.taxRate = 0.25
	fmt.Printf("%+v\n", t)

	GetMessage(f)
	GetMessage(t)
}

yo no conozco typescript, por lo que me perdi en esta explicación.

Siento muy forzado go para la OOP, pero siento que se puede mantener la limpieza si todo lo llevamos a un archivo aparte.

Si no queda muy claro lo de interfaces, básicamente es un plano, igual que los structs pero en lugar de enfocarse en los datos (estructura), se enfoca en las acciones (métodos). Ya que no existe implementación en go, al utilizar la interface como parámetro (como el caso de *getMessage*), validará cualquier estructura que cumpla con el plano, es decir, que contenga todos los métodos de la interface.
Comparto mi codigo ```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 yearsExperience int } type HalfTimeEmployee struct { Person Employee internship bool } //Constructores func NewFullTimeEmployee(name string, age int, id int, yearExperience int) *FullTimeEmployee { return &FullTimeEmployee{ Person: Person{ name: name, age: age, }, Employee: Employee{ id: id, }, yearsExperience: yearExperience, } } func (ftEmployee *FullTimeEmployee) GetMesagge() { fmt.Printf("FullTimeEmployee's Name :%s with a age %d and him/her id is %d with %d years of experience\n", ftEmployee.name, ftEmployee.age, ftEmployee.id, ftEmployee.yearsExperience) } func NewHalfTimeEmployee(name string, age int, id int, internship bool) *HalfTimeEmployee { return &HalfTimeEmployee{ Person: Person{ name: name, age: age, }, Employee: Employee{ id: id, }, internship: internship, } } func (htEmployee *HalfTimeEmployee) GetMesagge() { fmt.Printf("HalfTimeEmployee's Name: %s, Age: %d, ID: %d, Internship: %t\n", htEmployee.name, htEmployee.age, htEmployee.id, htEmployee.internship) } type PrintInfo interface { GetMesagge() } func PrintData(p PrintInfo) { p.GetMesagge() } func main() { ft := NewFullTimeEmployee("Axel", 22, 1, 2) ht := NewHalfTimeEmployee("Alexis", 22, 2, true) PrintData(ft) PrintData(ht) } ```
Comparto mi codigo con implemetacion de constructores con interfacespackage 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    yearsExperience int}type HalfTimeEmployee struct {    Person    Employee    internship bool} //Constructores func NewFullTimeEmployee(name string, age int, id int, yearExperience int) \*FullTimeEmployee {    return \&FullTimeEmployee{        Person: Person{            name: name,            age:  age,        },        Employee: Employee{            id: id,        },        yearsExperience: yearExperience,    }} func (ftEmployee \*FullTimeEmployee) GetMesagge() {    fmt.Printf("FullTimeEmployee's Name :%s  with a age %d and him/her id is %d with %d years of experience\n", ftEmployee.name, ftEmployee.age, ftEmployee.id, ftEmployee.yearsExperience)} func NewHalfTimeEmployee(name string, age int, id int, internship bool) \*HalfTimeEmployee {    return \&HalfTimeEmployee{        Person: Person{            name: name,            age:  age,        },        Employee: Employee{            id: id,        },        internship: internship,    }} func (htEmployee \*HalfTimeEmployee) GetMesagge() {    fmt.Printf("HalfTimeEmployee's Name: %s, Age: %d, ID: %d, Internship: %t\n", htEmployee.name, htEmployee.age, htEmployee.id, htEmployee.internship)} type PrintInfo interface {    GetMesagge()} func PrintData(p PrintInfo) {    p.GetMesagge()} func main() {    ft := NewFullTimeEmployee("Axel", 22, 1, 2)    ht := NewHalfTimeEmployee("Alexis", 22, 2, true)    PrintData(ft)    PrintData(ht)} ```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 yearsExperience int } type HalfTimeEmployee struct { Person Employee internship bool } //Constructores func NewFullTimeEmployee(name string, age int, id int, yearExperience int) *FullTimeEmployee { return &FullTimeEmployee{ Person: Person{ name: name, age: age, }, Employee: Employee{ id: id, }, yearsExperience: yearExperience, } } func (ftEmployee *FullTimeEmployee) GetMesagge() { fmt.Printf("FullTimeEmployee's Name :%s with a age %d and him/her id is %d with %d years of experience\n", ftEmployee.name, ftEmployee.age, ftEmployee.id, ftEmployee.yearsExperience) } func NewHalfTimeEmployee(name string, age int, id int, internship bool) *HalfTimeEmployee { return &HalfTimeEmployee{ Person: Person{ name: name, age: age, }, Employee: Employee{ id: id, }, internship: internship, } } func (htEmployee *HalfTimeEmployee) GetMesagge() { fmt.Printf("HalfTimeEmployee's Name: %s, Age: %d, ID: %d, Internship: %t\n", htEmployee.name, htEmployee.age, htEmployee.id, htEmployee.internship) } type PrintInfo interface { GetMesagge() } func PrintData(p PrintInfo) { p.GetMesagge() } func main() { ft := NewFullTimeEmployee("Axel", 22, 1, 2) ht := NewHalfTimeEmployee("Alexis", 22, 2, true) PrintData(ft) PrintData(ht) } ```
Hola! Los invito a "jugar" con el siguiente código, ver cómo se comporta solo con el primer método (comentando los últimos 2 SIN comentar las correspondientes llamadas) antes de pasar a interfaces. (Go 1.22.1) ```js package main import "fmt" type Person struct { Name string Age int } type Employee struct { Person // Embedding id int } type Developer struct { Employee // Embedding Language string } func (p *Person) GetBdayMsj() string { return fmt.Sprintf("Hi %s. Congratulations! on your %dth birthday", p.Name, p.Age) } func (e *Employee) GetBdayMsj() string { return fmt.Sprintf("Hi %s. Congratulations! on your %dth birthday. Your employee id is %d", e.Name, e.Age, e.id) } func (d *Developer) GetBdayMsj() string { return fmt.Sprintf("Hi %s. Congratulations! on your %dth birthday. I see you are a %s developer", d.Name, d.Age, d.Language) } func main() { dev := Developer{ Employee: Employee{ Person: Person{ Name: "John", Age: 25, }, id: 1, }, Language: "Go", } fmt.Println(dev.Person.GetBdayMsj()) fmt.Println(dev.Employee.GetBdayMsj()) fmt.Println(dev.GetBdayMsj()) } ```

Genial lo que he podido recordar de TS., pero para quienes no conocen de JS o TS, siento podría ser un poco engorroso tener que ver media clase de un lenguaje al cual no le están apuntando. Por lo demás, muy bien explicado.

package main

import "fmt"

type Person struct {
	name string
	age  uint8
	sex  string
}

type PrintInfo interface {
	getMessage() string
}
type Employee struct {
	id uint64
}

type FullTimeEmployee struct {
	Person
	Employee
	endTime int
}

func (ftEmployee FullTimeEmployee) getMessage() string {
	return "Este es un fulltimeEmployee"
}

type TemporaryEmployee struct {
	Person
	Employee
	taxRate string
}

func (tEmployee TemporaryEmployee) getMessage() string {
	return "Este es un TemporaryEmployee"
}

func getMessage(p PrintInfo) {
	fmt.Printf("%+v\n", p.getMessage())
}

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

	tEmployee := TemporaryEmployee{}
	fmt.Printf("%+v\n", tEmployee)

	getMessage(ftEmployee)
	getMessage(tEmployee)

}

codigo:

package main

import "fmt"

type Person struct {
	name string
	age  int
}

type Employee struct {
	id int
}

type FullTimeEployee struct {
	Person
	Employee
	endDate string
}

// metodo de FullTimeEmployee
func (ftEmploye FullTimeEployee) getMessage() string {
	return "Full Time Employe"
}

type TemporaryEmployee struct {
	Person
	Employee
	taxRate int
}

// Metodo de Temporary Employee
func (tEmploye TemporaryEmployee) getMessage() string {
	return "Temporary Employe"
}

// Interface
type PrintInfo interface {
	getMessage() string
}

func getMessage(p PrintInfo) {
	fmt.Println(p.getMessage())
}

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

	tEmployee := TemporaryEmployee{}
	getMessage(ftEmployee)
	getMessage(tEmployee)

}