Swift - 继承

  • 简述

    采取更多形式的能力被定义为继承。通常一个类可以从另一个类继承方法、属性和功能。类可以进一步分为子类和超类。
    • 子类 - 当一个类从另一个类继承属性、方法和函数时,它被称为子类
    • 超类 − 包含从自身继承其他类的属性、方法和函数的类称为超类
    Swift 4 类包含调用和访问方法、属性、函数和重写方法的超类。此外,属性观察器还用于添加属性和修改存储或计算的属性方法。
  • 基类

    不从另一个类继承方法、属性或函数的类称为“基类”。
    
    class StudDetails {
       var stname: String!
       var mark1: Int!
       var mark2: Int!
       var mark3: Int!
       
       init(stname: String, mark1: Int, mark2: Int, mark3: Int) {
          self.stname = stname
          self.mark1 = mark1
          self.mark2 = mark2
          self.mark3 = mark3
       }
    }
    let stname = "Swift 4"
    let mark1 = 98
    let mark2 = 89
    let mark3 = 76
    print(stname)
    print(mark1)
    print(mark2)
    print(mark3)
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    Swift 4
    98
    89
    76
    
    classname为StudDetails的类在这里定义为一个基类,用于包含学生姓名,三个科目标记为mark1、mark2和mark3。'let' 关键字用于初始化基类的值,基类值借助 'print' 函数显示在playground上。
  • 子类

    在现有类的基础上创建新类的行为被定义为“子类”。子类继承其基类的属性、方法和功能。定义子类 ':' 在基类名称之前使用
    
    class StudDetails {
       var mark1: Int;
       var mark2: Int;
       
       init(stm1:Int, results stm2:Int) {
          mark1 = stm1;
          mark2 = stm2;
       }
       func print() {
          print("Mark1:\(mark1), Mark2:\(mark2)")
       }
    }
    class display : StudDetails {
       init() {
          super.init(stm1: 93, results: 89)
       }
    }
    let marksobtained = display()
    marksobtained.print()
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    Mark1:93, Mark2:89
    
    类“StudDetails”被定义为声明学生分数的超类,子类“display”用于从其超类继承分数。子类定义学生成绩并调用print()方法显示学生成绩。
  • 重写

    访问超类实例、类型方法、实例、类型属性和下标子类提供了重写的概念。'override' 关键字用于重写超类中声明的方法。

    访问超类方法、属性和下标

    'super' 关键字用作访问超类中声明的方法、属性和下标的前缀
    重写 访问方法、属性和下标
    方法 super.somemethod()
    特性 super.someProperty()
    下标 super [someIndex]
  • 方法重写

    继承的实例和类型方法可以通过 'override' 关键字重写到我们在子类中定义的方法。这里print()在子类中被重写以访问超类print()中提到的type属性。cricket() 超类的新实例也被创建为“cricinstance”。
    
    class cricket {
       func print() {
          print("Welcome to Swift 4 Super Class")
       }
    }
    class tennis: cricket {
       override func print() {
          print("Welcome to Swift 4 Sub Class")
       }
    }
    let cricinstance = cricket()
    cricinstance.print()
    let tennisinstance = tennis()
    tennisinstance.print()
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    Welcome to Swift Super Class
    Welcome to Swift Sub Class
    
  • 属性重写

    您可以重写继承的实例或类属性来为该属性提供您自己的自定义 getter 和 setter,或者添加属性观察器以使重写的属性能够在底层属性值更改时进行观察。

    重写属性 Getter 和 Setter

    Swift 4 允许用户提供自定义的 getter 和 setter 来重写继承的属性,无论它是存储属性还是计算属性。子类不知道继承的属性名称和类型。因此,用户必须在子类中指定超类中指定的重写属性的名称和类型。
    这可以通过两种方式完成 -
    • 当为重写属性定义 setter 时,用户也必须定义 getter。
    • 当我们不想修改继承的属性 getter 时,我们可以简单地通过语法 'super.someProperty' 将继承的值传递给超类。
    
    class Circle {
       var radius = 12.5
       var area: String {
          return "of rectangle for \(radius) "
       }
    }
    class Rectangle: Circle {
       var print = 7
       override var area: String {
          return super.area + " is now overridden as \(print)"
       }
    }
    let rect = Rectangle()
    rect.radius = 25.0
    rect.print = 3
    print("Radius \(rect.area)")
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    Radius of rectangle for 25.0  is now overridden as 3
    
  • 重写属性观察者

    当需要为继承的属性添加新属性时,Swift 4 中引入了“属性重写”概念。这会在继承的属性值发生更改时通知用户。但是重写不适用于继承的常量存储属性和继承的只读计算属性。
    
    class Circle {
       var radius = 12.5
       var area: String {
         return "of rectangle for \(radius) "
       }
    }
    class Rectangle: Circle {
       var print = 7
       override var area: String {
          return super.area + " is now overridden as \(print)"
       }
    }
    let rect = Rectangle()
    rect.radius = 25.0
    rect.print = 3
    print("Radius \(rect.area)")
    class Square: Rectangle {
       override var radius: Double {
          didSet {
             print = Int(radius/5.0)+1
          }
       }
    }
    let sq = Square()
    sq.radius = 100.0
    print("Radius \(sq.area)")
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    Radius of rectangle for 25.0  is now overridden as 3
    Radius of rectangle for 100.0  is now overridden as 21
    
  • 防止重写的 final 属性

    当用户不需要其他人访问超类的方法、属性或下标时,Swift 4 引入了“final”属性来防止重写。一旦声明了“final”属性,下标将不允许重写超类方法、属性及其下标。没有规定在“超类”中具有“最终”属性。当声明“final”属性时,用户被限制创建更多的子类。
    
    final class Circle {
       final var radius = 12.5
       var area: String {
          return "of rectangle for \(radius) "
       }
    }
    class Rectangle: Circle {
       var print = 7
       override var area: String {
          return super.area + " is now overridden as \(print)"
       }
    }
    let rect = Rectangle()
    rect.radius = 25.0
    rect.print = 3
    print("Radius \(rect.area)")
    class Square: Rectangle {
       override var radius: Double {
          didSet {
             print = Int(radius/5.0)+1
          }
       }
    }
    let sq = Square()
    sq.radius = 100.0
    print("Radius \(sq.area)")
    
    当我们使用playground运行上述程序时,我们得到以下结果 -
    
    <stdin>:14:18: error: var overrides a 'final' var
    override var area: String {
    ^
    <stdin>:7:9: note: overridden declaration is here
    var area: String {
    ^
    <stdin>:12:11: error: inheritance from a final class 'Circle'
    class Rectangle: Circle {
    ^
    <stdin>:25:14: error: var overrides a 'final' var
    override var radius: Double {
    ^
    <stdin>:6:14: note: overridden declaration is here
    final var radius = 12.5
    
    由于超类被声明为“final”并且其数据类型也被声明为“final”,因此程序将不允许进一步创建子类,并且会抛出错误。