Menu
CoddyTech

Định nghĩa giao thức

Thuộc phần Lập trình hướng đối tượng trong hành trình Swift của Coddy. Bài học 27 trên 57.

Một giao thức liệt kê các yêu cầu (phương thức và thuộc tính) mà không triển khai chúng. Một kiểu tuân theo giao thức bằng cách cung cấp mọi yêu cầu, sau đó kiểu đó có thể được dùng ở bất cứ nơi nào yêu cầu giao thức này:

protocol Describable {
    func describe() -> String
}

struct Book: Describable {
    let title: String
    func describe() -> String { "Book: \(title)" }
}

print(Book(title: "Dune").describe())

Đầu ra:

Book: Dune

Khác với kế thừa, một giao thức áp dụng cho cấu trúc, lớp và kiểu liệt kê như nhau, và một kiểu có thể tuân theo nhiều giao thức. Giao thức chỉ quy định điều gì một kiểu có thể làm; mỗi kiểu tự quyết định cách thực hiện:

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())

Đầu ra:

(1, 2)
high

Các yêu cầu về thuộc tính nêu rõ kiểu dữ liệu và thuộc tính chỉ có thể đọc ({ get }) hay cũng có thể ghi ({ get set }). Bạn có thể đáp ứng yêu cầu { get } bằng thuộc tính được lưu trữ hoặc thuộc tính được tính toán:

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)

Đầu ra:

ada
Planet 3

Nếu một kiểu khai báo tuân thủ nhưng bỏ sót một yêu cầu, chương trình sẽ không biên dịch. Trình biên dịch kiểm tra mọi sự tuân thủ, vì vậy code sử dụng giao thức có thể dựa vào giao thức đó:

protocol Priced {
    var price: Int { get }
    func discounted(by percent: Int) -> Int
}

// struct Ticket: Priced { var price = 10 }
// lỗi: kiểu 'Ticket' không tuân theo giao thức 'Priced'
challenge icon

Thử thách

Dễ

Khai báo một giao thức Shape có thuộc tính chỉ đọc name (String) và phương thức area() trả về Double. Hãy tạo các cấu trúc Rectangle (width, height) và Circle (radius, dùng 3.0 cho π để các con số đơn giản hơn) tuân theo giao thức này, với các tên rectangle và circle.

Code được cung cấp đọc các dòng r,3,4 hoặc c,2, tạo hình tương ứng và in ra rectangle: 12.0.

Viết code của bạn trong Shape.swift, Rectangle.swift và Circle.swift. main.swift chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.

Tự làm thử

// Đoạn code đầu vào/đầu ra đã cho: giữ nguyên
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())")
    }
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Playground Swift