Swift的Protocol

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
    }
}

 

posted @ 2018-08-20 14:57  hongsheng  阅读(484)  评论(0编辑  收藏  举报