English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Swift Inheritance

Inheritance can be understood as a class obtaining the methods and properties of another class.

When a class inherits from another class, the inheriting class is called a subclass, and the class being inherited is called a superclass (or parent class)

In Swift, a class can call and access the methods, properties, and subscripts of its superclass, and can override them.

We can also add property observers to the properties inherited by the class.

Base Class

A class that does not inherit from other classes is called a base class (Base Class).

The following example defines the base class StudDetails, describing the student (stname) and their scores (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.mark)1)
print(sds.mark)2)
print(sds.mark)3)

The output result of the above program is:

swift
98
89
76

Subclass

A subclass refers to a new class created based on an existing class.

To indicate the superclass of a class, write the name of the superclass after the name of the subclass, separated by a colon (:), in the following format:

class SomeClass: SomeSuperclass {
    // Class definition
}

Online 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 above program is:

Mark1:93, Mark2:89

Overriding (Overriding)

A subclass can implement its own custom functionality by using the methods, class methods, instance properties, or subscripts inherited from the superclass, and we call this behavior overriding (overriding).

We can use the override keyword to implement overriding.

Access the methods, properties, and subscripts of the superclass

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

Override Access methods, properties, and subscripts
Method super.somemethod()
Property super.someProperty()
Subscripting super[someIndex]

Method and property overriding

Method overriding

In our subclass, we can use the override keyword to override the method of the superclass.

In the following example, we override the show() method:

class SuperClass {
    func show() {
        print("This is the SuperClass")
    }
}
class SubClass: SuperClass {
    override func show() {
        print("This is the SubClass")
    }
}
let superClass = SuperClass()
superClass.show()
let subClass = SubClass()
subClass.show()

The output result of the above program is:

This is the superclass SuperClass
This is the subclass SubClass

Override Properties

You can provide a custom getter (or setter) to override any inherited property, regardless of whether the inherited property is a storage property or a computed property.

The subclass does not know whether the inherited property is a storage property or a computed property; it only knows that the inherited property will have a name and a type. Therefore, when you override a property, you must write out both its name and type.

Note:

  • If you provide a setter in the property override, you must also provide a getter.

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

In the following example, we define the superclass Circle and subclass Rectangle. In the Rectangle class, we override the property area:

class Circle {
    var radius = 12.5
    var area: String {
        return "The radius of the rectangle \(radius) "
    }
}
// Inherit superclass 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 is:

Radius The radius of the rectangle 25.0  ,但现在被重写为 3

Override Property Observers

You can add property observers to an inherited property in property overrides. In this way, you will be able to monitor when the value of the inherited property changes.

Note:You cannot add property observers to inherited constant storage properties or inherited read-only computed properties.

class Circle {
    var radius = 12.5
    var area: String {
        return "The radius of the rectangle is \(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("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: The radius of the rectangle is 25.0  ,但现在被重写为 3
Radius: The radius of the rectangle is 100.0  ,但现在被重写为 21

Prevent Overriding

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

If you override a final method, property, or index script, a compilation error will occur.

You can mark an entire class as final by adding the final keyword before the class keyword (final class), such classes cannot be inherited, otherwise a compilation error will occur.

final class Circle {
    final var radius = 12.5
    var area: String {
        return "The radius of the rectangle is \(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("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)")

The execution will fail due to the final keyword used in the above example, which does not allow rewriting:

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 {
      ^