Sobes.tech
Junior

Come viene implementato l'ereditarietà in Golang?

sobes.tech AI

Risposta dell'AI

In Go non esiste l'ereditarietà classica come in Java o C++. Al suo posto, vengono utilizzati due meccanismi:

  1. Embedding (Incorporamento):

    • L'embedded permette di inserire una struttura o un tipo in un altro.
    • Il tipo embedded "trasmette" i propri campi e metodi al tipo che lo incorpora.
    • L'accesso ai campi e ai metodi del tipo embedded avviene direttamente, come se fossero definiti nel tipo che lo incorpora.
    • Questo imita la composizione, ma con una sintassi di accesso più comoda, simile all'ereditarietà.
    package main
    
    import "fmt"
    
    type Engine struct {
        Type string
    }
    
    func (e Engine) Start() {
        fmt.Println(e.Type, "motore avviato")
    }
    
    type Car struct {
        Engine // Incorporamento della struttura Engine
        Model  string
    }
    
    func main() {
        car := Car{
            Engine: Engine{Type: "V8"},
            Model:  "Mustang",
        }
    
        // Accesso diretto ai campi e ai metodi della struttura incorporata
        fmt.Println("Modello dell'auto:", car.Model)
        car.Start() // Chiamata al metodo della struttura incorporata
    }
    
  2. Interfacce:

    • Le interfacce definiscono un insieme di metodi che un tipo deve implementare.
    • Definiscono "comportamento", non struttura dati.
    • Il tipo non deve dichiarare esplicitamente di implementare l'interfaccia; basta implementare tutti i metodi definiti.
    • Le interfacce forniscono polimorfismo.
    package main
    
    import "fmt"
    
    type Speaker interface {
        Speak()
    }
    
    type Dog struct {
        Name string
    }
    
    func (d Dog) Speak() {
        fmt.Println(d.Name, "dice Woof!")
    }
    
    type Cat struct {
        Name string
    }
    
    func (c Cat) Speak() {
        fmt.Println(c.Name, "dice Miau!")
    }
    
    func main() {
        animals := []Speaker{
            Dog{Name: "Buddy"},
            Cat{Name: "Whiskers"},
        }
    
        for _, animal := range animals {
            animal.Speak() // Chiamata polimorfica al metodo Speak
        }
    }
    

La combinazione di embedding e interfacce permette a Go di raggiungere flessibilità e riutilizzo del codice senza le complessità e i problemi associati all'ereditarietà tradizionale (ad esempio, il problema del "diamante"). In Go, si preferisce la composizione e le interfacce rispetto alle gerarchie di ereditarietà.