Swift inherits
Inheritance can be understood as a class getting methods and properties of another class.
When a class inherits other classes, the inheritance class is called a child class, and the inherited class is called a super class (or parent class)
In Swift, classes can call and access super-class methods, properties, and underseed scripts, and can override them.
We can also add property observers to inherited properties in the class.
The base class
A class that does not inherit other classes, called Base Class.
In the following example, we define the base class StudDetails, which describes the scores of students (stname) and their grades in each section (mark1, mark2, mark3):
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" let mark1 = 98 let mark2 = 89 let mark3 = 76 print(stname) print(mark1) print(mark2) print(mark3)
The output of the above program execution is:
swift 98 89 76
swift 98 89 76
Sub-class
A sub-class is a new class created on top of an existing class.
To indicate a class's super-class, write the super-class name after the sub-class name, separated by a colon (:), in the following syntax format
class SomeClass: SomeSuperclass { // 类的定义 }
Instance
In the following example we define the super-class StudDetails and then inherit it using the sub-class Tom:
class StudDetails { var mark1: Int; var mark2: Int; init(stm1:Int, results stm2:Int) { mark1 = stm1; mark2 = stm2; } func show() { print("Mark1:\(self.mark1), Mark2:\(self.mark2)") } } class Tom : StudDetails { init() { super.init(stm1: 93, results: 89) } } let tom = Tom() tom.show()
The output of the above program execution is:
Mark1:93, Mark2:89
Rewriting (Overriding)
Sub-classes can implement their own customization through inherited instance methods, class methods, instance properties, or subsemase scripts, which we call overriding.
We can use the override keyword to implement the override keyword for override.
Access super-class methods, properties, and underseed scripts
You can access super-class methods, properties, or underseed scripts by using the super prefix.
Rewrite | Access methods, properties, underseed scripts |
---|---|
Method | super.somemethod() |
Property | super.someProperty() |
The underlying script | super[someIndex] |
Override methods and properties
The override method
In our sub-classes we can use the override keyword to override methods to override super-classes.
In the following example, we overrrote the show() method:
class SuperClass { func show() { print("这是超类 SuperClass") } } class SubClass: SuperClass { override func show() { print("这是子类 SubClass") } } let superClass = SuperClass() superClass.show() let subClass = SubClass() subClass.show()
The output of the above program execution is:
这是超类 SuperClass 这是子类 SubClass
Override the property
You can provide a custom getter (or setter) to override any inherited property, whether the inherited property is stored or computational.
The sub-class does not know whether the inherited property is stored or computational, it only knows that the inherited property has a name and type. So when you override a property, you have to write its name and type.
Note points:
-
If you provide setter in the override property, then you must also provide getter.
-
If you don't want to modify the inherited property value in the getter in the rewrite version, you can return the inherited value directly through super.someProperty, where homeProperty is the name of the property you want to override.
The following examples define the hyper-class Circle and the sub-class Rectangle, in which we override the property area:
class Circle { var radius = 12.5 var area: String { return "矩形半径 \(radius) " } } // 继承超类 Circle class Rectangle: Circle { var print = 7 override var area: String { return super.area + " ,但现在被重写为 \(print)" } } let rect = Rectangle() rect.radius = 25.0 rect.print = 3 print("Radius \(rect.area)")
The output of the above program execution is:
Radius 矩形半径 25.0 ,但现在被重写为 3
Override the property observer
You can add a property observer to an inherited property in a property override. That way, when the inherited property value changes, you'll be able to monitor it.
Note: You can't add property observers to inherited constant storage properties or inherited read-only compute properties.
class Circle { var radius = 12.5 var area: String { return "矩形半径为 \(radius) " } } class Rectangle: Circle { var print = 7 override var area: String { return super.area + " ,但现在被重写为 \(print)" } } let rect = Rectangle() rect.radius = 25.0 rect.print = 3 print("半径: \(rect.area)") class Square: Rectangle { override var radius: Double { didSet { print = Int(radius/5.0)+1 } } } let sq = Square() sq.radius = 100.0 print("半径: \(sq.area)")
半径: 矩形半径为 25.0 ,但现在被重写为 3 半径: 矩形半径为 100.0 ,但现在被重写为 21
Prevent overrides
We can use the final keyword to prevent them from being override.
If you rewrite the final method, property, or understag script, you will report an error at compile time.
You can mark the entire class as final by adding the final class before the keyword class, which is not inheritable, otherwise compilation errors will be reported.
final class Circle { final var radius = 12.5 var area: String { return "矩形半径为 \(radius) " } } class Rectangle: Circle { var print = 7 override var area: String { return super.area + " ,但现在被重写为 \(print)" } } let rect = Rectangle() rect.radius = 25.0 rect.print = 3 print("半径: \(rect.area)") class Square: Rectangle { override var radius: Double { didSet { print = Int(radius/5.0)+1 } } } let sq = Square() sq.radius = 100.0 print("半径: \(sq.area)")
Because the above instance uses the final keyword to not allow overrides, the execution will report an error:
error: var overrides a 'final' var override var area: String { ^ note: overridden declaration is here var area: String { ^ error: var overrides a 'final' var override var radius: Double { ^ note: overridden declaration is here final var radius = 12.5 ^ error: inheritance from a final class 'Circle' class Rectangle: Circle { ^