100 Days of Swift - Day 10 - 类Cl

2023-01-01  本文已影响0人  NieFeng1024

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 重载方法

class Dog {
    func makeNoise() {
        print("Woof!")
    }
}
// 继承Dog
class Poodle: Dog {
}
// 调用父类方法
let poppy = Poodle()
poppy.makeNoise()
// Woof!
class Poodle: Dog {
    override func makeNoise() {
        print("Yip!")
    }
}
let poppy = Poodle()
poppy.makeNoise()
// Yip!

10.4 Final classes

final class Dog {
    var name: String
    var breed: String

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

10.5 Copying objects

  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

上一篇 下一篇

猜你喜欢

热点阅读