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

这里定义类名为 StudDetails 的类作为基类,用于包含学生姓名,以及三个科目标记为 mark1、mark2 和 mark3。'let' 关键字用于初始化基类的值,基类值在 'print' 函数的帮助下显示在 Playground 中。

子类

基于现有类的新类的Behave被定义为“子类”。子类继承其基类的属性、方法和功能。定义子类时,在基类名前使用“:”

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()
下标 超级[一些索引]

方法重写

继承的实例和类型方法可以通过子类中定义的方法的“override”关键字覆盖。这里 print() 在子类中被重写,以访问超类 print() 中提到的类型属性。此外,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

防止覆盖的最终属性

当用户不需要其他人访问超类方法、属性或下标时,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”,因此程序将不允许进一步创建子类,并且会抛出错误。