Swift inheritance


Inheritance can be understood as one class acquiring the methods and attributes of another class.

When a class inherits other classes, 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 methods of the superclass. , attribute and subscript scripts, and they can be overridden.

We can also add property observers for inherited properties in the class.


Base Class

A class that does not inherit other classes is called a base class.

In the following example, we define the base class StudDetails, which describes the student (stname) and the scores (mark1, mark2, mark3) for each subject:

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 execution output of the above program is :

swift
98
89
76
swift
98
89
76

Subclass

Subclass refers to creating a new class based on an existing class.

In order to specify the superclass of a certain class, write the superclass name after the subclass name and separate it with a colon (:). The syntax format is as follows

class SomeClass: SomeSuperclass {
    // 类的定义
}

Example

In the following example, we define the superclass StudDetails, and then use the 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 result of the execution of the above program is:

Mark1:93, Mark2:89

Overriding

Subclasses can implement their own customized functions through inherited instance methods, class methods, instance attributes, or subscript scripts. We call this behavior overriding.

We can use the override keyword to implement rewriting.

Accessing superclass methods, properties and subscripts

You can access superclass methods, properties or subscripts by using the super prefix.

##Subscript script super[someIndex]

Override methods and properties

Override methods

In our subclasses we can use the override keyword to override superclass methods.

In the following example, we have rewritten 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 execution output of the above program is:

这是超类 SuperClass
这是子类 SubClass

Rewrite attributes

You can Provides custom getters (or setters) to override any inherited property, whether the inherited property is stored or computed.

The subclass does not know whether the inherited properties are stored or calculated. It only knows that the inherited properties will have a name and type. So when you override an attribute, you must write out its name and type.

Note:

  • If you provide a setter in an overridden property, you must also provide a getter.

  • If you don’t want to modify the inherited property value in the getter in the overridden version, you can directly return the inherited value through super.someProperty, where someProperty is the value you want to override. Write the name of the property.

In the following example, we define the super class Circle and the subclass Rectangle. In the Rectangle class, we override the attribute 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 result of the above program execution is:

Radius 矩形半径 25.0  ,但现在被重写为 3

Overriding property observers

You can add property observers for an inherited property in property overriding. In this way, you will detect when the inherited property value changes.

Note: You cannot add property observers for 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

Prevent rewriting

We can use the final keyword to prevent them from being rewritten.

If you override the final method, attribute or subscript script, an error will be reported during compilation.

You can mark the entire class as final by adding the final attribute (final class) before the keyword class. Such a class cannot be inherited, otherwise a compilation error 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)")

Since the above example uses the final keyword and does not allow rewriting, 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 {
      ^
OverrideAccess method, attribute, subscript script
Method super.somemethod()
Propertysuper.someProperty()