Swift là một dạng languague protocol-oriented programming (POP). POP không chỉ liên quan đến mỗi protocol mà còn mang nhiều ý nghĩa khác.
Với POP, ta phải thay đổi cả cách viết app cũng như thay đổi cách tiếp cận khi code.
POP không đơn giản chỉ là đổi cái tên từ OOP sang POP (vì Protocol ban đầu nghe có vẻ giống Interface trong OOP).
Loạt bài này, sẽ xem sự giống và khác nhau, ưu nhược điểm của chúng?
Thay vì bắt đầu với hệ thống phân cấp lớp, với POP ta nên bắt đầu với protocol. Nó gần như là xương sống của 1 dự án dùng POP.
Trong POP, bất cứ type nào conforms 1 protocol nào đó phải chắc chắn implement tất cả những yêu cầu mà được định nghĩa bởi protocol đó. Nếu không thì ta sẽ bị compile-time error.
Class, Structure, or Enumeration đều có thể conform 1 protocol.
Hiện giờ, Swift và các thư viện chuẩn của nó đều đã thực hiện POP. Do đó việc hiểu rõ và áp dụng vào app là điều gần như phải làm.
b.1 Khai báo property
CẦN | KHÔNG CẦN |
- read-only or a read-write - chỉ rõ type của property's type vì ta không thể dùng type inference trong một protocol - có thể khai báo static. | The protocol KHÔNG CẦN KHAI BÁO NÓ LÀ stored or computed. Vì việc khai báo chi tiết để cho phần implementation. |
Ví dụ:
protocol FullName { var firstName: String {get set} var lastName: String {get set} static var typeProperty: String {get} }
{get set} -> read & write
{get} -> read only
{set} -> write only
b.1 Khai báo function
CẦN | KHÔNG CẦN |
- Khai báo tên hàm và return value - Có thể khai báo static | - { } và body bên trong. - giá trị default của argument. |
- Đối với việc sử dụng hàm để thay đổi instance cho Struct và Enum, ta dùng mutating keyword. Không áp dụng cái này cho class.
protocol FullName { var firstName: String {get set} var lastName: String {get set} static var typeProperty: String {get} func getName() -> String mutating func updateFirstName() }
c. Khai báo Optionals
Khi mà ta cần khai báo property hoặc func mà không bắt buộc implement. Ta dùng @objc optional trước các giá trị đó
@objc protocol Phone { var phoneNumber: String {get set} @objc optional var emailAddress: String {get set} func dialNumber() @objc optional func getEmail() }
- Giống như kế thừa trong class, protocol cũng có thể kế thừa được.
- Không giới hạn số protocol kế thừa
protocol A {} protocol B {} protocol C: A, B {}
Bất cứ type nào muốn conform thì chỉ cần conform C là đủ và không cần A,B nhưng nó phải implement các requirements từ A, B, C.
Xem ví dụ sau:
class Athletic { var name } class Pro: Athletic { var paid } class Amateur: Athletic { var collegue }
Bây giờ ta muốn có ProFootballer, AmateurFootballer, AmateurBasketball, ProBasketball thì
class ProFootballer: Pro { var run } class AmateurFootballer: Amateur { var run } class ProBasketball: Pro { var shoot } class AmateurBasketball: Amateur { var shoot }
Đã xuất hiện code duplicate. Nếu dùng protocol, ta có thể tách ra thành nhiều phần khác nhau. Lưu ý check cẩn thận nếu không sẽ có nhiều protocol mà chỉ có 1 vài property sẽ rất phí.