Swift 5.1 (13) - 继承

继承

继承是一种基本行为:子类继承父类方法,属性和其他特性。子类可以重写父类的方法,属性。继承将类与Swift中的其他类型区分开来。
类还可以将属性观察者添加到继承的存储属性或计算属性上。

定义一个基类

基类:定义的任何不从其他类继承的类。Swift中的类在不指定父类的情况下,是不会从通用基类继承,这种情况下构建的类便是开发者定义的基类。

class BaseClass {
    //....基类的方法,属性等定义
}

子类

子类:在现父类基础上构建的新类。子类继承父类的方法,属性和其他特征,并进行差异化操作。

class SubClass: BaseClass {
    //...继承自`BaseClass`的子类
}

重写

重写:子类提供父类的实例方法,类型方法,实例属性,类型属性或下标的自定义实现。
重写的实现方式:子类要覆盖的继承父类的特性属性或方法前使用override关键字。
访问父类的方法,属性和下标
在重写父类的方法,属性和下标时,使用super前缀可以承继父类对于方法,属性和下标的实现。

class BaseClass {
    
    //....基类的方法,属性等定义
    var something: String {
        get {
            return "i from super"
        }
    }
    func doSomething() -> Void {
    }
    subscript(index:Int)->String {
        return "QiShare"
    }
}
class SubClass: BaseClass {
    //...继承自`BaseClass`的子类
    override var something: String {
        return super.something + "+override" //!< 调用输出:i from super+override
    }
    override func doSomething() {
        super.doSomething()
    }
    override subscript(index:Int)->String {
        return super[1] + "/subClass" //!< 调用输出:QiShare/subClass
        
    }

重写属性
可以覆盖继承的实例或类型属性,为该属性提供自定义的gettersetter,也能添加属性观察者。子类无法知道继承的属性是否计算或存储属性,但知道继承的属性名称和类型。故重写属性时需明确属性的名称和类型。

1. 重写属性的GetterSetter方法:
关于重写属性的GetterSetter,官网描述:

You can provide a custom getter (and setter, if appropriate) to override any inherited property, regardless of whether the inherited property is implemented as a stored or computed property at source。译文:无论继承的属性是在父类中是存储属性还是计算属性,子类都可以提供自定义getter,也可以在场景适用情况下提供setter,用以重写属性

但是在实际的操作中发现:
• 继承自父类的存储属性不能被重写。重写时报错:Cannot override with a stored property 'something'。错误示范如下:

//父类声明常量属性
let something: String = "QiShare"
//子类重写常量属性:报错:`Cannot override with a stored property 'something'`
override let something: String {
    get {
        return "sub+QiShare"
    }
}

• 继承自父类的变量属性,非计算属性,子类在重写该属性时需要同时提供settergetter。否则编译器报错:Cannot override mutable property with read-only property 'something'。正确示范如下:

//父类声明变量属性
var something: String = ""
//或
var something: String?
//子类重写变量属性
override var something : String {
    get {
        return "子类的实现"
    }
    set{
    }
}

• 通过重写计算属性GetterSetter方法,子类可将继承自父类的read-only属性变为read-write属性。示例如下:

//父类声明`read-only`属性
var something: String {
        get {
            return "i from super"
        }
    }
//子类重写后变为`read-write`属性
private var _temp :String = ""
override var something: String {
    get {
       return super.something + _temp //!< 调用输出:i from super+override
    }
    set {
        _temp = newValue + "subClass override setter"
    }
}
//实际调用,确实如此
let base = BaseClass()
//base.something = "这句话会报错,因为`sothing`在基类中是只读属性"
let sub = SubClass()
sub.something = "子类重写后" //!< i from super子类重写后subClass override setter

• 通过重写计算属性GetterSetter方法,不能将继承自父类的read-write属性变为read-only。个人理解:子类可以增加属性功能,但不能减少属性功能。反其道而行之,编译器报错:Cannot override mutable property with read-only property 'something'

• 计算属性不管是read-write还是read-only都需要使用var关键字来声明为变量属性。计算属性在组成上由getter和一个可选的setter组成的,即:不管setter有没有,getter都必须有。也因此,若是我们重写了setter方法则必须重写getter方法。基于这种情况getter方法的重写,有时是基于语法的组合体,本质上其实和父类是一样的,那么我们便可以在getter方法中使用super前缀来承继父类的调用。

2. 重写属性的观察者:
• 属性可观察的前提是该属性是可变的,故不能在继承的存储属性和read-only属性中添加willSetdidSet。反其道而行之,实际操作中编译器也会报错:Cannot observe read-only property 'something'; it can't change
• 继承的read-write属性,不能重写setter方法的同时,重写或者添加属性观察器。反其道而行之,在实际操作中编译器会报错:didSetwillSet cannot be provided together with a settergetter

防止重写

使用final关键字防止方法,属性或下标被子类重写。具体使用:final varfinal funcfinal class funcfinal subscript

  • 父类使用final关键字修饰过的方法,属性或下标,子类重写时编译器便会报错。
  • 在类扩展中使用final关键字修饰过的方法,属性或下标也同样生效。
  • 在类定义时的class关键字之前使用final关键字,来将整个类的方法,属性或下标标记为子类不可重写。

参考资料:
swift 5.1官方编程指南

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容