מבוא לממשקים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-GO של Coddy. שיעור 25 מתוך 107.
ממשק ב-Go מגדיר קבוצה של חתימות מתודות בלי לממש אותן. הוא מתאר מה טיפוס יכול לעשות, ולא איך הוא עושה זאת. כל טיפוס שמממש את כל המתודות בממשק מקיים את הממשק הזה באופן אוטומטי.
כך מגדירים ממשק:
type Speaker interface {
Speak() string
}הממשק Speaker הזה דורש מכל טיפוס שמממש אותו שתהיה לו מתודת Speak() שמחזירה מחרוזת. כעת אפשר להשתמש בכל מבנה עם המתודה הזו בכל מקום שבו מצופה 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!"
}גם Dog וגם Cat מממשים את הממשק Speaker, משום שלכל אחד מהם יש מתודה Speak() עם חתימה מתאימה. עכשיו אפשר לכתוב פונקציות שמקבלות כל Speaker:
func MakeSound(s Speaker) {
fmt.Println(s.Speak())
}
func main() {
dog := Dog{Name: "Buddy"}
cat := Cat{Name: "Whiskers"}
MakeSound(dog) // Buddy אומר הב הב!
MakeSound(cat) // Whiskers אומר מיאו!
}ממשקים מאפשרים לך לכתוב קוד גמיש ושימושי מחדש, שעובד עם כל סוג שעומד בדרישות הממשק, ללא קשר למימוש הבסיסי.
אתגר
קלבואו נבנה מערכת לתיאור כלי רכב שמדגימה כיצד ממשקים מאפשרים לסוגים שונים לחלוק התנהגות משותפת. תיצרו ממשק שסוגים שונים של כלי רכב יכולים לממש, ואז תשתמשו בו כדי לתאר כל כלי רכב באופן אחיד.
תארגנו את הקוד שלכם בשני קבצים:
vehicles.go: הגדירו ממשקDescriberעם מתודה אחת בלבדDescribe() string. לאחר מכן צרו שתי רשומות (struct) שמממשות את הממשק הזה:Carעם השדותBrandו-Model(שניהם מסוג מחרוזת)Bicycleעם השדותType(מחרוזת) ו-Gears(מספר שלם)
Describe()שמחזירה מחרוזת תיאורית על כלי הרכב.main.go: צרו פונקציה בשםPrintDescriptionשמקבלת כל ערך שמממש אתDescriberומדפיסה את התוצאה של קריאה למתודתDescribe()שלו. קראו את פרטי כלי הרכב מהקלט, צרו גםCarוגםBicycle, והשתמשו בפונקציה שלכם כדי להדפיס תיאור של כל אחד מהם.
הקלט הבא יסופק:
- שורה 1: מותג המכונית
- שורה 2: דגם המכונית
- שורה 3: סוג האופניים
- שורה 4: מספר ההילוכים (מספר שלם)
מתודות ה-Describe() שלכם צריכות להחזיר מחרוזות בתבניות הבאות:
- מכונית:
[Brand] [Model] - אופניים:
[Type] bike with [Gears] gears
לדוגמה, עבור Toyota, Camry, Mountain ו-21, הפלט שלכם צריך להיות:
Toyota Camry
Mountain bike with 21 gearsהתובנה המרכזית היא שהפונקציה PrintDescription שלכם פועלת עם כל סוג שיש לו מתודת Describe(). היא לא צריכה לדעת אם היא עובדת עם מכונית, אופניים או כל סוג אחר של כלי רכב שתוסיפו בהמשך.
נסו בעצמכם
package main
import (
"fmt"
)
// TODO: צרו פונקציה בשם PrintDescription שמקבלת כל Describer
// ומדפיסה את התוצאה של קריאה למתודה Describe() שלו
func main() {
// קראו קלט
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: צרו Car עם המותג והדגם מהקלט
// TODO: צרו Bicycle עם הסוג ומספר ההילוכים מהקלט
// TODO: השתמשו ב-PrintDescription כדי להדפיס את התיאור של המכונית
// TODO: השתמשו ב-PrintDescription כדי להדפיס את התיאור של האופניים
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות OOP ב-Go
קבצים חיצונייםסביבת העבודה והמודולים של Goחבילות וייבואשמות מיוצאים לעומת שמות לא מיוצאיםמבוא ל-OOP ב-GoStructs כמחלקותהגדרת מתודות עבור Structsמקבלי Pointer לעומת Valueאתחול Structפונקציות Constructorחזרה – מחשבון פשוט4ממשקים
מבוא לממשקיםמימוש משתמעממשק כחוזהממשק ריק (any)אימות טיפוסמתג טיפוסיםהרכבת ממשקיםממשקי Stringer ו-Errorסיכום – מחשבון צורות7כימוס
שדות מיוצאים לעומת שדות לא מיוצאיםכימוס ברמת החבילהמתודות Getter ו-Setterהסתרת מידע ב-Goסיכום – רשומות תלמידים10Generics (Go 1.18 ומעלה)
מבוא ל־Genericsפרמטרים של טיפוסיםאילוצי טיפוסיםמבנים גנרייםפתרון עוקף למתודות גנריותסיכום – אוסף גנרי2העמקה בסוגים וב-Structs
סוגים בסיסיים ומורכביםהגדרות של סוגים מותאמים אישיתתגיות StructStructs אנונימייםStructs מקונניםערכי אפס וברירות מחדלסיכום – ספר אנשי קשר5קומפוזיציה במקום ירושה
למה ב-Go אין ירושהיסודות הטמעת Structקידום מתודותהטמעת כמה Structsהטמעה לעומת אגרגציההסתרת מתודות מוטמעותסיכום – היררכיית עובדים8טיפול בשגיאות ו-OOP
ממשק errorסוגי שגיאות מותאמים אישיתעטיפת שגיאות (fmt.Errorf)שגיאות Sentinelerrors.Is() ו-errors.As()Panic, Defer ו-Recoverסיכום – מנתח קבצים11ספרייה סטנדרטית ותכנות מונחה עצמים
io.Reader ו-io.Writersort.Interfaceהממשק fmt.Stringerencoding/json עם מבניםהממשק http.Handlerסיכום – מודלים של REST API3מצביעים וזיכרון
יסודות המצביעים ב-Goמצביעים למבניםהעברה לפי ערך לעומת לפי הפניההפונקציה new()איסוף אשפה ב-Goסיכום - בונה רשימה מקושרת6פולימורפיזם ב-Go
פולימורפיזם באמצעות ממשקיםטיפוס ברווז ב-Goכללי התאמה לממשקאוספים פולימורפייםהזרקת תלויותסיכום - מעבד תשלומים9מקביליות ו-OOP
יסודות GoroutinesChannels ותקשורתChannel עם חוצץ לעומת ללא חוצץפקודת Selectsync.Mutex ו-sync.RWMutexsync.WaitGroupתכנון Struct בטוח לשימוש במקבילסיכום - מאגר עובדים12מושגים מתקדמים בתכנות מונחה עצמים
דפוס האפשרויות הפונקציונליותדפוס Builder ב-Goשרשור מתודותכינויי טיפוסים לעומת הגדרותיסודות Reflectionסקירה כללית של יצירת קודתרגלו בעצמכם: קומפיילר Go אונליין