持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
Swift的继承与其他语言并无两样,本文主要把重写进行了说明,主要是方法/下标重写、属性重写、属性观察器重写,其实他们的本质也就是方法重写。
主要内容:
- 方法/下标重写
- 属性重写
- 属性观察器重写
1、继承认识
继承概念没区别,都是父类子类的关系,也没必要赘言了,这里只看下内存结构。子类如何存储属性。
代码:
说明:
- 父类继承过来的存储属性是放在前面的
- 子类继承父类的存储属性是拷贝到子类中的
2、重写
子类可以重写父类的属性、下标、方法,重写必须加上override关键字(required不需要),需要注意的是不管是方法、下标、属性、属性观察器,所有的重写本质都是函数重写
2.1 方法/下标
下标其实就是方法,所以放到一起写
2.1.1 实例方法
代码:
说明:
- 下标和方法只要在前边加上override就声明被重写了
- 案例中Cat继承自Animal,下标方法和speak方法都进行了重写。
- 多态调用时,就会执行子类的方法实现。
2.1.2 类型方法
代码:
/*
2、下标、方法重写
*/
func test2() {
class Animal {
class func speak() {
print("Animal speak")
}
class subscript(index: Int) -> Int {
return index
}
}
class Cat : Animal {
//方法重写
override class func speak() {
super.speak()
print("Cat speak")
}
//下标重写
override class subscript(index: Int) -> Int {
return super[index] + 1
}
}
Cat.speak()
print(Cat(2))
}
test2()
说明:
- 类型方法也是一样,只是在调用时需要通过类型调用
- 被class修饰的类型方法、下标,允许被子类重写
- 被static修饰的类型方法、下标,不允许被子类重写
- 注意重写的方法/下标可以是static
2.2 属性
属性本身是没有重写的,只有继承,但是在Swift中有计算属性和属性观察器这两种东西,他们本质上也是函数,所以这两种也可以重写
属性重写的种类:
- 计算属性重写为计算属性;
- 存储属性重写为计算属性;
- 存储属性重写成带有属性观察器的存储属性
代码:
说明:
- 仅仅只是普通的重写,没什么特殊的
- 只是需要注意在调用circle.diameter时,调用一下父类的getDiameter方法,因为在子类的getDiameter方法中会调用super的diameter
注意:
- 子类可以将存储属性和计算属性重写为计算属性
- 子类不可以将父类属性重写成存储属性
- 存储属性只能继承
- 但是如果子类增加属性观察器,也就可以重写
- 子类不能将父类的存储属性重写为存储属性,因为子类本身就会有父类的存储属性,所以没必要重写
- 只能重写var属性,不能重写let属性,这个很正常,重写就是为了子类修改实现
- 重写时,属性名、类型要一致
- 子类重写后的属性权限不能小于父类属性的权限
- 被Class修饰的计算类型属性,可以被子类重写
- 被static修饰的类型属性(存储、计算),不可以被子类重写
2.3 属性观察器
可以在子类中为父类属性增加属性观察器,此时也需要使用override修饰
代码:
说明:
- let属性、只读计算属性不能增加属性观察器
- 如果是给父类的存储属性增加属性观察器,那么子类中只会继承父类的存储属性,没有变成计算属性。仅仅是增加了属性观察器
- 如果父类的存储属性也有属性观察器,子类也是可以重写的
- 也可以给父类的计算属性重写属性观察器
3、总结
注意:
- 值类型(枚举、结构体)不支持继承,只有类支持继承
- Swift中的类没有统一的基类,比如NSObject
- 没有继承任何父类的类是基类,但其实它 是有一个父类的,叫_SwiftObject
- 被final修饰的方法、下标、属性禁止被重写,被final修饰的类,禁止被继承
总结:
- 重写除了一般的方法重写,还有下标重写、属性重写、属性观察器重写
- 其中下标、属性观察器、计算属性的重写本质上都是属于方法重写
- 只是注意一点可以将存储属性重写为计算属性