今天讲一下有关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的比较
本来先看了 paging 的相关资料,发现顺序有点不太对,应该先处理 RecyclerView 下滑...
什麽是Mock API Mock(模拟)这个词,其实源自於单元测试。主要的概念就是先省略中间的复杂情...
#odoo #开源系统 #数位赋能 #E化自主 在第一天的文章中,我们简单认识了odoo。在此一提,...
表单 表单在实作上是件常见的的处理,为什麽会写这篇呢?实在是因为我太容易忘了 XD 还记得一开始接触...
Digitization of Sound(声音数字化) Facts about Sound(关於声...