100 Days of Swift - Day 10 - 类Classes

100 Days of Swift - Day 10 - 类Classes

10.0 摘要

  1. 类和结构类似,都可以使用属性和方法创建自己的类型。
  2. 类可以继承,并获得父类的所有属性和方法。
  3. 用final关键字标记一个类,其他类无法继承。
  4. 方法重写允许子类用新的实现替换父类中的方法。
  5. 当两个变量指向同一个类实例时,它们指向同一块内存,——改变一个会改变另一个。
  6. 类有一个析构函数,在类的实例销毁时运行。
  7. 类不同于结构体那样强地强制常量,如果属性声明为变量,则无论如何创建类实例,都可以更改它。

10.1 创建自定义类

  • 类和结构体类似,可以创建新的数据结构,拥有属性和方法。
  1. 类可以继承,而结构体无法继承。
  2. 结构体拥有默认成员初始化构造器,而类没有默认成员初始化构造器,需要创建自定义初始化构造器。
  3. Copy结构体属于深copy,每次都会创建一个新变量,而类的copy 默认是浅copy指向源数据,不会开辟新的内存。
  4. 类有析构函数,在对象被销毁时调用,而结构体没有。
  5. 类的常亮实例对象可以随意修改属性变量,而结构体常量不可以修改其属性变量。
class Dog {
    var name: String
    var breed: String

    init(name: String, breed: String) {
        self.name = name
        self.breed = breed
    }
}
// 创建类的实例对象和结构体类似,调用初始化方法,传入成员初始值即可
let poppy = Dog(name: "Poppy", breed: "Poodle")

10.2 类继承 Class inheritance

  • 类可以通过继承获得父类的所有属性和方法,也可以创建只属于自己的属性和方法。
class Dog {
    var name: String
    var breed: String

    init(name: String, breed: String) {
        self.name = name
        self.breed = breed
    }
}

// Poodle 继承自 Dog,无自定义初始化构造方法
class Poodle: Dog {
    
}
// 默认可以调用父类初始化方法
let poodle = Poodle(name: "Poodle旺财", breed: "Poodle")
// Poodle 继承自 Dog,自定义初始化构造器,通过super关键字可以调用父类的初始化构造器进行初始化
class Poodle: Dog {
    init(name: String) {
        super.init(name: name, breed: "Poodle")
    }
}
// 
let poodle = Poodle(name: "Poodle旺财")

10.3 重载方法

  • 子类方法用overriding修饰,覆盖父类方法,自定义实现称之为重载。
class Dog {
    func makeNoise() {
        print("Woof!")
    }
}
// 继承Dog
class Poodle: Dog {
}
// 调用父类方法
let poppy = Poodle()
poppy.makeNoise()
// Woof!
  • 子类重载makeNoise方法
class Poodle: Dog {
    override func makeNoise() {
        print("Yip!")
    }
}
let poppy = Poodle()
poppy.makeNoise()
// Yip!
  • 非子类用overriding修饰方法编译器会报错。
  • 重载目的是子类复用父类方法并在其基础上扩展,或者子类需要和父类不同的实现。

10.4 Final classes

  • 非继承类,类默认可以被继承,从而构建复杂有序的类簇结构,但如果为了保持类简单不可被继承,需要使用final关键字修饰类。
  • 非继承类不可重载方法。
final class Dog {
    var name: String
    var breed: String

    init(name: String, breed: String) {
        self.name = name
        self.breed = breed
    }
}
  • OC 不支持final

10.5 Copying objects

  • 结构体和类的copy有所不同,
  1. 类对象的copy 是浅copy,两个对象内存指向同一区域,一改全改,
class Singer {
    var name = "Taylor Swift"
}
var singer = Singer()
print(singer.name)
var singerCopy = singer
singerCopy.name = "Justin Bieber"
print(singer.name)  
// Justin Bieber
print(singerCopy.name)
// Justin Bieber
  1. 结构体对象copy则是深copy,copy出来的对象和源对象属于两个不同的对象,只是数据一样。
struct Singer {
    var name = "Taylor Swift"
}
var singer = Singer()
var singerCopy = singer
singerCopy.name = "Justin Bieber"
print(singer.name)  
// Taylor Swift
print(singerCopy.name)
// Justin Bieber
  1. 结构体是值类型,而类是引用类型。可根据不同场景选择使用。

10. 6 析构函数 Deinitializers

  • 类有析构函数,而结构体没有,析构函数是类对象生命周期函数之一,当类对象被销毁时调用。
class Person {
    var name = "John Doe"

    init() {
        print("\(name) is alive!")
    }

    func printGreeting() {
        print("Hello, I'm \(name)")
    }
}
deinit {
    print("\(name) is no more!")
}

for _ in 1...3 {
    let person = Person()
    person.printGreeting()
    // Hello, I'm John Doe
    // John Doe is no more!
}
  1. 结构体是值类型,存储在栈区,由系统管理生命周期,copy一次产生一个新对象,使用完系统自动回收。
    而类是引用类型,由ARC 管理生命周期,copy一次引用计数加一,销毁一次则引用计数减一。直至引用计数为0时执行析构函数,被系统回收。

10.7 可变能力Mutability

  1. 类变量可以随意修改其属性变量,即便类对象是常量类型
  2. 结构体变量不可以随意修改其属性变量,如需修改属性变量需要用mutating关键字修饰方法,编译器则允许该方法可修改属性变量。
class Singer {
    var name = "Taylor Swift"
}
let taylor = Singer()
// 常量类对象修改属性变量
taylor.name = "Ed Sheeran"
print(taylor.name)
// 类对象禁止修改常量属性
class Singer {
    let name = "Taylor Swift"
}

声明:本文创作来自hackingwithswift

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

推荐阅读更多精彩内容