הגדרת פרוטוקולים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Swift של Coddy. שיעור 27 מתוך 57.
פרוטוקול מונה דרישות (מתודות ומאפיינים) בלי לממש אותן. טיפוס מציית לפרוטוקול על ידי אספקת כל הדרישות, ואז אפשר להשתמש בו בכל מקום שבו מצופה הפרוטוקול:
protocol Describable {
func describe() -> String
}
struct Book: Describable {
let title: String
func describe() -> String { "Book: \(title)" }
}
print(Book(title: "Dune").describe())פלט:
Book: Duneבניגוד לירושה, פרוטוקול פועל באותה מידה עבור מבנים, מחלקות ומנויים, וטיפוס יכול להתאים לפרוטוקולים רבים. הפרוטוקול מציין רק מה טיפוס יכול לעשות; כל טיפוס מחליט איך:
protocol Describable {
func describe() -> String
}
struct Point: Describable {
var x = 0, y = 0
func describe() -> String { "(\(x), \(y))" }
}
enum Level: Describable {
case low, high
func describe() -> String { self == .low ? "low" : "high" }
}
print(Point(x: 1, y: 2).describe())
print(Level.high.describe())פלט:
(1, 2)
highדרישות מאפיינים מציינות את הטיפוס והאם המאפיין הוא לקריאה בלבד ({ get }) או שגם ניתן לכתיבה ({ get set }). אפשר למלא דרישה של { get } באמצעות מאפיין מאוחסן או מחושב:
protocol Named {
var name: String { get }
}
struct User: Named {
let name: String
}
struct Planet: Named {
var number: Int
var name: String { "Planet \(number)" }
}
print(User(name: "ada").name)
print(Planet(number: 3).name)פלט:
ada
Planet 3אם טיפוס מצהיר שהוא תואם לפרוטוקול אך אינו עומד בדרישה כלשהי, הקוד לא עובר קומפילציה. המהדר בודק כל תאימות, כך שקוד שמשתמש בפרוטוקול יכול להסתמך עליה:
protocol Priced {
var price: Int { get }
func discounted(by percent: Int) -> Int
}
// struct Ticket: Priced { var price = 10 }
// שגיאה: הטיפוס 'Ticket' אינו תואם לפרוטוקול 'Priced'אתגר
קלהצהירו על פרוטוקול Shape עם מאפיין לקריאה בלבד name (String) ושיטה area() שמחזירה Double. צרו את המבנים Rectangle (רוחב, גובה) ו-Circle (רדיוס, תוך שימוש ב-3.0 עבור π כדי לשמור על מספרים פשוטים) כך שיתאימו לפרוטוקול, עם השמות rectangle ו-circle.
הקוד שסופק קורא שורות r,3,4 או c,2, יוצר את הצורה המתאימה ומדפיס rectangle: 12.0.
הקוד שלכם ייכתב בקבצים Shape.swift, Rectangle.swift ו-Circle.swift. הקובץ main.swift מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
// קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in input {
let p = line.split(separator: ",").map(String.init)
if p[0] == "r" {
let s = Rectangle(width: Double(p[1])!, height: Double(p[2])!)
print("\(s.name): \(s.area())")
} else {
let s = Circle(radius: Double(p[1])!)
print("\(s.name): \(s.area())")
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
7פולימורפיזם וטיפוסים גנריים
פולימורפיזםהמרת טיפוסיםפונקציות גנריותטיפוסים גנרייםסיכום - מחשבון צורות6פרוטוקולים
הגדרת פרוטוקוליםטיפוסים התואמים לפרוטוקולהרחבות לפרוטוקוליםפרוטוקולים כטיפוסיםסיכום – מערכת תשלומיםתרגלו בעצמכם: Swift אונליין