Go
Programmation orientée objet
Recherche…
Remarques
L'interface ne peut pas être implémentée avec les récepteurs de pointeurs car *User
n'est pas un User
Structs
Go prend en charge les types définis par l'utilisateur sous la forme de structures et d'alias de type. Les structures sont des types composites, les composants de données constituant le type de structure sont appelés champs . un champ a un type et un nom qui doit être unqiue.
package main
type User struct {
ID uint64
FullName string
Email string
}
func main() {
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
fmt.Println(user) // {1 Zelalem Mekonen [email protected]}
}
c'est aussi une syntaxe légale pour définir des structures
type User struct {
ID uint64
FullName, Email string
}
user := new(User)
user.ID = 1
user.FullName = "Zelalem Mekonen"
user.Email = "[email protected]"
Structures intégrées
Comme une structure est aussi un type de données, elle peut être utilisée comme un champ anonyme, la structure externe peut accéder directement aux champs de la structure intégrée même si la structure provient d’un package différent. Ce comportement permet de dériver tout ou partie de votre implémentation à partir d'un autre type ou d'un ensemble de types.
package main
type Admin struct {
Username, Password string
}
type User struct {
ID uint64
FullName, Email string
Admin // embedded struct
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
admin,
}
fmt.Println(admin) // {zola supersecretpassword}
fmt.Println(user) // {1 Zelalem Mekonen [email protected] {zola supersecretpassword}}
fmt.Println(user.Username) // zola
fmt.Println(user.Password) // supersecretpassword
}
Les méthodes
En Go une méthode est
une fonction qui agit sur une variable d'un certain type, appelée le récepteur
le receveur peut être n'importe quoi, non seulement des structs
mais même une function
, les types d’alias pour les types intégrés tels que int
, string
, bool
peuvent avoir une méthode, une exception à cette règle est que les interfaces
interface est une définition abstraite et une méthode est une implémentation, essayant de générer une erreur de compilation.
En combinant des structs
et des methods
vous pouvez obtenir un équivalent proche d'une class
en programmation orientée objet.
une méthode dans Go a la signature suivante
func (name receiverType) methodName(paramterList) (returnList) {}
package main
type Admin struct {
Username, Password string
}
func (admin Admin) Delete() {
fmt.Println("Admin Deleted")
}
type User struct {
ID uint64
FullName, Email string
Admin
}
func (user User) SendEmail(email string) {
fmt.Printf("Email sent to: %s\n", user.Email)
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
admin,
}
user.SendEmail("Hello") // Email sent to: [email protected]
admin.Delete() // Admin Deleted
}
Pointeur Vs Value Receiver
le récepteur d'une méthode est généralement un pointeur pour des raisons de performances car nous ne ferions pas de copie de l'instance, comme ce serait le cas dans le récepteur de valeur, ceci est particulièrement vrai si le type de récepteur est une structure. une autre raison pour que le récepteur soit un pointeur serait de pouvoir modifier les données pointées par le récepteur.
un récepteur de valeur est utilisé pour éviter la modification des données contenues dans le récepteur, un récepteur de vaule peut provoquer une baisse de performance si le récepteur est une structure volumineuse.
package main
type User struct {
ID uint64
FullName, Email string
}
// We do no require any special syntax to access field because receiver is a pointer
func (user *User) SendEmail(email string) {
fmt.Printf("Sent email to: %s\n", user.Email)
}
// ChangeMail will modify the users email because the receiver type is a ponter
func (user *User) ChangeEmail(email string) {
user.Email = email;
}
func main() {
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
user.SendEmail("Hello") // Sent email to: [email protected]
user.ChangeEmail("[email protected]")
fmt.Println(user.Email) // [email protected]
}
Interface et polymorphisme
Les interfaces permettent de spécifier le comportement d'un objet, si quelque chose peut le faire, il peut être utilisé ici. une interface définit un ensemble de méthodes, mais ces méthodes ne contiennent pas de code car elles sont abstraites ou l'implémentation est laissée à l'utilisateur de l'interface. Contrairement à la plupart des langages orientés objet, les interfaces peuvent contenir des variables dans Go.
Le polymorphisme est l'essence même de la programmation orientée objet: la capacité à traiter des objets de types différents de manière uniforme tant qu'ils adhèrent à la même interface. Les interfaces Go offrent cette fonctionnalité de manière très directe et intuitive
package main
type Runner interface {
Run()
}
type Admin struct {
Username, Password string
}
func (admin Admin) Run() {
fmt.Println("Admin ==> Run()");
}
type User struct {
ID uint64
FullName, Email string
}
func (user User) Run() {
fmt.Println("User ==> Run()")
}
// RunnerExample takes any type that fullfils the Runner interface
func RunnerExample(r Runner) {
r.Run()
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
RunnerExample(admin)
RunnerExample(user)
}