Swift初学 - 四大自定义数据类型之Class

说完Struct,我们再来看看Class,这应该是最经常用的了,我们还是先举例看一下怎么定义一个Class

class Person {
  var firstName: String
  var lastName: String

  init(firstName: String, lastName: String) {
    self.firstName = firstName
    self.lastName = lastName
  }

  var fullName: String {
    return "\(firstName) \(lastName)"
  }
}

let me = Person(firstName: "Joshua", lastName: "Jiang")

跟struct同样的定义Person,然后创建一个instance。从实现上来看非常像,那struct和class到底有什么区别呢?我们来更细的讨论一下。

一、Struct vs Class

1、初始方法init

不像struct会自动生成一个init让你用,上述代码中的init是必须要写的,而且和struct一样,在init中所有stored property(不懂这个的去看上一篇struct哈)都必须赋初始值。

2、Reference Type(引用类型) vs Value Type(值类型)

Struct是值类型,class是引用类型。分别是什么意思呢?

I. Value Type值类型

值类型是指当你把这种类型赋值时,整个instance是copy到被赋值的常量或变量的。Struct是值类型,之前我们说过Int, Array这些都是Struct,所以我们举一个整数的例子来了解这个概念:

var a = 3
var b = a
print("\(a), \(b)") // 3, 3

a = 10
print("\(a), \(b)") // 10. 3

可以看到b并没有因为a的改变而改变,因为把a赋值给b的时候,是把3这个值拷贝给b的。

值类型都存储在内存中的stack(栈)里,通俗一点类似这种形式:


heap.png

每个变量/常量都储存了相对应的值,可以直接读取。栈里储存的数据都是程序主线程执行需要的,这些数据都被CPU很好的管理着:当你在function里创建了一个本地变量,cpu将它储存到栈里,当你的function运行结束,cpu会将它毁掉;这种机制非常有效率。

I. Reference Type引用类型

与值类型不同,当你创建并把引用类型assign给一个变量/常量时,创建的instance(实例)储存在内存中的heap(堆)里,然后在stack里,这个变量/常量储存的是一个指向heap中的instance的地址。举个栗子:

var me = Person(firstName: "Joshua", lastName: "Jiang")
var prince = me
print("\(me.firstName), \(prince.firstName)") // Joshua, Joshua

me.firstName = "coolboy"
print("\(me.firstName), \(prince.firstName)") // coolboy, coolboy

因为当把me assign给prince的时候,并没有拷贝整个instance给prince,而是拷贝了指向instance的地址;所以当me的firstName变了,那么prince的自然也会变。画个图:


class.png

画的非常通俗易懂,呵呵...

III. 判定相等or not

当你比较值类型时,不管是struct还是Int,用==即可

1 == 1 // true

当你比较引用类型时,需要用===,比较的是他们指向的地址是否相同

me === prince // true

所以虽然定义的代码看起来差不多,但struct和class还是有很大区别的!

二、常量 or 变量

我们知道如果你把一个struct复制给constant的时候,你是不能修改他的属性的;但class确可以:

struct Employee {
    var jobTitle: String
}
let employee = Employee(jobTitle: "CEO")
employee.jobTitle = "CTO" // error: cannot assign to property

let me = Person(firstName: "Joshua", lastName: "Jiang")
me.firstName = "coolboy" // cool

为啥呢,因为me储存的是一个地址,我们改变instance的firstName,并没有改变me储存的那个地址。但你想改变我是什么人,那就不行了,man!

me = Person(firstName: "dog", lastName: "shit") // error: I am not

三、如何选择用Class还是Struct

Struct是用来代表值的,比如距离、名称之类的,用的时候创建不用的时候毁掉,很快的这种,你要用struct;

Class代表一个对象,像一个学生或者一个城市之类的,通常有超多的属性,一般长时间在内存里,不会随便就毁掉,这时候你当然要用class

Simple!

小QUIZ

String是引用类型还是值类型?那么下方的代码会print出什么?

var str1 = "123"
var str2 = str1
print(str1 + str2)

str1 = "abc"
print(str1 + str2)

四、Inheritance继承

class是可以继承的,虽然这是初学知识分享,但这有点儿太初学了,不多说了,栗子:

class Employee: Person {
    var salary: Int = 0
    func raise() {
      salary += 200
    }
}

class Student: Person {
    var grades: Int = 0
}

let joshua = Employee(firstName: "Joshua", lastName: "J")
let ming = Student(firstName: "Ming", lastName: "Xiao")
joshua.raise() // 不需要加mutating也可以改属性的值

a) 一个class只能继承一个别的class
b) 深度不限,可以无限往下继承Person -> Employee -> President -> VP...
c) 类型转换

joshua as Person //用as要确保运行的时候会成功,不然error;一般是从子class往上cast
(joshua as? Student)?.grades // 这种情况用as?,cast不成功就return nil
(joshua as! Student).grades // 最好别用,不成功就crash

d) 如果用了final在class前面,那就不能继承了;同样func前面用了final,那么子class就不能override

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