Héritage en Go

En programmation orientée objet (POO), l'héritage est un mécanisme qui permet à une classe (sous-classe) d'hériter des attributs et des méthodes d'une autre classe (classe parente). Grâce à l'héritage, les sous-classes peuvent réutiliser le code de la classe parente et peuvent étendre ou modifier leur comportement sans modifier la classe parente.

Go n'est pas un langage de programmation orienté objet traditionnel ; il ne possède pas de classes ni d'héritage.

Go utilise des structures et des interfaces pour implémenter des fonctionnalités similaires.


"Héritage" en Go

Le langage Go ne possède pas les concepts de classe et d'héritage que l'on trouve dans les langages orientés objet traditionnels ; à la place, il utilise la composition et les interfaces pour obtenir des fonctionnalités similaires.

Composition

La composition est le principal moyen pour Go de mettre en œuvre la réutilisation du code. En intégrant une structure dans une autre, la structure enfant peut "hériter" des champs et des méthodes de la structure parente.

Exemple

package main

import "fmt"

// Structure parente
type Animal struct {
    Name string
}

// Méthode de la structure parente
func (a *Animal) Speak() {
    fmt.Println(a.Name, "dit bonjour !")
}

// Structure enfant
type Dog struct {
    Animal // Intégrer la structure Animal
    Breed  string
}

func main() {
    dog := Dog{
        Animal: Animal{Name: "Buddy"},
        Breed:  "Golden Retriever",
    }

    dog.Speak() // Appeler la méthode de la structure parente
    fmt.Println("Breed:", dog.Breed)
}

Explication de code

  • Animalest la structure parente, contenant un champNameet une méthodeSpeak。
  • Dogest la structure enfant, grâce à l'incorporationAnimalLa structure hériteAnimalles champs et méthodes de.
  • DansmainDans la fonction, nous avons créé unDogune instance, et appeléSpeakméthode.

2. Interface

Les interfaces sont le principal moyen pour Go de mettre en œuvre le polymorphisme. En définissant des interfaces, différentes structures peuvent implémenter les mêmes méthodes, ce qui permet d'obtenir un comportement polymorphe semblable à l'héritage.

Exemple de code

Exemple

package main

import "fmt"

// Définir l'interface
type Speaker interface {
    Speak()
}

// Structure parente
type Animal struct {
    Name string
}

// Implémenter les méthodes de l'interface
func (a *Animal) Speak() {
    fmt.Println(a.Name, "dit bonjour !")
}

// Structure enfant
type Dog struct {
    Animal
    Breed string
}

func main() {
    var speaker Speaker

    dog := Dog{
        Animal: Animal{Name: "Buddy"},
        Breed:  "Golden Retriever",
    }

    speaker = &dog
    speaker.Speak() // Appeler la méthode via l'interface
}

Explication de code

  • Speakerest une interface, définissant unSpeakméthode.
  • AnimalLa structure implémenteSpeakerInterface.
  • DogLa struct, par incorporation,Animalstruct, implémentantSpeakerInterface.
  • DansmainDans la fonction, nous allonsDogassigner l'instance àSpeakerinterface, et appelée via l'interfaceSpeakméthode.

Différences entre Go et l'héritage classique

FonctionnalitésHéritage classiquela manière Go
Réutilisation du codePar héritagePar composition (incorporation de structs)
PolymorphismePar héritage et redéfinition de méthodeimplémenté via des interfaces
Relationrelation "is-a"relation "has-a" ou "implements".
FlexibilitéLa relation d'héritage est fixepeut être composé à l'exécution

Simulation complète de l'héritage :

Exemple

package main

import "fmt"

// Classe de base
type Vehicle struct {
    Brand string
}

func (v *Vehicle) Start() {
    fmt.Println(v.Brand, "started")
}

// Classe dérivée
type Car struct {
    Vehicle // Intégrer Vehicle
    Model  string
}

// Redéfinir la méthode Start
func (c *Car) Start() {
    fmt.Println(c.Brand, c.Model, "car started")
}

func main() {
    v := Vehicle{Brand: "Toyota"}
    c := Car{
        Vehicle: Vehicle{Brand: "Honda"},
        Model:  "Civic",
    }
   
    v.Start() // Toyota a démarré
    c.Start() // La voiture Honda Civic a démarré
    c.Vehicle.Start() // Honda a démarré
}

Cette conception en Go évite de nombreux problèmes de l'héritage traditionnel, comme le problème de la classe de base fragile, tout en offrant une plus grande flexibilité.

autres extensions