D
D
Dmitrii Solovev2016-01-25 18:01:04
go
Dmitrii Solovev, 2016-01-25 18:01:04

How to "inherit method" golang?

I made a simple code of two structures:

package main

import "fmt"

type Animal struct {
  Name string
}

type Rabbit struct {
  Animal
}

//Метод Walk у каждого свой
func (this *Animal) Walk() *Animal{
  fmt.Println("I walk", this.Name)
  return this
}

//Метод Say один
func (this *Animal) Say() *Animal{
  fmt.Println("Im Animal and my Name is", this.Name)
  return this
}

//Метод Walk изменяется для Rabbit и работает корректно
func (this *Rabbit) Walk() *Rabbit{
  this.Animal.Walk()
  fmt.Println("...and Jump")
  return this
}

func main() {

  animal := Animal{ Name: "Зверь" }
  animal.Walk().Say().Walk()

  fmt.Println("\n---------------------\n")

  rabbit := Rabbit{ }
  rabbit.Name = "Кроль"
  rabbit.Walk().Say().Walk() // Say возвращает ссылку на Animal, поэтому второй вызов Walk срабатывает от Animal (без jump) - как сделать правильно?
  
}

you can run it here: play.golang.org/p/RricqVcYx7
The problem is that when chaining (rabbit) after the "parent" Say method, which returns a pointer to Animal, the next method is called for Animal, not Rabbit. I understand that there is no inheritance in GO, but I don’t understand how to solve typical tasks.
Copy-paste your method every time with the return of the necessary pointer? Avoid inheritance altogether?
Or is it done in some other way?
Please show how in GO style.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
S
s_kozlov, 2016-01-26
@dimonnwc3

package main


import "fmt"

type AnimalIntf interface {
  Walk() AnimalIntf
  Say() AnimalIntf
}

type Animal struct {
  animal    AnimalIntf
  Name string
}

type Rabbit struct {
  Animal
}


// Animal
func NewAnimal(name string) *Animal {
  animal := new(Animal)
  animal.animal = animal
  animal.Name = name
  return animal
}

//Метод Walk у каждого свой
func (this *Animal) Walk() AnimalIntf {
  fmt.Println("I walk", this.Name)
  return this.animal
}

//Метод Say общий
func (this *Animal) Say() AnimalIntf {
  fmt.Println("Im Animal and my Name is", this.Name)
  return this.animal
}


// Rabbit
func NewRabbit(name string) *Rabbit {
  rabbit := new(Rabbit)
  rabbit.animal = rabbit
  rabbit.Name = name
  return rabbit
}

//Метод Walk изменяется для Rabbit и работает корректно
func (this *Rabbit) Walk() AnimalIntf {
  this.Animal.Walk()
  fmt.Println("...and Jump")
  return this.animal
}


func main() {

  animal := NewAnimal("Зверь")
  animal.Walk().Say().Walk()

  fmt.Println("\n---------------------\n")

  rabbit := NewRabbit("Кроль")
  rabbit.Walk().Say().Walk()

}

something like a variant
output:
I walk Зверь
Im Animal and my Name is Зверь
I walk Зверь

---------------------

I walk Кроль
...and Jump
Im Animal and my Name is Кроль
I walk Кроль
...and Jump

O
Oleg Shevelev, 2016-01-25
@mantyr

What you have done is called embed. You can move away from it explicitly and not be confused.

type Animal struct {
  Name string
}

type Rabbit struct {
  Ani Animal
}

func (this *Rabbit) Walk() *Rabbit{
  this.Ani.Walk()
  fmt.Println("...and Jump")
  return this
}

func (this *Rabbit) Say() *Rabbit{
  this.Ani.Say()
  return this
}

As for me, using the name this wherever it is implied in Golang is not the best choice, as it becomes more difficult to visually separate between different types of objects.
You can also avoid duplicating functions like this:
rabbit := Rabbit{ }
  rabbit.Ani.Name = "Кроль"
  rabbit.Ani.Walk()
  rabbit.Ani.Say()
  rabbit.Ani.Walk()

N
Nikita, 2016-01-26
@bitver

This is called late binding (late binding) it is done simply through reflection, but it contradicts the idea of ​​go.
stackoverflow.com/questions/10255926/go-reflection...

V
Vitaly Filinkov, 2016-01-26
@vitfil

For this, interfaces were invented in GO.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question