本文讲的是Swift 面向协议编程入门,

面向对象编程的思想没毛病,但老铁你可以更 666 的

上图这个人不是我,但这就是使用面向协议编程替换掉面向对象编程之后的感觉。

介绍

这个教程也是为了那些不知道类和结构体根本区别的人写的。我们都知道在结构体里是没有继承的,但是为什么没有呢?

如果你不知道上面问题的答案,那么花几秒钟看下下面的代码。请再次原谅我的排版,我已经让它尽可能的简单明了了。

注:译者已经改过排版了

class HumanClass {var name: Stringinit(name: String) {self.name = name}
}var classyHuman = HumanClass(name: "Bob")
classyHuman.name // "Bob"var newClassyHuman = classyHuman // Created a "copied" objectnewClassyHuman.name = "Bobby"
classyHuman.name // "Bobby"

当我把 newClassyHuman 的 name 属性设为 “Bobby” 之后,原来对象 classyHuman 的 name 属性也会变成 “Bobby” 。

现在,让我们来看一下结构体的情况。

struct HumanStruct {var name: String
}var humanStruct = HumanStruct(name: "Bob" )
var newHumanStruct = humanStruct // Copy and pastenewHumanStruct.name = "Bobby"
humanStruct.name // "Bob"

你看到它们的不同之处了么?对拷贝出来的对象的 name 属性的改变并没有影响到原有的 humanStruct 对象。

在类中,当你对一个变量进行拷贝的时候,两个变量都指向内存中的同一个对象。两个中的任何一个变量中的改变都会影响另外一个变量(引用类型)。然而在结构体中,你是通过创建了一个新的对象(值类型)来实现简单的拷贝和复制的。

如果你还没有理解的话,试着把之前那一段再看一遍。如果还是不理解的话,你可以看下我做的这个视频。

结构体 vs 类课程

再见面向对象编程

你可能会很奇怪为什么我所讲的这些好像和面向协议编程的话题一点关系都没有。然而,在我讲使用面向协议编程替换面向对象编程的好处之前,是必须要理解引用类型和值类型的区别的。

使用面向对象编程当然有优点的,但是相对的缺点也存在。

  1. 当时构建子类的时候,你必须继承一些你不需要的属性和方法。你的对象变得不必要的虚胖。

  2. 当时使用了大量的父类(太多继承层级),在不同的类里面跳来跳去编写代码或者修复 bug 都会变得非常棘手。

  3. 因为对象都是指向内存中的同一个空间,如果你创建了一个拷贝,并且对它的属性进行了一点小改动,它会影响到其余的对象。(引用导致的易变性)

顺便说一下,来看一下 UIKit 框架是怎么用面向对象编程来写的。

如果你作为软件工程师第一次去苹果工作的话,你能使用这些代码么?我的意思是我们开发者在界面层使用中都有过很痛苦的经历。

有人说过面向对象编程就是通过模块化的模式来写意大利面条式的代码。如果你想找到更多关于面向对象编程的缺点的话,看这里的咆哮 1 、咆哮 2 、咆哮 3 、咆哮 4 。

欢迎使用面向协议编程

你可能已经猜到了,和类不一样的是,面向协议编程的基础是值类型。不再是引用了,和你之前看到的金字塔结构不一样,面向协议所提倡的是扁平化和去嵌套的代码。

可能会有点吓到你,我将引出的是苹果的定义。

“协议定义了方法、属性的蓝图…… 然后类、结构体或枚举类型都能够使用协议” — 苹果

你现在唯一需要记住的就是这个词语,“蓝图”。

协议就好像是一个篮球教练,他告诉他的队员该怎么做,但是他却不知道怎么扣篮。

真正的使用面向协议编程

首先,我们来生成人的蓝图。

protocol Human {var name: String { get set }var race: String { get set }func sayHi()
}

就像你看到的,在协议里是没有真正的”扣篮“。它只会告诉你有那么个东西的存在。顺便说一下,现在你不需要担心 { get set } 。它只是表示你可以改变这个属性的值并能够获取这个属性。除非你用的是一个计算属性话,现在是不用担心的。

现在让我们通过这个协议来写一个韩国人  结构体

struct Korean: Human {var name: String = "Bob Lee"var race: String = "Asian"func sayHi() {print("Hi, I'm \(name)") }
}

一旦这个结构体采用了人类这个协议,它就必须”遵循”这个协议,实现它的所有属性和方法。如果不这么做的话, Xcode 会警报,当然左边也会报错  。

就像你看到的,为了满足蓝图你能够自定义所有的协议。你甚至可以建造一个“围墙”。

当然,对美国人  来说也是一样的。

struct American: Human {var name: String = "Joe Smith"var race: String = "White"func sayHi() { print("Hi, I'm \(name)") }
}

是不是相当酷?看看不再使用 “init” 和 “override” 关键词之后你拥有了多少自由。它是不是开始变得有点意思了?

协议介绍课程

协议继承

如果你想创建一个继承人类协议蓝图的超人协议该怎么办呢?

protocol SuperHuman: Human {var canFly: Bool { get set } func punch()
}

现在,如果你想生成一个采用超人协议的结构体或者类的话,你必须也要让它满足人类的协议。

//  超过 9000
struct SuperSaiyan: SuperHuman {var name: String = "Goku"var race: String = "Asian"var canFly: Bool = truefunc sayHi() { print("Hi, I'm \(name)") }func punch() { print("Puuooookkk") }
}

那些理解不了的人,看下这个视频

当然,你可以像在类上面一样遵循多个协议。

// 例子
struct Example: ProtocolOne, ProtocolTwo { }

协议继承课程

协议扩展

现在,这是使用协议最强大的特点了,我不认为我需要讲太多。

// 会说英语的超级动物
protocol SuperAnimal {func speakEnglish()
}

给 SuperAnimal 增加一个扩展

extension SuperAnimal {func speakEnglish() { print("I speak English, pretty cool, huh?")}
}

现在,让我们来创建一个采用 SuperAnimal 协议的类。

class Donkey: SuperAnimal { }
var ramon = Donkey()
ramon.speakEnglish() //  "I speak English, pretty cool, huh?"

如果你使用扩展的话,你能够给类,结构体和枚举增加默认方法和属性。它难道不神奇么?我发现这是真正的金块啊。

顺带提一下,如果你没有理解的话,你可以看这个

Protocol Extension Lesson

协议作为类型 (Last)

如果我告诉你不需要类型修饰就能够生成一个既包含结构体对象又有类对象的数组呢?

就是这样。

我用为获得雌性配偶而打架的袋鼠来举个例子。如果你不相信我的话,看看这个袋鼠打架

protocol Fightable {func legKick()
}struct StructKangaroo: Fightable {func legKick() {print("Puuook")}
}class ClassKangaroo: Fightable { func legKick() {print("Pakkkk") }
}

来,我们生成两个袋鼠对象

let structKang = StructKangaroo()
let classKang = ClassKangaroo()

现在,你可以把它们放到一个数组里了。

var kangaroos: [Fightable] = [structKang, classKang]

厉害了我的哥,这是真的么? 看看这个

for kang in kangaroos {kang.legKick()
}
// "Puuook"
// "Pakkkk"

这个难道不巧妙么?你在面向对象编程中怎么可能实现这个效果... 封面的图片是不是对你来说已经有意义了?面向协议编程纯粹是金子啊。

协议类型课程

现在是免费的,直到它发布之前:)

最后提示

如果你觉得这个教程有用的话,而且你认为我做了一个很棒的事情,请  我并且分享到你的社交圈中。我发誓,更多的 iOS 开发者都该应该使用面向协议编程 !我也在努力中,所以才写了这个文章,但是为了更大的影响我需要你的支持。

公开感谢

特别感谢那些参与和指出各处问题的人们。Kilian Költzsch , Erik Krietsch, Özgür Celebi , Sanchika Singh Rana, Frederick C. Lee ,moh tabi , october hammer , Anthony Kersuzan , Kenneth Trueman , Wilson Balderrama , Rowin , Quang Dinh Luong , Oren Alalouf , Peter Witham , Victor Tong.

预告

这个周六,我将写一些关于在 Swift 3 中如何通过协议实现代理的设计模式的东西。有些人让我写这个,所以我决定听你们的。如果你想要快速更新或者请求我的文章的话,你可以关注我Facebook Page,那里我和我的读者有很多的互动。再见!





原文发布时间为:2017年2月3日

本文来自云栖社区合作伙伴掘金,了解相关信息可以关注掘金网站。

Swift 面向协议编程入门相关推荐

  1. Swift 面向协议编程 基础篇 (一) 介绍

    前言 好久没有写文章了,期末复习周也到了.在复习的同时顺便开了一个专题,面向协议编程,[ 基础篇 ],[ 进阶篇 ],[ 实践篇 ]. 介绍 首先,面向对象(OOP)大家并不陌生,苹果的很多框架都是以 ...

  2. Swift 面向协议编程的那些事

    一直想写一些 Swift 的东西,却不知道从何写起.因为想写的东西太多,然后所有的东西都混杂在一起,导致什么都写不出来.翻了翻以前在组内分享的一些东西,想想把这些内容整理下,写进博客吧.我对计划要写的 ...

  3. 知道swift为什么是面向协议编程么?不知道,还不快来学习!

    swift为什么是面向协议编程 面向协议编程 (Protocol Oriented Programming) 是 Apple 在 2015 年 WWDC 上提出的 Swift 的一种编程范式. 面向协 ...

  4. 面向协议编程与 Cocoa 的邂逅(上)

    作者简介: 王巍(@onevcat),江湖人称"喵神",iOS 和 Unity3D 开发者,旅居日本,目前供职于 LINE,著有<Swifter - 100 个 Swift ...

  5. 大型Web前端架构设计:面向抽象编程入门

    面向抽象编程,是构建一个大型系统非常重要的参考原则. 但对于许多前端同学来说,对面向抽象编程的理解说不上很深刻.大部分同学的习惯是 拿到需求单和设计稿之后就开始编写UI界面,UI里哪个按钮需要调哪些方 ...

  6. 大型 web 前端架构设计-面向抽象编程入门

    作者:svenzeng,腾讯 PCG 前端开发工程师 面向抽象编程,是构建一个大型系统非常重要的参考原则.但对于许多前端同学来说,对面向抽象编程的理解说不上很深刻.大部分同学的习惯是 拿到需求单和设计 ...

  7. swift3面向协议编程实现Alamofire封装

    1.原先的实现过程我们一般使用的是Alamofire,对其单例封装 // // NetworkTools.swift // // Created by targetcloud on 2017/3/26 ...

  8. 面向协议与面向对象的区别

    面向对象的设计和面向协议的设计都使用了多态让我们使用同样的接口来跟不同的类型进行交互.在面向对象的设计中,我们使用了基类提供的接口来跟所有的子类进行交互.在面向协议的设计中,我们使用了协议和协议扩展提 ...

  9. spring中AOP(面向切面编程)

    spring中AOP(面向切面编程) 面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是spring框架中的一个重要内容 ...

  10. JAVA入门Hwork,HBase Java编程入门教程

    一款优秀的数据库除了会提供客户端,还会提供编程语言接口,HBase 也不例外.HBase 除了支持使用 Shell 客户端来操作(请看<HBase Shell及其常用命令>),还提供了多种 ...

最新文章

  1. Javascript 取小数点后面N位
  2. Count Color(poj 2777)
  3. golang 文件 文件夹 创建 读取 移动 复制 写入 遍历
  4. Android Studio中mac上面的安装
  5. 今天试了一下iscroll
  6. C#条件运算符if-else的简化格式
  7. 中标麒麟/NeoKylin 安装QT开发环境
  8. python如何运行一个python程序_在python中,如何运行一个命令行程序,它在发送Ctrl+D之前不会返回...
  9. @encode(type)的使用
  10. Linux 文件相关的常用命令
  11. Comprehensive Python Cheatsheet
  12. 显示隐藏-visibility(HTML、CSS)
  13. 【转】20个Java 代码生成器
  14. 小米路由器刷 linux,小米路由器刷入Padavan系统
  15. 四阶龙格库塔法的基本思想_经典四阶龙格库塔法解1阶微分方程组.doc
  16. 基于SpringBoot的宠物医院管理系统JAVA MYSQL
  17. 计算机类文献综述如何写,应该如何撰写计算机类文献综述.doc
  18. java随机百分比_java随机百分比
  19. 微服务架构开发实战:什么是微服务的熔断机制和熔断的意义
  20. 「ROS Kinetic」发布速度消息cmd_vel

热门文章

  1. Google 再见 Java
  2. centos php mongodb 驱动,安装 MongoDB PHP 驱动 在CentOS 6.x和遇到的问题
  3. python速学_【Python杂货铺】速学python基础
  4. java前端 js弹出框_前端js弹出框组件使用方法
  5. as5300g2 nas软件功能_浪潮AS5300G2 5500G2存储2U12
  6. python爬虫哪个选择器好用_Python爬虫学习8-css选择器使用
  7. 视觉中国被连夜约谈后再次致歉;京东高管:下一步将向总监“开刀”;华为P30价格公布 | 雷锋早报...
  8. java编程思想(注释文档)
  9. macOS IKPictureTaker 图片选择器
  10. hdu 1811 Rank of Tetris 并查集+拓扑排序