程序员

关于Swift中POP的理解

2018-05-31  本文已影响19人  Uncle丶shuai

简介

这篇文章同样适合于那些对“Class”和"Struct"的区别不太清楚的同学,我们知道结构体不支持“继承”,为什么呢?

如果你不知道答案的话,请阅读下面的代码

class HumanClass {
  var name: String
  init(name: String) {
    self.name = name 
  } 
}
var classyHuman = HumanClass(name: "Bob")
classyHuman.name    // "Bob"
var newClassyHuman = classyHuman    // Created a "copied" object
newClassyHuman.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 paste
newHumanStruct.name = "Bobby"
humanStruct.name // "Bob"

很明显,新复制的对象"newHumanStruct"中"name"属性的变化并没有影响原来的结构体"humanStruct"的变化

类中,当你复制一个对象,两个对象指针在内存中都会指向同一个对象,所以当一个对象的某个属性变化了,另外一个对象的属性也跟着变化(这里只是对索引进行了copy),然而,在结构体中,通过创建一个新的独立对象来进行复制粘贴(这里对索引所关联的对象也进行了复制)

Bye,OOP

当然面向对象编程有很多好处,但是它同样存在劣势

接下来,让我们看一下,UIKit framework在OOP中的继承关系

avatar

Welcome, POP

不同于类和结构体,POP扁平化并且有效的降低代码的耦合性

“A protocol defines a blueprint of methods, properties… 
The protocol can then be adopted by a class, 
structure, or enumeration” — Apple

这里 "blueprint"是需要重点关注的
让我们继续用“human”为例来创建自己的"blueprint"

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

正如你所见,协议中并没有什么惊艳的操作,它仅仅是告诉你这些属性或方法的客观存在。所以暂时不需要关心它的{get set},它仅仅表明你可以给这些属性赋值或通过“get”方法拿到对应的值。所以在你需要处理这些值之前不需要关注它的具体实现。

接下来我们创建一个遵从"Human"协议的结构体 "Chinese"

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

一旦这个结构体遵从了"Human"协议,它就必须实现协议里的方法和所有的属性,如果不这样,Xcode就会报错

上一篇下一篇

猜你喜欢

热点阅读