美文网首页
100 Days of Swift - Day 10 - 类Cl

100 Days of Swift - Day 10 - 类Cl

作者: NieFeng1024 | 来源:发表于2023-01-01 22:54 被阅读0次

    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

    相关文章

      网友评论

          本文标题:100 Days of Swift - Day 10 - 类Cl

          本文链接:https://www.haomeiwen.com/subject/qbnqcdtx.html