11-继承

作者: 二斤寂寞 | 来源:发表于2023-04-09 11:08 被阅读0次

继承 (Inheritance)

  • 值类型(枚举、结构体)不支持继承,只有类支持继承

  • 没有父类的类,称为:基类

    • Swift并没有像OC、Java那样的规定:任何类最终都要继承自某个基类
image.png
  • 子类可以重写父类的下标、方法、属性,重写必须加上override关键字

内存结构

class Animal {
    var age = 0
}

class Dog : Animal {
    var weight = 0
}

class ErHa : Dog {
    var iq = 0                                                          
}
let a = Animal()
a.age = 10
// 32
print(Mems.size(ofRef: a))
/*
 0x00000001000073e0   指向类型信息地址
 0x0000000000000002   引用计数相关
 0x000000000000000a   age 
 0x0000000000000000   内存对齐,暂时没用到的
 */                                                           
print(Mems.memStr(ofRef: a))
let d = Dog()
d.age = 10
d.weight = 20
// 32
print(Mems.size(ofRef: d))
/*
 0x0000000100007490  指向类型信息地址
 0x0000000000000002  引用计数相关
 0x000000000000000a  age 
 0x0000000000000014  weight
 */                                                             
print(Mems.memStr(ofRef: d))
let e = ErHa()
e.age = 10
e.weight = 20
e.iq = 30                                                         
// 48                                                       
print(Mems.size(ofRef: e))
/*
 0x0000000100007560  指向类型信息地址
 0x0000000000000002  引用计数相关
 0x000000000000000a  age 
 0x0000000000000014  weight
 0x000000000000001e  iq
 0x0000000000000000  内存对齐,暂时没用到的
 */                                                          
print(Mems.memStr(ofRef: e))

重写实力方法、下标

class Animal {
    func speak() {
        print("Animal speak")
    }
    subscript(index: Int) -> Int {
        return index                                                                
    }
}

var anim: Animal
anim = Animal()
// Animal speak
anim.speak()                                                         
// 6
print(anim[6])
class Cat : Animal {
    override func speak() {
        super.speak()
        print("Cat speak")
    }
    override subscript(index: Int) -> Int {
        return super[index] + 1                                                          
    }
}

anim = Cat()
// Animal speak
// Cat speak
anim.speak()
// 7
print(anim[6])

重写实力方法、下标

  • 被class修饰的类型方法、下标,允许被子类重写

  • 被static修饰的类型方法、下标,不允许被子类重写

class Animal {
    class func speak() {
        print("Animal speak")
    }
    class subscript(index: Int) -> Int {
        return index                                            
    }
}

// Animal speak
Animal.speak()
// 6
print(Animal[6])
class Cat : Animal {
    override class func speak() {
        super.speak()
        print("Cat speak")
    }
    override class subscript(index: Int) -> Int {
        return super[index] + 1                                                               
    }
}
// Animal speak
// Cat speak
Cat.speak()
// 7
print(Cat[6])

重写属性

  • 子类可以将父类的属性(存储、计算)重写为计算属性

  • 子类不可以将父类属性重写为存储属性

  • 只能重写var属性,不能重写let属性

  • 重写时,属性名、类型要一致

  • 子类重写后的属性权限 不能小于 父类属性的权限

    • 如果父类属性是只读的,那么子类重写后的属性可以是只读的、也可以是可读写的

    • 如果父类属性是可读写的,那么子类重写后的属性也必须是可读写的

重写实例属性

class Circle {
    var radius: Int = 0
    var diameter: Int {
        set {
            print("Circle setDiameter")
            radius = newValue / 2                                                  
        }
        get {
            print("Circle getDiameter")
            return radius * 2
        }                                                       
    }
}
var circle: Circle
circle = Circle()
circle.radius = 6
// Circle getDiameter
// 12
print(circle.diameter)

// Circle setDiameter
circle.diameter = 20

// 10
print(circle.radius)

重写实例属性

class SubCircle : Circle {
    override var radius: Int {                                                        
        set {
            print("SubCircle setRadius")
            super.radius = newValue > 0 ? newValue : 0          
        }
        get {                                                                
            print("SubCircle getRadius")
            return super.radius
        }
    }
    override var diameter: Int {                                                           
        set {
            print("SubCircle setDiameter")
            super.diameter = newValue > 0 ? newValue : 0        
        }
        get {                                                   
            print("SubCircle getDiameter")
            return super.diameter
        }                                                       
    }
}
var circle = SubCircle()
// SubCircle setRadius
circle.radius = 6

// SubCircle getDiameter
// Circle getDiameter
// SubCircle getRadius
// 12
print(circle.diameter)

// SubCircle setDiameter
// Circle setDiameter
// SubCircle setRadius
circle.diameter = 20

// SubCircle getRadius
// 10
print(circle.radius)

重写类型属性

  • 被class修饰的计算类型属性,可以被子类重写

  • 被static修饰的类型属性(存储、计算),不可以被子类重写

class Circle {
    static var radius: Int = 0
    class var diameter: Int {
        set {
            print("Circle setDiameter")
            radius = newValue / 2                                                        
        }
        get {
            print("Circle getDiameter")
            return radius * 2
        }                                                       
    }
}
Circle.radius = 6
// Circle getDiameter
// 12
print(Circle.diameter)
// Circle setDiameter
Circle.diameter = 20
// 10
print(Circle.radius)
class SubCircle : Circle {
    override static var diameter: Int {
        set {
            print("SubCircle setDiameter")
            super.diameter = newValue > 0 ? newValue : 0        
        }
        get {
            print("SubCircle getDiameter")
            return super.diameter
        }                                                       
    }
}
SubCircle.radius = 6
// SubCircle getDiameter
// Circle getDiameter
// 12
print(SubCircle.diameter)
// SubCircle setDiameter
// Circle setDiameter
SubCircle.diameter = 20
// 10
print(SubCircle.radius)

属性观察器

  • 可以在子类中为父类属性(除了只读计算属性、let属性)增加属性观察器
class Circle {
    var radius: Int = 1
}

class SubCircle : Circle {
    override var radius: Int {
        willSet {                                                         
            print("SubCircle willSetRadius", newValue)
        }                                                       
        didSet {
            print("SubCircle didSetRadius", oldValue, radius)                                                                
        }
    }                                                           
}

var circle = SubCircle()

// SubCircle willSetRadius 10
// SubCircle didSetRadius 1 10
circle.radius = 10

属性观察器

class Circle {
    var radius: Int = 1 {                                       
        willSet {
             print("Circle willSetRadius", newValue)                                          
        } 
        didSet {                                              
            print("Circle didSetRadius", oldValue, radius) 
        }                                          
    } 
} 

class SubCircle : Circle {
    override var radius: Int {                                       
        willSet {
             print("SubCircle willSetRadius", newValue)                                                  
        }
        didSet {                                          
            print("SubCircle didSetRadius", oldValue, radius) 
        }                                      
    } 
} 

var circle = SubCircle()

// SubCircle willSetRadius 10
// Circle willSetRadius 10 
// Circle didSetRadius 1 10 
// SubCircle didSetRadius 1 10
circle.radius = 10

属性观察器

class Circle {
    var radius: Int {                                                           
        set {
            print("Circle setRadius", newValue)                 
        }
        get {                                                   
            print("Circle getRadius")                           
            return 20
        }                                                       
    }
}

class SubCircle : Circle {
    override var radius: Int {                                  
        willSet {
            print("SubCircle willSetRadius", newValue)          
        }
        didSet {                                                
            print("SubCircle didSetRadius", oldValue, radius)
        }                                                       
    }
}

var circle = SubCircle()
// Circle getRadius
// SubCircle willSetRadius 10
// Circle setRadius 10
// Circle getRadius
// SubCircle didSetRadius 20 20
circle.radius = 10

属性观察器

class Circle {
    var radius: Int {                                                           
        set {
            print("Circle setRadius", newValue)                 
        }
        get {                                                   
            print("Circle getRadius")                           
            return 20
        }                                                       
    }
}

class SubCircle : Circle {
    override static var radius: Int {                                  
        willSet {
            print("SubCircle willSetRadius", newValue)          
        }
        didSet {                                                
            print("SubCircle didSetRadius", oldValue, radius)
        }                                                       
    }
}

var circle = SubCircle()
// Circle getRadius
// SubCircle willSetRadius 10
// Circle setRadius 10
// Circle getRadius
// SubCircle didSetRadius 20 20
circle.radius = 10

final

  • 被 final 修饰的方法、下标、熟悉、禁止被重写

  • 被 final 修饰的类,禁止继承

多态:

在 Swift 中实现多态的方式主要有两种,分别是继承和协议。

1. 继承

继承是面向对象编程中最基本的多态实现方式。在 Swift 中,我们可以使用继承实现多态。 假设有一个基类 Animal,有两个子类 CatDog,它们都重写了 Animal 的方法 makeSound()。我们可以通过创建一个 Animal 类型的变量,然后将它指向 CatDog 的实例对象,从而实现多态。

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

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

class Dog: Animal {
    override func makeSound() {
        print("Dog makes sound")
    }
}

let animal: Animal = Cat()
animal.makeSound()  // 输出 "Cat makes sound"let animal2: Animal = Dog()
animal2.makeSound() // 输出 "Dog makes sound"

在上面的代码中,我们首先定义了一个基类 Animal,然后创建了两个子类 CatDog。子类重写了 Animal 的方法 makeSound(),实现自己的行为。然后我们创建了 Animal 类型的变量 animalanimal2,分别指向 CatDog 类型的实例对象。接着对 animalanimal2 调用 makeSound() 方法,分别输出了不同的结果。

2. 协议

协议是 Swift 中实现多态的另一种方式。在 Swift 中,协议可以定义一组行为特征,不同类型可以遵守同一个协议,从而实现相同的行为特性。 例如,我们可以定义一个名为 Animal 的协议,定义 makeSound() 方法。

protocol Animal {
  func makeSound()
}

class Cat: Animal {
  func makeSound() {
    print("Cat makes sound")
  }
}

class Dog: Animal {
  func makeSound() {
    print("Dog makes sound")
  }
}

let animal: Animal = Cat()
animal.makeSound() // 输出 "Cat makes sound"let animal2: Animal = Dog()
animal2.makeSound() // 输出 "Dog makes sound"

在上面的代码中,我们首先定义了一个 Animal 协议,并定义了 makeSound() 方法。然后我们创建了两个实现了 Animal 协议的类 CatDog。最后,我们创建了 Animal 类型的变量 animalanimal2,分别指向 CatDog 类型的实例对象,从而实现了多态。

查看汇编实现:

观察一下 class Animalstruct Animal 有啥不一样。

class Animal {
    func speak() {
        print("Animal speak")
    }

    func eat() {
        print("Animal eat")
    }

    func sleep() {
        print("Animal sleep")
    }
}

let animal: Animal = Cat()
animal.speak()
animal.eat()
animal.sleep()

相关文章

网友评论

      本文标题:11-继承

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