博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
14--swift之派生类构造方法
阅读量:7220 次
发布时间:2019-06-29

本文共 2994 字,大约阅读时间需要 9 分钟。

hot3.png

1.指定构造和便利构造方法解析

这些是类类型的概念,在值类型里没有

class Ab {

var a: Int

var b: Int

//init开头就是指定构造

init(a: Int,b: Int){

self.a = a

self.b = b//注意:类的指定构造方法里不能像值类型那样调用其他构造器

print("Class ab init")

}

//类似值类型的构造方法,加上关键字convenience,搭配self.init就是便利构造方法,他通过调用其他的构造方法来实现初始化,当然既可以通过指定构造方法也可以是其他便利构造方法

convenience init(a: Int){

//        self.a = a

//        b = 0

self.init(a: a,b: 0)

}

}

2.派生类的构造方法

class Ab {

var a: Int

var b: Int

//init开头就是指定构造

init(a: Int,b: Int){

self.a = a

self.b = b//注意:类的指定构造方法里不能像值类型那样调用其他构造器

print("Class ab init")

}

//类似值类型的构造方法,加上关键字convenience,搭配self.init就是便利构造方法,他通过调用其他的构造方法来实现初始化,当然既可以通过指定构造方法也可以是其他便利构造方法

convenience init(a: Int){

//        self.a = a

//        b = 0

self.init(a: a,b: 0)

}

}

class CD: Ab {

var c: Int

var d: Int

//构造方法默认是不会被继承,基类的存储属性只能通过基类的构造方法来初始化。

//派生类引入的存储属性要先被初始化,然后在调用父类的构造方法对父类的属性进行初始化

//我们只能通过调用父类的指定构造方法来对父类的属性进行初始化

init(c: Int,d: Int){//指定构造器

self.c = c

self.d = d

super.init(a: 1, b: 1)//通过父类指定构造方法来初始化

}

}

3.构造器链

//指定构造器必须调用其直接父类的指定构造器

//便利构造器必须调用同类中定义的其他构造器(指定,便利)

//便利构造器必须最终以调用一个指定构造器结束。

4.两段式构造--构造过程可以划分为两个阶段:

第一,确保所有的存储属性都初始化完毕

第二,对父类中的存储属性做进一步的处理,可以防止属性在被初始化之前访问,也可以防止属性被另外一个构造器意外的赋值

class A {

var a: Int

init(a: Int){

self.a = a

}

}

class B: A{

var b: Int

init (a: Int,b: Int){

//派生类引入的属性进行初始化

print("b类第一阶段初始化开始")

self.b = b//先初始化当前类的属性

//再用父类的指定构造方法对父类的属性进行初始化

super.init(a: a)

//额外的代码执行

print("b类第二阶段初始化开始")

if(b>100){

self.a = 100

}

}

}

5.派生类构造方法定义时的编译器安全性检查

首先应该将派生类引入的存储属性初始化,再向上代理父类的指定构造方法

首先调用父类的指定构造器实现父类中属性的初始化之后,才可以访问父类的属性

在便利构造器,首先调用同类中的其他构造方法,才可以访问属性

在第一阶段完成之前,不能调用任何实例方法,不能访问任何父类中的存储属性,不能引用self

6.重写指定构造方法

是指子类构造方法与父类构造方法的参数列表一样

class Human {

let name: String

var age: Int

init (name: String,age: Int){

self.name = name

self.age = age

}

}

class Woman: Human {

let haveBaby: Bool

//派生类定义一个指定构造方法去覆盖父类中与他有相同参数列表的指定构造方法

//    override init(name: String, age: Int) {

//        haveBaby = false

//        super.init(name: name, age: age)

//    }

//也可以定义指定构造方法,引出便利构造方法,用便利构造器覆盖

init(name: String, age: Int,haveBaby: Bool) {

self.haveBaby = haveBaby

super.init(name: name, age: age)

}

override convenience init(name: String, age: Int) {

self.init(name: name,age: age,haveBaby: false)

}

}

7.构造方法的自动继承

a.如果子类中没有定义任何的构造方法,且子类中所有的存储属性都有默认缺省值,会自动继承父类中所有的构造方法,包括便利构造方法.但是子类中有自己定义的构造方法则不会继承父类的任何构造方法

b。如果子类中只是重写了父类中的某些(而不是全部)指定构造方法,不管子类中的存储属性是否有缺省值,都不会继承父类中的其他构造方法

c。如果子类中重写了父类中所有的指定构造方法,不管子类中的存储属性是否有缺省值,都同时会继承父类中所有的便利构造方法

class xy {

var x: Int

var y: Int

init(x: Int,y: Int){

self.x = x

self.y = y

}

convenience init(){

self.init(x:0,y:0)

}

}

class xyz: xy {

var z: Int = 10

//    init(z: Int){

//        self.z = z

//        super.init(x: 0, y: 0)

//    }//一旦定义自己的构造方法,则不能继承父类的构造方法

}

var r1 = xyz()

var r2 = xyz(x: 2, y: 2)//xyz类中没有任何构造方法时,且自己的存储属性有缺省值时,就能继承父类的构造方法

8.必须构造器

构造方法所属的类的后续子子孙孙类必须实现这个构造方法

class Some {

var some: Int

required init(){

some = 0

}

}

class Subsome: Some {

var sub: Int

init(sub: Int){

self.sub = sub

super.init()

}

required init() {//required必须得写

sub = 0

super.init()

}

}

class Subsubsome: Subsome {

required init() {

super.init()

}

}

转载于:https://my.oschina.net/u/2598427/blog/636246

你可能感兴趣的文章
phpMyAdmin 后台拿webshell
查看>>
Linux 关机 休眠, 关闭移动设备自动挂载 命令
查看>>
Html唤起手机APP,如果有就唤起,如果没有就跳到下载页。
查看>>
Java中File类如何扫描磁盘所有文件包括子目录及子目录文件
查看>>
VC++ 限制窗口的大小范围的方法
查看>>
结对开发-返回一个整数数组中最大子数组的和(首尾相接版)
查看>>
meanshift-聚类
查看>>
不要if else的编程
查看>>
rn.ShowDialog() == DialogResult.OK
查看>>
20160519
查看>>
SCU 3132(博弈)
查看>>
正则表达式
查看>>
delete archivelog all 无法彻底删除归档日志?
查看>>
Redis五大数据类型
查看>>
大型分布式网站架构技术总结
查看>>
矩阵求导与投影梯度相关问题
查看>>
SVN
查看>>
C语言编程写的一个http下载程序(王德仙)2012-04-08
查看>>
CCF201409-3 字符串匹配(100分)
查看>>
UVALive2203 UVa10042 Smith Numbers【质因数分解+素数判定+数位之和】
查看>>