很久沒有寫文章了,期末複習周也到了。在複習的同時順便開了一個專題,面向協議編程,[ 基礎篇 ],[ 進階篇 ],[ 實踐篇 ]。javascript
首先,面向對象(OOP)你們並不陌生,蘋果的不少框架都是以這種形式進行構建的,可是,蘋果很矯情,2015年WWDC來,鼓勵使用 Value Type 值類型,也引出了這麼一個話題Protocol Oriented Programming 面向協議編程方式。關於值類型和引用類型,能夠查看官方文檔或者這篇博客[推薦略看一下]java
OOP的發展已經不少年了,一直做爲一種主流,蘋果的框架也是在一層又一層的繼承搭建起來的,可是在水果已經在不斷地強調使用Protocol了,天然有它的緣由所在。編程
class
是引用類型,因此可能會出現一些引用計數,引用循環等問題,你必須處理好這些問題。「Instead of using a class, start with a protocol」.swift
引用蘋果官方文檔的說明,Protocol定義一張藍圖,而且能被class
,struct
,enum
繼承。並且,最重要的是支持多繼承的關係。app
A protocol defines a blueprint of methods, properties, and other requirements ... The protocol can then be adopted by a class, structure, or enumeration.框架
正好今早學校寵物節🐶,下面咱們定義一個Dog的協議。ide
struct Person {
var name: String
}
protocol Dog {
var name: String { get }
var owner: Person { get }
var age: Int { get }
}複製代碼
而後聲明一個struct
遵循該協議ui
struct Husky: Dog {
let name: String // 實例的name不能修改
let owner: Person
var age: Int
// 不須要init( ) 也不須要override
// init(name: String, owner: Person, age: Int) {
// self.name = name
// self.owner = owner
// self.age = age
// }
}複製代碼
咱們的狗狗在寵物節是要去參加比賽的,因此咱們定義一個Playable的協議spa
protocol Playable {
var GameName: String { get }
func playGame()
}複製代碼
咱們知道在OOP的世界裏,是不支持多繼承的關係的。Protocol的出現直接修補了這個DrawBack。code
咱們組合一下兩個協議
protocol DogCanPlay: Dog, Playable { }複製代碼
接下來聲明一個struct
遵循這個協議,這樣這個struct就擁有了這兩個協議的全部屬性和方法,並且,編譯器還會告訴你,你缺乏哪一個屬性,哪一個方法沒有聲明,很是方便。
struct PlayableDog: DogCanPlay {
var name: String
var owner: Person
var age: Int
func playGame() {
print("biubiubiu~")
}
var GameName: String
}複製代碼
協議的組合原理也是多繼承的關係,上面的代碼也能夠這麼寫
struct PlayableDog: Dog, Playable {
var name: String
var owner: Person
var age: Int
func playGame() {
print("biubiubiu~")
}
var GameName: String
}複製代碼
不得不說,自Swift 2.0後,協議擴展【Protocol Extension】的出現,讓面向協議編程更加地powerful,強力推薦這個WWDC Session
extension DogCanPlay {
func playGame() { // 爲協議添加默認實現
print("biubiu~~")
}
func loseGame() { //添加額外方法
print("😭😭")
}
}複製代碼
因爲添加了默認實現,struct的定義就能夠省去了playGame( )
struct Husky: DogCanPlay {
var name: String
var owner: Person
var age: Int
var GameName: String
}複製代碼
實例一個變量試試~
var myDog = Husky(name: "小黃", owner: Person(name: "大東"), age: 4, GameName: "接飛盤")
myDog.playGame() // biubiu~
myDog.loseGame() // 😭😭複製代碼
咱們知道,OOP有多態的特徵,在POP裏,也支持💪
struct Dalmatian: DogCanPlay {
var name: String
var owner: Person
var age: Int
var GameName: String
}複製代碼
創建兩個實例
let myDog = Husky(name: "小黃", owner: Person(name: "大東"), age: 4, GameName: "接飛盤")
let otherDog = Dalmatian(name: "達爾馬提亞狗", owner: Person(name: "洪**"), age: 4, GameName: "賽跑")複製代碼
👉👉
var competitionDog: [DogCanPlay] = [myDog, otherDog]
for dog in competitionDog {
print(dog.name)
//小黃
//達爾馬提亞狗
}複製代碼
基礎篇就介紹到這。日後,我會介紹protocol中where
語法的使用,還有POP在UIKit的實踐。喜歡請點個贊👍
ARC and Memory Management in Swift
Introducing Protocol-Oriented Programming in Swift 3