Trong bài học trước, bạn đã được học “kỹ thuật mở rộng class bằng Extension“. Đây là một kỹ thuật rất hay để mở rộng một class nào đó dù cho bạn không nắm mã nguồn. Để nâng cao hơn trong việc thao tác với class, bài viết này mình sẽ trình bày tới bạn một thành phần mới cho phép bạn khai báo các qui tắc giao tiếp chung cho class, đó là protocol. Nếu bạn đã học Objective C thì sẽ không xa lạ với protocol, thế nhưng protocol trong Swift thì sao? Có gì giống và khác với protocol trong Objective hay không?


Protocol là gì


Protocol là thành phần trừu tượng cho phép bạn khai báo danh sách các phương thức và thuộc tính nhưng không cài đặt các phương thức này.

Protocol được sử dụng làm lớp cơ sở cho bất kỳ class, struct, enum nào cũng có thể áp dụng thực thi. Class, struct, enum áp dụng protocol sẽ cài đặt các phương thức được khai báo trong protocol.

Cú pháp khai báo và thực thi protocol

Việc khai báo protocol cũng tương tự như bạn khai báo một class, bạn tuân thủ theo cú pháp sau:
Protocol trong SwiftTương tự, để áp dụng thực thi một protocol bạn sử dụng toán tử “:” tương tự việc kế thừa:
Protocol trong SwiftHai cú pháp trên bạn có thấy quen không nào? Rất giống việc khai báo class và thực hiện kế thừa cho class phải không? Thực tế thì làm việc với protocol cũng tương tự như làm việc với class thôi bạn ạ. Chỉ khác là bạn sẽ không cần phải cài đặt các phương thức của protocol mà bạn đã khai báo.

Ví dụ

Chúng ta sẽ cùng nhau xây dựng protocol StreetLegal như hình minh hoạ bên dưới:
Protocol trong SwiftMình sẽ mô tả sơ đồ trên một xíu nhé. StreetLegal là protocol khai báo qui tắc luật giao thông đường bộ chung cho các phương tiện bộ hành.

  • Lớp Car, Bicycle, Pedestrian sẽ áp dụng thực thi protocol StreetLegal.
    Lưu ý: luật đường bộ của Car sẽ khác BicyclePedestrian vì vậy bạn sẽ cần định nghĩa qui tắc luật đường bộ riêng cho phù hợp với mỗi loại phương tiện này.
  • BoatCar cũng là phương tiện nhưng Boat là phương tiện đường thuỷ nên không thể sử áp dụng qui tắc đường bộ như Car.

Thuộc tính và phương thức


Bây giờ, chúng ta hãy cùng nhau tìm hiểu cách thức khai báo thuộc tính và phương thức cho protocol bằng cách làm luôn ví dụ ở trên nhé.

Khai báo thuộc tính

Việc khai báo thuộc tính cho protocol tương tự như khai báo thuộc tính cho class. Tuy nhiên, protocol yêu cầu chỉ rõ thuộc tính read-only hay thuộc tính thông thường.

Ví dụ: mình sẽ xây dựng protocol StreetLegal và khai báo thuộc tính như sau.
Protocol trong SwiftCách thức khai báo tương tự class, ngoại trừ việc bắt buộc phải chỉ định set/get. Bạn hãy lưu ý những phần mình ghi chú trong ví dụ trên nhé. Những ghi chú đó là những gợi ý để giúp bạn xác định nên khai báo thuộc tính là hằng hay biến.

Khai báo phương thức

Khai báo phương thức trong protocol tương tự khai báo hàm thông thường, nhưng không cài đặt. Việc cài đặt các phương thức này sẽ được class/struct/enum nào áp dụng thực hiện.

Ngoài ra, protocol cũng cho phép khai báo phương thức mutating để hỗ trợ người dùng thực hiện việc thay đổi giá trị nội tại của class/struct/enum thực thi protocol.

Ví dụ: mình sẽ tiếp tục khai báo phương thức cho protocol StreetLegal như sau.
Protocol trong Swift

Áp dụng thực thi protocol

Bây giờ chính là lúc để bạn thử sử dụng protocol StreetLegal đã được khai báo ở 02 phần trên. Nhìn lại sơ đồ trên, chúng ta sẽ có 03 class Car, Bicycle, Pedestrian sẽ áp dụng protocol StreetLegal. Bây giờ mình sẽ làm mẫu một class, sau đó bạn hãy thử làm tiếp với hai class còn lại.

Ví dụ: mình sẽ xây dựng lớp Bicycle áp dụng protocol StreetLegal như sau.
Protocol trong SwiftBạn thấy không, class Bicycle áp dụng protocol StreetLegal do đó class này cần phải thực hiện cài đặt nội dung cho các phương thức mẫu của protocol StreetLegal. Đồng thời bạn cũng có thể thiết lập giá trị cho các thuộc tính của protocol StreetLegal tại đây. Tương tự, bạn hãy thực hiện xây dựng class CarPedestrian nhé.

Phương thức khởi tạo

Tương tự class, protocol trong Swift cũng cho phép bạn khai báo các phương thức khởi tạo (init) mẫu. Và bạn cũng cần lưu ý là, đối tượng nào (class/struct/enum) áp dụng protocol đều phải cài đặt các phương thức khởi tạo này.

Cú pháp khai báo cũng tương tự class, ví dụ:
Protocol trong SwiftLưu ý: class nào áp dụng protocol thì phải thêm từ khoá required khi cài đặt phương thức khởi tạo. Riêng struct/enum hoặc final class thì không cần. Ví dụ như sau:
Protocol trong Swift Ghi chú: final classclass không bao giờ có subclass (class con kế thừa).


Một số tính chất khác của protocol


Optional Protocol Requirements

Mặc định khi một class thực thi protocol thì phải cài đặt lại tất cả các thuộc tính và phương thức của protocol.

Vấn đề: giả sử protocol có quá nhiều phương thức và không phải phương thức nào cũng được sử dụng. Không lẽ chúng ta cũng phải cài đặt hết các phương thức không sử dụng đó luôn sao?
Giải pháp: Swift cho phép bạn cấu hình một số thuộc tính hoặc phương thức optional. Những thuộc tính hoặc phương thức này có thể được cài đặt hoặc không cần cài đặt trong đối tượng nào áp dụng protocol.

Để khai báo thuộc tính hoặc phương thức optional, bạn cần thêm từ khoá @objc optional trước protocol. Ví dụ:
Protocol trong SwiftTrong ví dụ trên, hàm signalRightTurn được khai báo là optional, do đó bạn có thể không cần cài đặt hàm này nếu muốn.

Protocol Extension

Tương tự như class, bạn cũng có thể tạo đối tượng extension để mở rộng bổ sung thêm thuộc tính hoặc phương thức cho một protocol nào đó.

Ví dụ: mình sẽ thử xây dựng extension để bổ sung thêm phương thức cho protocol StreetLegal như sau.
Protocol trong SwiftLưu ý: nếu bổ sung thêm phương thức cho protocol thì bạn phải cài đặt phương thức đó ngay trong extension.

Protocol Composition

Một đối tượng (class/struct/enum) nào đó cũng đều có khả năng áp dụng một hoặc nhiều protocol cùng lúc. Ví dụ:
Protocol trong SwiftTrong ví dụ trên, mình có 02 protocolNamedAged. Đồng thời mình xây dựng struct Person, và bạn hãy để ý là struct Person này áp dụng cả 02 protocol NamedAged cùng lúc. Mỗi một protocol ngăn cách nhau bởi dấu phẩy “,“.

Tính kế thừa

Mình tin rằng đọc tới đây, chắc nhiều bạn sẽ phải thốt lên rằng: “Protocol có thua kém gì class đâu, ngay cả tính kế thừa cũng có nữa mà.” Đúng vậy bạn ạ, một protocol cũng có thể được kế thừa lại từ một hoặc nhiều protocol khác tương tự như class.
Cú pháp:
Protocol trong SwiftBạn thấy không, với cú pháp trên, bạn sử dụng dấu “:” để thực hiện việc kế thừa cho protocol. Cách làm này hoàn toàn tương tự như kế thừa của class. Ngoài ra, bạn cũng có thể chỉ định protocol tạo ra chỉ giành riêng cho class (không cho phép struct/enum thực thi).
Cú pháp:
Protocol trong Swift

Các tính chất khác

  • Tương tự class, bạn có thể sử dụng toán tử is, as, as? để kiểm tra và ép kiểu protocol.
  • Protocol cũng là một kiểu dữ liệu, do đó bạn cũng có thể:
    • Khai báo biến, hằng, thuộc tính có kiểu là protocol.
    • Dùng protocol là kiểu dữ liệu đầu vào của tham số, kiểu trả ra của hàm đều được.
  • Để xem nội dung (cấu trúc) của một protocol nào đó (kể cả protocol hệ thống), bạn sử dụng phím cmd và click chuột trái vào tên protocol đó.

Tổng kết


Đến thời điểm này, mình tin rằng bạn đã có thể bắt tay vào lập trình iOS được rồi. Hoàn thành xong bài học này, mình tạm kết thúc chuỗi bài viết về lập trình Swift cơ bản. Tất nhiên là kiến thức về ngôn ngữ Swift vẫn còn chứ chưa hết đâu bạn nhé. Những bài viết sau bài này về Swift sẽ là những bài viết nâng cao hoặc là những thủ thuật trong lập trình Swift hoặc là những vấn đề lặt vặt khác liên quan tới Swift. Mình hy vọng rằng sẽ tiếp tục được bạn đón nhận, tuy nhiên để đi tiếp thì bạn cần phải hoàn thành các bài học về lập trình Swift cơ bản đã nhé.

Khu vực Thảo luận

Viết bình luận

avatar