Swift:14 繼承
類可以從另外一個類中繼承方法、屬性、下標以及其他特性。當類繼承自其他類時,繼承的類叫子類,被繼承的類叫超類。類可以覆蓋超類的方法、屬性和下標。
基類定義
在Swift中,不繼承任何其他類的類,稱之為基類。Swift中的類并不是從一個通用的基類繼承而來的。下面示例定義一個基類,其中init是類的構造器,是一種特殊的類方法。
class Person{
var name:String, age:Int
init() {
name = "person"
age = 1
}
func toString() {
print("name:\(name),age:\(age)",terminator:",")
}
}
let p = Person()
p.toString() //打?。簄ame:person,age:1
子類化
為了指明一個類有超類,將超類名寫在子類名的后面,用冒號分隔即實現了子類化。如下演示繼承自Person的Student子類。
class Student:Person{
var studentId:Int
convenience init(name:String,age:Int) {
self.init()
super.name = name
super.age = age
}
override init() {
studentId = 0
}
override func toString() {
super.toString()
print("studentId:\(studentId)")
}
}
let student = Student(name: "Liming", age: 18)
student.studentId = 100
student.toString() //打?。簄ame:Liming,age:20,studentId:100
覆蓋
子類可以對繼承來的實例方法、類方法、實例屬性或下標進行覆蓋實現。為了覆蓋某個特性,需要在覆蓋定義的特性前面加上override關鍵詞。通過super來訪問父類中的同名方法或者屬性。
可以提供自定義的getter(或setter)來覆蓋任意繼承來的屬性,無論它是存儲屬性還是計算屬性。子類并不知道繼承來的屬性是存儲屬性還是計算屬性,只知道繼承來的屬性會有一個特定的名稱和類型。在覆蓋一個屬性時,必須將它的名稱和類型都寫出來。這樣才能讓編譯器檢查覆蓋的屬性是與超類中同名同類型的屬性是否匹配。
可以通過為子類繼承來的屬性提供getter和setter,將一個只讀屬性覆蓋為一個可讀寫的屬性。但是,不可以將一個繼承來的可讀寫的屬性覆蓋為一個只讀屬性。
class Student:Person{
var studentId:Int
convenience init(name:String,age:Int) {
self.init()
super.name = name
super.age = age
}
override init() {
studentId = 0
}
override var age: Int{
get{
return super.age
}
set{
super.age = max(8,newValue)
}
}
override func toString() {
super.toString()
print("studentId:\(studentId)")
}
}
let student = Student(name: "Liming", age: 18)
student.studentId = 100
student.toString() //打印結果:name:Liming,age:18,studentId:100
student.age = 6
student.toString() //打印結果:name:Liming,age:8,studentId:100
防止覆蓋
可以通過將方法,屬性或下標腳本標記為final來防止它們被覆蓋,只需要在聲明關鍵詞前加上final關鍵詞即可。
任何覆蓋final方法,屬性或下標的嘗試都會導致編譯時的報錯。在擴展中,添加到類里的方法,屬性或下標也可以在擴展的定義里標記為final。
可以通過在關鍵詞class前添加final關鍵詞(final class)來將整個類標記為final。所有對這種類進行繼承的嘗試都會導致編譯時報錯。
class Person{
var name:String, age:Int
init() {
name = "person"
age = 1
}
func toString() {
print("name:\(name),age:\(age)",terminator:",")
}
final func addAge(add:Int){
age += add
}
}
class Teacher:Person{
/*//報錯,final方法無法被覆蓋
override func addAge(add:Int){
}
*/
override func toString() {
super.toString()
print("teacher")
}
}
let teacher = Teacher()
teacher.addAge(add: 10)
teacher.toString() //打?。簄ame:person,age:11,teacher
示例代碼
https://github.com/99ios/23.15