第四周第一天

第四周第一天

协议,协议的语法

protocol Flyable {
    func fly()
}

protocol Fightable {
    func fight()
}

协议是方法的集合(计算属性相当于就是方法)
// 可以把看似不相关的对象的公共行为放到一个协议中
// 协议在Swift开发中大致有三种作用:
// 1. 能力 - 遵循了协议就意味着具备了某种能力
// 2. 约定 - 遵循了协议就一定要实现协议中的方法
// 3. 角色 - 一个类可以遵循多个协议, 一个协议可以被多个类遵循, 遵循协议就意味着扮演了某种角色, 遵循多个协议就意味着可以扮演多种角色
// Swift中的继承是单一继承(一个类只能有一个父类), 如果希望让一个类具备多重能力可以使用协议来实现(C++里面是通过多重继承来实现的, 这是一种非常狗血的做法)
协议的继承

class Boxer: Fightable {
    @objc func fight() {
        print("正在进行格斗.")
    }
}
class Bird: Flyable {

    func fly() {
        print("鸟儿扇动翅膀飞行.")
    }
}
class Airplane: Flyable {
    func fly() {
        print("飞机依靠空气动力学原理飞行.")
    }
}

协议的拓展也可以说协议的默认实现当在类中没有实现这个方法默认实现的方法
协议扩展 - 可以在协议扩展中给协议中的方法提供默认实现
也就是说如果某个类遵循了协议但是没有实现这个方法就直接使用默认实现
那么这个方法也就相当于是一个可选方法(可以实现也可以不实现)


extension Fightable {
    func fight() {
        print("正在打架")
    }
}

依赖倒转原则(面向协议编程)

  1. 声明变量的类型时应该尽可能使用协议类型
  2. 声明方法参数类型时应该尽可能使用协议类型
  3. 声明方法返回类型时应该尽可能使用协议类型
    协议的组合
let array: [protocol<Flyable, Fightable>] = [
    // Rocket(),
    // Bird(),
    Superman(),
    // Boxer()
    // Airplane()
]
//只有同时满足两个协议的类才可以
for obj in array {
    obj.fly()
    obj.fight()
}

协议中全是抽象概念(只有声明没有实现) 遵循协议的类可以各自对协议中的计算属性和方法给出自己的实现版本 这样当我们面向协议编程时就可以把多态的优势发挥到淋漓尽致 可以写出更通用更灵活的代码(符合开闭原则)

实现开闭原则最关键有两点:

  1. 抽象是关键(在设计系统的时候一定要设计好的协议);
  2. 封装可变性(桥梁模式 - 将不同的可变因素封装到不同的继承结构中)

接口(协议)隔离原则: 协议的设计要小而专不要大而全
协议的设计也要高度内聚

protocol Shape {
    var perimeter: Double { get }
    var area: Double { get }
    func draw()
}
class Triangle: Shape {
    var a: Double
    var b: Double
    var c: Double
    
    init(a: Double, b: Double, c: Double) {
        assert(a + b > c && b + c > a && a + c > b, "不能构成三角形")
        self.a = a
        self.b = b
        self.c = c
    }
    
    var perimeter: Double {
        get { return a + b + c }
    }
    
    var area: Double {
        get {
            let half = perimeter / 2
            return sqrt(half * (half - a) * (half - b) * (half - c))
        }
    }
    
    func draw() {
        print("△")
    }
    
}

协议的应用

#### //图书类的定义
import Foundation

/// 图书
class Book {
    var name: String
    var price: Double
    var type: String
    
    // 四人帮设计模式 - 策略模式
    var strategy: DiscountStrategy?
    
    /**
     初始化方法
     - parameter name:  书名
     - parameter price: 价格
     - parameter type:  类型
     */
    init(name: String, price: Double, type: String) {
        self.name = name
        self.price = price
        self.type = type
    }
    
    /// 减多少钱
    var discountValue: Double {
        get {
            if let s = strategy {
                return s.discount(price)
            }
            else {
                return 0
            }
        }
    }
    
    /// 折后价格
    var discountedPrice: Double {
        get { return price - discountValue }
    }
}


#### //写协议部分
import Foundation

/**
 *  打折策略协议
 */
protocol DiscountStrategy {
    
    /**
     计算折扣
     - parameter price: 原价
     - returns: 折扣的金额
     */
    func discount(price: Double) -> Double
}

/// 百分比折扣策略
class PercentageDiscount: DiscountStrategy {
    var percentage: Double
    
    init(percentage: Double) {
        self.percentage = percentage
    }
    
    func discount(price: Double) -> Double {
        return price * (1 - percentage)
    }
}

// 固定金额折扣策略
class FixedDiscount: DiscountStrategy {
    var fixedMoney: Double
    
    init(fixedMoney: Double) {
        self.fixedMoney = fixedMoney
    }
    
    func discount(price: Double) -> Double {
        return price >= fixedMoney ? fixedMoney : 0
    }
}

// 分段折后策略
class SegmentedDiscount: DiscountStrategy {
    
    func discount(price: Double) -> Double {
        if price < 20 {
            return 0
        }
        else if price < 50 {
            return 3
        }
        else if price < 100 {
            return 10
        }
        else {
            return 30
        }
    }
}
#### //实现和调用部分

import Foundation

let booksArray = [
    Book(name: "C语言程序设计", price: 24.0, type: "计算机"),
    Book(name: "名侦探柯南", price: 98.5, type: "漫画"),
    Book(name: "Swift从入门到住院", price: 35.8, type: "计算机"),
    Book(name: "黄冈数学密卷", price: 34.2, type: "教材"),
    Book(name: "中国股市探秘", price: 58.5, type: "金融")
]

let discountDict: [String: DiscountStrategy] = [
    "计算机": PercentageDiscount(percentage: 0.78),
    "教材": PercentageDiscount(percentage: 0.85),
    "漫画": SegmentedDiscount(),
    "科普": FixedDiscount(fixedMoney: 2)
]

var totalPrice = 0.0
var totalDiscount = 0.0
for book in booksArray {
    if let strategy = discountDict[book.type] {
        book.strategy = strategy
    }
    print("《\(book.name)》原价: ¥\(book.price)元")
    print("《\(book.name)》折后价: ¥\(book.discountedPrice)元")
    totalPrice += book.discountedPrice
    totalDiscount += book.discountValue
}

print(String(format: "总计: ¥%.1f元", totalPrice))
print(String(format: "为您节省了: ¥%.1f元", totalDiscount))


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,045评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,114评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,120评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,902评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,828评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,132评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,590评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,258评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,408评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,335评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,385评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,068评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,660评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,747评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,967评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,406评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,970评论 2 341

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,566评论 18 139
  • 1.项目经验 2.基础问题 3.指南认识 4.解决思路 ios开发三大块: 1.Oc基础 2.CocoaTouch...
    阳光的大男孩儿阅读 4,966评论 0 13
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 3,766评论 1 10
  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,678评论 0 9
  • 在工作,恋爱,以及种种方面我们总会处于被动的局面中。矛盾与焦虑也会随之产生。这个时候你要如何去做? 当上司要求你加...
    城中听雨阅读 870评论 4 6