Swift继承
Swift继承

Swift继承

Swift 中的继承是面向对象编程(OOP)的核心特性之一,掌握继承机制对于理解类结构、构造器规则、方法重写、访问控制等都非常重要。

什么是继承(Inheritance)?

继承允许一个类(子类)获得另一个类(父类)的方法、属性和其他特性,从而实现代码复用和扩展功能。

Swift 中使用 : 表示继承:

class Animal {
    func makeSound() {
        print("Some sound")
    }
}

class Dog: Animal {
    func fetch() {
        print("Dog fetches")
    }
}

现在 Dog 拥有了 Animal 的所有公开属性和方法。

Swift继承规则

1、单继承:Swift 不支持多继承,一个类只能继承一个父类;

2、继承构造器:子类可以继承父类的构造器(条件:父类没有指定构造器或子类没有自定义构造器);

3、方法重写:子类可以使用 override 关键字重写父类的方法;

4、属性继承:子类继承父类所有非私有属性,但不能直接初始化父类属性;

5、类型继承:子类可以被用作父类类型(多态)。

构造器继承

1、父类只有默认构造器

class Person {
    var name = "No name"
}

class Student: Person {
    // 自动继承构造器,不需要写 init
}

2、父类有指定构造器

class Animal {
    var name: String
    init(name: String) {
        self.name = name
    }
}

class Dog: Animal {
    var breed: String
    init(name: String, breed: String) {
        self.breed = breed
        super.init(name: name) // 必须显式调用
    }
}

子类必须在构造器中调用 super.init(…);

方法重写override

如果子类想要修改父类的方法逻辑,必须使用 override

class Animal {
    func makeSound() {
        print("Animal sound")
    }
}

class Cat: Animal {
    override func makeSound() {
        print("Meow")
    }
}

不加 override 会报错,Swift 要求重写的方法显式加上override。

访问控制与继承

public / open:可以继承(open 可在其他模块继承);

internal:仅在同一模块可继承;

fileprivate / private:不能继承或访问。

详细访问控制,请见《Swift访问控制级别》。 final修饰符阻止继承

final class Utility {
    // 不能被继承
}

final 用于安全性和优化;

也可以用 final func 防止方法被重写。

多态(Polymorphism)和类型转换

let a: Animal = Dog()  // 父类类型存储子类实例

if let dog = a as? Dog {
    dog.fetch()
}

这体现了面向对象的核心:多态性(父类引用可指向子类实例)。

使用场景

1、继承结构下属性初始化的规则

class Animal {
    var name: String
    init(name: String) {
        self.name = name
        print("Animal 被初始化")
    }
}

class Dog: Animal {
    var breed: String
    init(name: String, breed: String) {
        self.breed = breed
        // 这里必须调用 super.init
        super.init(name: name)
        print("Dog 被初始化")
    }
}

为什么Dog没有显式声明name属性,但是在构造器中可以使用name属性,并传递给super.init(name:)?

因为name是父类Animal中定义的属性,属于继承而来的成员,子类Dog自动拥有这个属性,但不能直接初始化它,必须调用super.init()来初始化它。

super.init(name: name)

实际上是告诉编译器: “请使用父类 Animal 的构造器来初始化你负责的属性(比如从父类继承的 name 属性)。”

因此,相当于使用Animal的初始化代码:

还可以通过另一种方法校验:

class Animal {
    var name: String
    init(name: String) {
        self.name = "22"
        print("Animal 被初始化")
    }
}

class Dog: Animal {
    var breed: String
    init(name: String, breed: String) {
        self.breed = breed
        // 这里必须调用 super.init
        super.init(name: name)  // name为赋值为 22
        print("Dog 被初始化")
    }
}

当调用super.init()后,因为Animal的初始化name为22,因此Dog实例显示的name就是22.

如果在Dog类中添加self修改name:

class Dog: Animal {
    var breed: String
    init(name: String, breed: String) {
        self.breed = breed
        // 这里必须调用 super.init
        super.init(name: name)  // 被初始化为22
        self.name = "33"    // 把22修改为33
        print("Dog 被初始化")
    }
}

使用self后,name就变成了33。

Swift初始化流程的本质在于,初始化所有输出(包括父类),然后使用self调用方法或访问属性。

在这个示例中,name是Animal的属性,只有调用super.init(name:),Animal才能完成name的初始化。

super.init()实际意义在于初始化父类的所有属性,调用父类初始化逻辑,让对象在内存中合法、完整,详细请见《swift引用父类的super》。

总结

Swift支持单继承,属性和方法也会被继承(除非被标记为private 或 final)。

构造器必须显式调用super.init,方法重写需要添加override。

支持多态,使用final可以组织继承或重写。

相关文章

1、Swift防止继承或重写的final:https://fangjunyu.com/2025/05/27/swift%e9%98%b2%e6%ad%a2%e7%bb%a7%e6%89%bf%e6%88%96%e9%87%8d%e5%86%99%e7%9a%84final/

2、Swift引用父类的super:https://fangjunyu.com/2025/05/19/swift%e5%bc%95%e7%94%a8%e7%88%b6%e7%b1%bb%e7%9a%84super/

3、Swift重写父类的override:https://fangjunyu.com/2025/05/18/swift%e9%87%8d%e5%86%99%e7%88%b6%e7%b1%bb%e7%9a%84override/

4、Swift访问控制级别:https://fangjunyu.com/2025/04/08/swift%e8%ae%bf%e9%97%ae%e6%8e%a7%e5%88%b6%e7%ba%a7%e5%88%ab/

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注