import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. var person = Person(); print("person.height==(person.height)"); print("person.weight==(person.weight)"); person.height = 200; print("person.height==(person.height)"); //可以更改(但在以前版本的Swift中是不能直接这样更改的) //weight没有set方法 person.weight = 300; //当我们把person从Person转换成PersonProtocol时 他就是只读的了 //(person as PersonProtocol).weight = 120; print("person.weight==(person.weight)"); //protocol extension let p = Point(x: 10, y: 10) print(p) // Point(x: 10, y: 10) // 创建遵守 PersonProperty 的自定义类型 let p2 = Person2(height: 178, weight: 61.5) // 那么 p 这个自定义类型 天生就有判断这个人身高体重是否合格的方法 p2.isStandard() // false } } /* 1、某个class、struct或者enum要遵守这种约定的话,需要实现约定的方法 2、protocol中的约定方法,当方法中有参数时是不能有默认值的 3、protocol中也可以定义属性,但必须明确指定该属性支持的操作:只读(get)或者是可读写(get set) 4、当protocol中定义了一个只读属性,其实我们也可以在遵守该约定的类型中完成该属性的可读可写 5、如何定义可选的protocol属性或者方法? protocol 前加@objc 方法名或属性前加optional 如果想提供可选的约定方法或者属性那么只能定义@objc的protocol 并且这种约定只能class能遵守 6、protocol可以继承,当然struct、class、enum都可以同时遵守多个约定 */ protocol PersonProtocol { var height: Int { get set } var weight: Int { get } func getName() func getSex() func getAge(age: Int) } struct Person: PersonProtocol { var height = 178 var weight = 120 func getName() { print("MelodyZhy") } func getSex() { print("boy") } func getAge(age: Int) { print("age = (age)") } } /*********************** protocol extension ************************/ //能在 protocol extension 方法中获取 protocol 的属性 struct Point { var x: Int var y: Int } // 如果我们想让打印界面变成 x = 10, y = 10 // 那么我们就要遵守 CustomStringConvertible 这个 protocol extension Point: CustomStringConvertible { // 这个 protocol 只有一个约定定义一个名为description的属性 var description: String { return "x = (self.x), y = (self.y)" } } /********************* 例子 ***********************/ // 定义一个人属性的 protocol protocol PersonProperty { var height: Int { get } // cm var weight: Double { get } // kg // 判断体重是否合格的函数 func isStandard() -> Bool } extension PersonProperty { // 给 protocol 添加默认的实现 func isStandard() -> Bool { print("测试1"); return self.weight == 100 } } struct Person2: PersonProperty { var height: Int var weight: Double // 如果自定义类型里面创建了遵守的 protocol 中的方法 // 那么他将覆盖 protocol 中的方法 // func isStandard() -> Bool { // print("测试2"); // return true // } } /*************** type constraints nonononono************/ //这相当于给 protocol extension 中的默认实现添加限定条件,写法如下 // 运动因素的 protocol protocol SportsFactors { // 运动量 var sportQuantity: Double { get } } // 下面这种写法就用到了 extension 中的 type constraints // 意思是 只有同时遵守了 SportsFactors 和 PersonProperty 时 // 才使 PersonProperty 获得扩展 并提供带有 sportQuantity 属性的 isStandard 方法 extension PersonProperty where Self: SportsFactors { func isStandard() -> Bool { print("测试3"); return true } }