Day 9 Swift语法-进阶篇(2/5)-Inheritance

今天讲一下有关class(类别)的继承:没有使用继承的class,我们一般称为"base class",继承通常是这样使用:

首先我们先宣告一个base class:

class userInformation {
    var currentUser = String()
    var information: String {
        return "当前使用者为 \(currentUser)"
    }
    func showAllUsers() {
        print("none")
    }
}

然後我们宣告他的子类

class User1: userInformation {
    var isOnline = false
    
}

如此一来,User1就是userInformation的子类(SubClass),而userInformation就是User1的父类,他会继承父类的一切东西,例如currentUser跟information,当然在子类别里,你可以去定义一些东西,譬如我就定义了一个"使用者是否在线上"的布林值,然後我们用下列方法把值取出来并显示在终端机上

let allen = User1()
allen.isOnline = true
allen.currentUser = "allen"
print("使用者状态: \(allen.information)")

上面我就对我子类别定义的"使用者是否在线上"对他的值的进行修改,当然子类别可以再被其他类别继承,譬如这样:

class Allen: User1 {
    var currentNumberOfUser = 1
}

然後一样,我们去设定他的值,并打印出来,记得前面的要注解掉或删除掉,然後我们可以看到,我在新的类别同样也宣告一个新的变数叫currentNumberOfUser,我们一样可以对他进行值得修改

let allen = Allen()
allen.isOnline = true
allen.currentNumberOfUser = 1
allen.currentUser = "allen"
print("显示当前使用者: \(allen.information)")

从上面程序码,我们可以看到"isOnline"还是可以修改的,且多了一个"currentNumberOfUser",因为我们Allen这个类别继承了User1类别~

重写方法(Overriding),我们可以重写的方式去重新定义子类的东西,例如这样:

override func showAllUsers() {
        print("使用者数:\(currentNumberOfUser)")
    }
}

然後我们把他打印出来:

allen.showAllUsers()

把这段程序码加在我们的子类里面,代表我们对 function "showAllUsers", 进行了重写,原本应该要显示的是"none",重写後变成"使用者数:1"结果如下:

重写属性,譬如我们有个父类跟一个子类:

//父类
class temperature {
    
    var Temperature = 0.0
    
    var description: String {
        return "当前温度:"
    }
    
    
    func dosomethingFunction() {
        //do something
    }
}

//子类
class currentTemperature: temperature {
    override var Temperature: Double {
        get {
            return 36.5
        }
        set {
            print(newValue)
        }
    }
    
    // do something
}

接着我们把他打印出来:

let student1 = currentTemperature()
print(student1.description)
student1.Temperature = 37.0 

可以注意到,我们设定一个新的值给他,是37.0,这样我们就对Temperature进行了属性重写。

补充:
当我们子类要继承的时候,无论继承来的属性是存储型(let)的还是计算型(var)的属性,子类并不知道继承来的属性是存储型的还是计算型的(譬如:Temperature)它只知道继承来的属性会有一个名字和类型。所以你在重写一个属性时,必需将它的名字和类型都写出来。然後我们可以自订一个getter跟一个setter,当你使用setter作为重写属性的一部分,那你也必须提供一个getter,可以注意到上面的getter我们设定的值是 36.5 ,这是一个默认的值,譬如我们把"student1.Temperature = 37.0"这行程序码,换成:

print(student1.Temperature)

结果如下:

这时候如果你不想为getter去提供一个默认的值,我们可以透过

return super.someProperty

这样的方式来传递继承得值,而someProperty就是我们要重写的属性的名子,譬如我们最一开始的程序码:

class userInformation {
    var currentUser = String()
    var information: String {
        return "当前使用者为 \(currentUser)"
    }
    func showAllUsers() {
        print("none")
    }
}

class User: userInformation {
var currentNumberOfUser = 1
    var isOnline = false
    
}

class Allen: User {
        override var information: String {
            return super.information + " 使用者数量为:\(currentNumberOfUser)位"
        }
}

我们就把information的属性重写了~

重写属性观察器,首先我们先了解什麽是属性观察器,属性观察器(property observer)会监控和回应属性值的变化,每次属性被设置新的值都会呼叫属性观察器,譬如我们希望使用者输入密码不能有特定的字符,或是我们规定他要大写,我们就可以透过属性观察器,去把多余的字符删除,或是帮忙转化成大写,我们先做一个简单的转换大小写的属性观察器:

class upperCased {
    var name = String() {
        willSet(name) {
            print("要转换成大写的字串:\(name)")
        }
        didSet {
            if (name == name.lowercased())  {
                self.name = name.uppercased()
                print(name)
            }
        }
    }
}
let lowerCased = upperCased()
lowerCased.name = "allen"
//结果:
//要转换成大写的字串:allen
//ALLEN

willSet 会在该值被存储之前被调用
didSet 会在一个新值被存储後被调用

接下来我们试看看重写属性观察器:

class Tom: User {
    override var currentUser: String {
        didSet{
            self.currentNumberOfUser = currentNumberOfUser + 1
        }
    }
    override var information: String {
        return super.information + " 使用者数量为:\(currentNumberOfUser)位"
    }
}

结果:

最後如果我们如果要防止重写的话:
在方法、属性或者下标脚本的关键字前写 final (譬如 final var , final func , final class func , final subscript )。


<<:  DAY9: setImmediate 与 nextTick的比较

>>:  Day06 X 图片最佳化

Day 31:RecyclerView Loads More

本来先看了 paging 的相关资料,发现顺序有点不太对,应该先处理 RecyclerView 下滑...

DAY08 - 自制MOCK API,让你开发更方便

什麽是Mock API Mock(模拟)这个词,其实源自於单元测试。主要的概念就是先省略中间的复杂情...

【Day2】如何安装odoo社区版?

#odoo #开源系统 #数位赋能 #E化自主 在第一天的文章中,我们简单认识了odoo。在此一提,...

Angular Reactive Form 表单

表单 表单在实作上是件常见的的处理,为什麽会写这篇呢?实在是因为我太容易忘了 XD 还记得一开始接触...

笔记-Multimedia Data Representations

Digitization of Sound(声音数字化) Facts about Sound(关於声...