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
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.- Dans
mainDans 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
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.- Dans
mainDans la fonction, nous allonsDogassigner l'instance àSpeakerinterface, et appelée via l'interfaceSpeakméthode.
Différences entre Go et l'héritage classique
| Fonctionnalités | Héritage classique | la manière Go |
|---|---|---|
| Réutilisation du code | Par héritage | Par composition (incorporation de structs) |
| Polymorphisme | Par héritage et redéfinition de méthode | implémenté via des interfaces |
| Relation | relation "is-a" | relation "has-a" ou "implements". |
| Flexibilité | La relation d'héritage est fixe | peut être composé à l'exécution |
Simulation complète de l'héritage :
Exemple
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