Introduzione alle interfacce
Fa parte della sezione Programmazione orientata agli oggetti del percorso GO di Coddy. Lezione 25 di 107.
Un'interfaccia in Go definisce un insieme di firme di metodi senza implementarli. Descrive cosa può fare un tipo, non come lo fa. Qualsiasi tipo che implementa tutti i metodi di un'interfaccia la soddisfa automaticamente.
Ecco come definisci un'interfaccia:
type Speaker interface {
Speak() string
}Questa interfaccia Speaker richiede che qualsiasi tipo che la implementi abbia un metodo Speak() che restituisca una stringa. Ora qualsiasi struct con questo metodo può essere usata ovunque sia previsto un Speaker.
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return d.Name + " says woof!"
}
type Cat struct {
Name string
}
func (c Cat) Speak() string {
return c.Name + " says meow!"
}Sia Dog sia Cat soddisfano l’interfaccia Speaker perché hanno entrambi un metodo Speak() con la firma corretta. Ora puoi scrivere funzioni che accettano qualsiasi Speaker:
func MakeSound(s Speaker) {
fmt.Println(s.Speak())
}
func main() {
dog := Dog{Name: "Buddy"}
cat := Cat{Name: "Whiskers"}
MakeSound(dog) // Buddy dice woof!
MakeSound(cat) // Whiskers dice meow!
}Le interfacce ti consentono di scrivere codice flessibile e riutilizzabile che funziona con qualsiasi tipo che soddisfi i requisiti dell'interfaccia, indipendentemente dall'implementazione sottostante.
Sfida
FacileCostruiamo un sistema di descrizione dei veicoli che mostri come le interfacce consentano a tipi diversi di condividere un comportamento comune. Creerai un'interfaccia che può essere soddisfatta da più tipi di veicoli, poi la userai per descrivere qualsiasi veicolo in modo uniforme.
Organizzerai il codice in due file:
vehicles.go: definisci un'interfacciaDescribercon un unico metodoDescribe() string. Poi crea due struct che soddisfano questa interfaccia:Carcon i campiBrandeModel(entrambi stringhe)Bicyclecon i campiType(stringa) eGears(int)
Describe()che restituisce una stringa descrittiva del veicolo.main.go: crea una funzione chiamataPrintDescriptionche accetta qualsiasiDescribere stampa il risultato della chiamata al suo metodoDescribe(). Leggi le informazioni sui veicoli dall'input, crea sia un Car che un Bicycle e usa la tua funzione per stampare la descrizione di ciascuno.
Verranno forniti i seguenti input:
- Riga 1: marca dell'auto
- Riga 2: modello dell'auto
- Riga 3: tipo di bicicletta
- Riga 4: numero di marce (intero)
I tuoi metodi Describe() dovrebbero restituire stringhe nei seguenti formati:
- Auto:
[Brand] [Model] - Bicicletta:
[Type] bike with [Gears] gears
Ad esempio, dati Toyota, Camry, Mountain e 21, l'output dovrebbe essere:
Toyota Camry
Mountain bike with 21 gearsL'intuizione chiave è che la tua funzione PrintDescription funziona con qualsiasi tipo che abbia un metodo Describe(). Non deve sapere se sta gestendo un'auto, una bicicletta o qualsiasi altro tipo di veicolo che potresti aggiungere in seguito.
Provalo tu
package main
import (
"fmt"
)
// TODO: Crea una funzione PrintDescription che accetti qualsiasi Describer
// e stampi il risultato della chiamata al suo metodo Describe()
func main() {
// Leggi l'input
var carBrand string
var carModel string
var bicycleType string
var gears int
fmt.Scanln(&carBrand)
fmt.Scanln(&carModel)
fmt.Scanln(&bicycleType)
fmt.Scanln(&gears)
// TODO: Crea una Car con la marca e il modello forniti in input
// TODO: Crea una Bicycle con il tipo e il numero di marce forniti in input
// TODO: Usa PrintDescription per stampare la descrizione dell'auto
// TODO: Usa PrintDescription per stampare la descrizione della bicicletta
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti di OOP in Go
File esterniWorkspace e moduli GoPacchetti e importazioniNomi esportati e non esportatiIntroduzione all’OOP in GoGli struct come classiDefinire metodi sugli structReceiver con puntatore vs receiver con valoreInizializzazione degli structFunzioni costruttriciRiepilogo - Calcolatrice semplice4Interfacce
Introduzione alle interfacceImplementazione implicitaL’interfaccia come contrattoInterfaccia vuota (any)Asserzione di tipoSwitch sul tipoComposizione di interfacceInterfacce Stringer ed ErrorRipasso - Calcolatore di forme7Incapsulamento
Campi esportati e non esportatiIncapsulamento a livello di packageMetodi Getter e SetterNascondimento delle informazioni in GoRiepilogo - Registri degli studenti10Tipi generici (Go 1.18+)
Introduzione ai tipi genericiParametri di tipoVincoli di tipoStruct genericheSoluzione alternativa per i metodi genericiRiepilogo - Collezione generica13Modelli di progettazione Parte 1
Introduzione ai modelli di progettazioneModello SingletonModello FactoryModello Abstract FactoryModello ObserverModello Strategy2Approfondimento su tipi e struct
Tipi di base e compostiDefinizioni di tipi personalizzatiTag delle structStruct anonimeStruct annidateValori zero e predefinitiRipasso - Rubrica5Composizione invece dell'ereditarietà
Perché Go non ha l'ereditarietàFondamenti dell'embedding delle structPromozione dei metodiEmbedding di più structEmbedding e aggregazione a confrontoMascheramento dei metodi embeddedRiepilogo: gerarchia dei dipendenti8Gestione degli errori e OOP
L'interfaccia errorTipi di errore personalizzatiWrapping degli errori (fmt.Errorf)Errori sentinellaerrors.Is() ed errors.As()Panic, Defer e RecoverRiepilogo - Parser di file11Libreria standard e OOP
io.Reader e io.Writersort.InterfaceInterfaccia fmt.Stringerencoding/json con le structInterfaccia http.HandlerRipasso - modelli REST API14Modelli di progettazione – Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositeMiddleware come Decorator3Puntatori e memoria
Concetti base dei puntatori in GoPuntatori a structPassaggio per valore vs per riferimentoLa funzione new()Garbage collection in GoRiepilogo - Costruttore di liste concatenate6Polimorfismo in Go
Polimorfismo tramite interfacceDuck typing in GoRegole di soddisfacimento delle interfacceCollezioni polimorficheIniezione delle dipendenzeRiepilogo - Elaboratore di pagamenti9Concorrenza e OOP
Basi delle goroutineCanali e comunicazioneCanali bufferizzati vs non bufferizzatiIstruzione selectsync.Mutex e sync.RWMutexsync.WaitGroupProgettazione di struct thread-safeRiepilogo: worker poolEsercitati da solo: Compilatore Go online