Swift Inheritance
Inheritance can be understood as one class acquiring the methods and properties of another class.
When a class inherits from another class, the inheriting class is called a subclass, and the inherited class is called a superclass (or parent class).
In Swift, a class can call and access the superclass's methods, properties, and subscripts, and can override them.
We can also add property observers to properties inherited by a class.
Base Class
A class that does not inherit from any other class is called a base class.
In the following example, we define a base class StudDetails, which describes a student (stname) and their scores in various subjects (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
let sds = StudDetails(stname:stname, mark1:mark1, mark2:mark2, mark3:mark3);
print(sds.stname)
print(sds.mark1)
print(sds.mark2)
print(sds.mark3)
The output of the above program execution is:
swift 98 89 76
Subclass
A subclass refers to creating a new class based on an existing class.
To indicate the superclass of a class, write the superclass name after the subclass name, separated by a colon (:). The syntax format is as follows:
class SomeClass: SomeSuperclass {
// 类的定义
}
Examples
In the following example, we define a superclass StudDetails, and then use a subclass Tom to inherit it:
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
Overriding
A subclass can implement its own customized functionality through inherited instance methods, class methods, instance properties, or subscripts. We call this behavior overriding.
We can use the override keyword to implement overriding.
Accessing Superclass Methods, Properties, and Subscripts
You can access the superclass's methods, properties, or subscripts by using the super prefix.
| Overriding | Accessing methods, properties, and subscripts |
|---|---|
| Methods | super.somemethod() |
| Properties | super.someProperty() |
| Subscripts | super[someIndex] |
Overriding Methods and Properties
Overriding Methods
In our subclass, we can use the override keyword to override the superclass's methods.
In the following example, we override 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
Overriding Properties
You can provide a custom getter (or setter) to override any inherited property, regardless of whether the inherited property is a stored or computed property.
The subclass does not know whether the inherited property is stored or computed; it only knows that the inherited property has a name and a type. So when you override a property, you must specify both its name and type.
Notes:
If you provide a setter in the overridden property, you must also provide a getter.
If you don't want to modify the inherited property's value in the getter of the overriding version, you can directly return the inherited value through super.someProperty, where someProperty is the name of the property you are overriding.
In the following example, we define a superclass Circle and a subclass Rectangle. In the Rectangle class, 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
Overriding Property Observers
You can add property observers to an inherited property in a property override. In this way, you can monitor when the inherited property's value changes.
Note:You cannot add property observers to inherited constant stored properties or inherited read-only computed 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
Preventing Overrides
We can use the final keyword to prevent them from being overridden.
If you override a final method, property, or subscript, a compile-time error will occur.
You can mark an entire class as final by adding the final modifier (final class) before the class keyword. Such a class cannot be inherited; otherwise, a compile error will occur.
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)")
Since the above example uses the final keyword and does not allow overriding, execution will result in 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 {
^
Other Extensions