POP - Part 2

1. Use Protocols as a type

Mặc dù không có chức năng cụ thể, protocols vẫn có thể được sử dụng giống như các loại khác tương tự. Tức là, ta có thể sử dụng như:

- Parameters

- Return types của 1 function

- Variables

- Constants

- Collections.

Hãy xem ví dụ sau: 
                                                
protocol Person {     
  var firstName: String {get set}     
  var lastName: String {get set}     
  var birthDate: Date {get set}     
  var profession: String {get}     
  init (firstName: String, lastName: String, birthDate: Date)
}                                   

 a. Sử dụng như 1 parameter, return type, array hoặc 1 type

func updatePerson(person: Person) -> Person {
  var newPerson: Person
  // Code to update person goes here
  return newPerson
  }
                                                
var personArray = [Person]()   

var personDict = [String: Person]()

b. Sử dụng bằng tính chất đa hình

Giả sử ta có hai class SwiftProgrammer và FootballPlayer đã conforms Person                                                
var myPerson: Person                   
myPerson = SwiftProgrammer(firstName: "Jon", lastName: "Hoffman", birthDate: birthDateProgrammer)
myPerson = FootballPlayer(firstName: "Dan", lastName: "Marino", birthdate:birthDatePlayer)

c. Hoặc đa hình trong array:

                                                
var programmer = SwiftProgrammer(firstName: "Jon", lastName: "Hoffman",                                    birthDate: bDateProgrammer)
var player = FootballPlayer(firstName: "Dan", lastName: "Marino",                               birthDate: bDatePlayer)             
var people: [Person] = [] 
people.append(programmer) 
people.append(player)
 Rất hay phải không ạ?


2.  Polymorphism (tính đa hình)

Như những ví dụ trên, ta thấy tính đa hình rất hiệu quả và phần này ta nên tự suy nghĩ sẽ thấm hơn. Một vài lưu ý quan trọng khác: 

Với mảng people trên, bạn không thể truy cập vào property của programmer bởi vì nó không được định nghĩa trong People protocol. 

Để truy cập được, bạn cần phải checking và casting. Có keyword quan trọng

- Keyword is: true nếu đúng, false nếu sai            

if person is SwiftProgrammer {     
  print("(person.firstName) is a Swift Programmer")
}                                   
                                                
for person in people where person is SwiftProgrammer {     
  print("(person.firstName) is a Swift Programmer")
}                                   


- Keyword as?: trả về type đó nếu đúng và nil nếu sai

                                                
if let _ = person as? SwiftProgrammer {     
  print("(person.firstName) is a Swift Programmer") 
}


2. Associated types with protocols
                

An associated type sẽ cho chúng ta 1 cái tên tạm thời để thay thế cho các type. Cái type thực sự sẽ được khai báo khi mà cái protocol đó được adopted. Và người conform protocol đó phải có nhiệm vụ khai báo cụ thể nó.
                  

Dùng keyword associatedtype để khai báo. 

                                                
protocol Queue {     
  associatedtype QueueType     
  mutating func addItem(item: QueueType)     
  mutating func getItem() -> QueueType?     
  func count() -> Int
}                                   
 Trong phần này, ta dùng QueueType như là một parameter và return type.


struct IntQueue: Queue {
     var items = [Int]()
     mutating func addItem(item: Int) { items.append(item) }
     mutating func getItem() -> Int? {
       if items.count > 0 { return items.remove(at: 0) }
       else { return nil }
      }
     func count() -> Int { return items.count }
}

Tronng ví dụ trên, ta đã implemented Queue protocol theo cách non-generic. Generics cho phép ta sử dụng tại run time thay vì compile time. 

- run time là có thể apply generic, tức là dùng với type thật sự sau khi đã run code.

- compile time là apply trước, kiểu như hard-code zậy.

3. Delegation

Đây gần như là cái cực kì phổ biến. Một instance của lớp nào đó hành động thay (làm gìum) cho một instance khác. 

protocol DisplayNameDelegate {
  func displayName(name: String)
}


struct Person {
  var displayNameDelegate: DisplayNameDelegate?
  var firstName = "" {
    didSet {
      displayNameDelegate?.displayName(name: getFullName())
    }
  }
  var lastName = "" {
    didSet {
      displayNameDelegate?.displayName(name: getFullName())
    } }
  init() {}
  func getFullName() -> String {
    return "\(firstName) \(lastName)"
  }
}


struct MyDisplayNameDelegate: DisplayNameDelegate {
  
  func displayName(name: String) {
    print("Name: \(name)")
  }
}


var displayDelegate = MyDisplayNameDelegate()
var person = Person()
person.displayNameDelegate = displayDelegate
person.firstName = "a"
person.lastName = "Hoffman"

didSet được xem như là một property observers.

Bình luận
* Các email sẽ không được công bố trên trang web.
I BUILT MY SITE FOR FREE USING