📜  Swift-继承

📅  最后修改于: 2020-12-25 04:35:57             🧑  作者: Mango


采取多种形式的能力被定义为继承。通常,一个类可以从另一个类继承方法,属性和功能。类可以进一步分类为子类和超类。

  • 子类-当一个类从另一个类继承属性,方法和函数时,称为子类

  • 超类-包含从其继承其他类的属性,方法和函数的类称为超类

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)

当我们使用游乐场运行上述程序时,我们得到以下结果-

Swift 4
98
89
76

此处将具有类名StudDetails的类定义为基类,该基类用于包含学生名称以及三个科目标记为mark1,mark2和mark3。 “ let”关键字用于初始化基类的值,并且借助“ print”函数在操场上显示基类的值。

子类

将新类基于现有类的行为被定义为“子类”。子类继承其基类的属性,方法和功能。要在基类名称之前定义子类“:”

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()

当我们使用游乐场运行上述程序时,我们得到以下结果-

Mark1:93, Mark2:89

“ StudDetails”类定义为超类,其中声明了学生标记,子类“ display”用于从其超类继承标记。子类定义学生标记,并调用print()方法显示学生标记。

覆写

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

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

“ super”关键字用作访问在超类中声明的方法,属性和下标的前缀

Overriding Access to methods,properties and subscripts
Methods super.somemethod()
Properties super.someProperty()
Subscripts 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()

当我们使用游乐场运行上述程序时,我们得到以下结果-

Welcome to Swift Super Class
Welcome to Swift Sub Class

属性覆盖

您可以覆盖继承的实例或类属性,以为该属性提供自己的自定义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)")

当我们使用游乐场运行上述程序时,我们得到以下结果-

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)")

当我们使用游乐场运行上述程序时,我们得到以下结果-

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 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)")

当我们使用游乐场运行上述程序时,我们得到以下结果-

:14:18: error: var overrides a 'final' var
override var area: String {
^
:7:9: note: overridden declaration is here
var area: String {
^
:12:11: error: inheritance from a final class 'Circle'
class Rectangle: Circle {
^
:25:14: error: var overrides a 'final' var
override var radius: Double {
^
:6:14: note: overridden declaration is here
final var radius = 12.5

由于超类被声明为“最终”,并且其数据类型也被声明为“最终”,因此程序将不允许进一步创建子类,并且会引发错误。