Download presentation
Presentation is loading. Please wait.
1
Ch16. 協定
2
16.1 屬性的協定 屬性的協定大都宣告為變數的屬性,所以前面會有var關鍵字。型 態宣告後以{get set}分別表示取得和設定之屬性。
3
範例程式 // property requirement protocol EnglishName {
var name: String {get set} } struct Person: EnglishName { var name: String var someone = Person(name: "Bright") print(someone.name) someone.name = "Linda"
4
輸出結果 Bright Linda
5
16.2 方法的協定 方法的協定只是一個方法的雛型或稱藍圖,當某一類別、結構或 列舉採納了此方法的協定後,必須加以實作此雛型的主體。
6
範例程式 protocol Area { mutating func getArea(r: Double) -> Double }
// struct not a class struct Circle: Area { var radius = 0.0 mutating func getArea(r: Double) -> Double { radius = r return radius * radius * // circleObject must be a var var circleObject = Circle() print("圓形面積: \(circleObject.getArea(r: 10))")
7
輸出結果 圓形面積:
8
16.3 當做型態的協定 協定也可以當做變數的型態。
9
範例程式part1 // protocol as type protocol Area {
func getArea(r: Double) ->Double } class Circle: Area { var radius = 0.0 func getArea(r: Double) -> Double { radius = r return radius * radius * class Cylinder { var height: Int var calculateVolume: Area init(height: Int, calculateVolume: Area) { self.height = height self.calculateVolume = calculateVolume func volume() -> Double { return calculateVolume.getArea(r: 10.0) * Double(height)
10
範例程式part2 let cylinderObject = Cylinder(height: 10, calculateVolume: Circle()) print(cylinderObject.volume())
11
輸出結果
12
16.4 以延展加入協定 也可以將協定以延展的方式加入於類別或結構。
13
範例程式part1 // extension protocol Description {
func information() -> String } protocol Area { func getArea(r: Double) -> Double class Circle: Area { var radius = 0.0 func getArea(r: Double) -> Double { radius = r return radius * radius * class Cylinder { var height: Int var calculateVolume: Area init(height: Int, calculateVolume: Area) { self.height = height self.calculateVolume = calculateVolume func volume() -> Double { return calculateVolume.getArea(r: 10.0) * Double(height)
14
範例程式part2 extension Cylinder: Description {
func information() -> String { return "Voluem of Cylinder:" } let cylinderObject2 = Cylinder(height: 10, calculateVolume: Circle()) print(cylinderObject2.information()) print(cylinderObject2.volume())
15
輸出結果 Voluem of Cylinder:
16
16.5 協定的繼承 協定也可以繼承。以下程式有一協定Description,如下所示: protocol Description {
16.5 協定的繼承 協定也可以繼承。以下程式有一協定Description,如下所示: protocol Description { func information() -> String } 之後又定義協定FullyDescription,其繼承協定Description,此稱為 協定繼承 (protocol inheritance) 如下所示: protocol FullyDescription: Description { func fullyinformation() -> String
17
範例程式part1 protocol Description { func information() -> String }
class Cylinder { var height: Int init(height: Int) { self.height = height extension Cylinder: Description { func information() -> String { return "Voluem of Cylinder:" protocol FullyDescription: Description { func fullyinformation() -> String extension Cylinder: FullyDescription { func fullyinformation() -> String { var output = information() output += " A" return output
18
範例程式part2 let cylinderObject3 = Cylinder(height: 20)
print(cylinderObject3.information()) print(cylinderObject3.fullyinformation())
19
輸出結果 Voluem of Cylinder: Voluem of Cylinder: A
20
16.6 協定的組合 若一型態要遵從多個協定時,就得利用協定組合 (protocol composition)。
16.6 協定的組合 若一型態要遵從多個協定時,就得利用協定組合 (protocol composition)。 遵從多個協定的格式為name: Someprotocol, Anotherprotocol,將 多個協定以逗號隔開。 協定的組合,則以&串連之。
21
範例程式 // protocol composition protocol Named {
var name: String {set get} } protocol Department { var department: String {set get} struct Person: Named, Department { var name: String var department: String func status(who nameDepartment: Named & Department) { print("\(nameDepartment.name) majors in \(nameDepartment.department)") let whoAmI = Person(name: "Jennifer", department: "foreign language") status(who: whoAmI) print()
22
輸出結果 Jennifer majors in foreign language
23
16.7 檢查是否有遵從協定 如何檢查實例是否遵從協定,有三種運算子可加以使用。
16.7 檢查是否有遵從協定 如何檢查實例是否遵從協定,有三種運算子可加以使用。 is運算子判斷實例是否遵從協定,若是,則回傳true,否則回傳 false。 as? 運算子若遵從協定,則回傳選項值,否則回傳nil。 as運算子和as? 相似,但若沒遵從協定時,在執行時期將會產生 錯誤。
24
範例程式part1 // checking for protocol conformance protocol GetArea {
var area: Double {get} } class Circle: GetArea { var radius: Double init(radius: Double) { self.radius = radius var area: Double { return radius * radius * class Rectangle: GetArea { var width: Double var height: Double init(width: Double, height: Double) { self.width = width self.height = height return width * height
25
範例程式part2 class What { var message: String init(message: String) {
self.message = message } let objects: [AnyObject] = [ Circle(radius: 20.0), Rectangle(width:10, height: 20), What(message: "I Want to buy iPhone 6") ] for object in objects{ print(object is GetArea) for object in objects { if let objectArea = object as? GetArea { print("面積為: \(objectArea.area)") } else { print("此物件無計算面積方法")
26
輸出結果 true false 面積為: 面積為: 此物件無計算面積方法
27
16.8 JSON的編碼和解碼 Swift 4簡化了整個JSON壓縮和解壓縮的過程。
只需要將自定的類別,繼承Codable協定 ,之後利用encode和 decode方法,就可輕易的完成。
28
範例程式 class Book: Codable { let title: String let author: String
let publishing: String init(title: String, author: String, publishing: String) { self.title = title self.author = author self.publishing = publishing } let book = Book(title: "學會Swift 4的24堂課", author: "蔡明志", publishing: "碁峯資訊股份有限公司") let encoder = JSONEncoder() let gotop = try encoder.encode(book) let string = String(data: gotop, encoding: .utf8) let decoder = JSONDecoder() let article = try decoder.decode(Book.self, from: gotop) let output = "\(article.title) \(article.author) \(article.publishing)"
29
輸出結果 學會Swift 4的24堂課 蔡明志 碁峯資訊股份有限公司
Similar presentations