用于完成时例构造的方法被称为构造方法,析构方法是构造方法的逆过程,一个实例对象要被注销或者释放的过程由析f构方法来实现
目录
✨ 1. 实例的构造过程(指定构造函数)
✨ 2. 指定构造方法与便利构造方法的意义与用法
✨ 3. 必要构造方法 如果某个构造方法必须被子类实现 使用required 修饰
✨ 4.构造方法的继承特性
✨ 5.构造方法的安全检查
✨ 6.可失败的构造方法与必要构造方法
✨ 7.析构方法
1. 实例的构造过程(指定构造函数)
未设置默认值的储存属性必须在构造方法中进行赋值
swift中f的构造方法都需要使用init()来标示,开发者可以通过函数重载来创建适用于各个场景的构造方法
对于optional类型的属性,如果在构造方法中不进行赋值,就会默认为nil
如果类或者结构体中的所有属性都有默认值,那么开发者不显示提供任何构造方法,编辑器会默认制动生成一个无参数的构造方法
和结构体不同的是,结构体可以不实现其构造方法,编译起会默认生成一个构造方法,将所有的属性作为参数,如果开发者为结构体提供了自定义的构造方法,默认的构造方法会失效(swift安全设计如此)
class classcreat: NSObject {
let name = "XW" //常量此时就需要赋值 ,因为常量一旦设置就不可以修改,构造函数中无法对常量重新赋值
var years : Int // 变量如果未设置默认值的话 必须在构造函数中赋值
var color:String = "Blue" //已经赋值的 狗仔函数中可以不用赋值
var love:String? //可选类型的,如果在构造h方法中不进行赋值,就会默认为nil
init(year:Int) {
years = year
}
init(year:Int,a:Int) {
years = year
}
}
2. 指定构造方法与便利构造方法的意义与用法
构造方法有指定构造方法和便利构造方法之分,(1.)中提到的构造方法就是指定构造方法,指定构造方法不需要任何关键字修饰init(参数列表)这种,便利构造函数需要使用关键字convenience修饰,指定构造方法是类的基础构造方法,任何一个类都需要至少一个指定构造方法,便利构造f方法最终也要调用指定构造方法
- 指定构造方法是类的基础构造方法,任何一个类都需要至少一个指定构造方法
- 子类构指定造函数必须调用父类的指定构造函数
- 便利构造函数必须调用当前类的其他构造函数
- 便利构造方法归根结底要调用父类的指定构造方法
class classSuper: NSObject { //父类
var years : Int
init(year:Int) {
years = year
}
init(year:Int,a:Int) {
years = year
}
convenience init(params:String) //convenience 便利构造方法中关键字
{
self.init(year: 10);// 便利构造方法需要调用同类中的指定构造方法
}
}
//子类构造方法写法
class classSub: classSuper { //子类
var name : String
// init(year:Int) {
// years = year
// } 报错 因为子类的构造函数需要调用父类的构造函数
init(year: Int,name1:String) {
name = name1
super.init(year: year)
}
convenience init(params:String) //convenience 便利构造方法中关键字
{
self.init(year: 10,name1: params);// 便利构造方法需要调用同类中的指定构造方法
}
}
// 子类构造方法覆盖父类构造方法
class classSub1: classSuper { //子类
var name : String
// init(year:Int) {
// years = year
// } 报错 因为子类的构造函数需要调用父类的构造函数
override init(year: Int) {
name = "xw"
super.init(year: year)
}
convenience init(params:String) //convenience 便利构造方法中关键字
{
self.init(year: 10);// 便利构造方法需要调用同类中的指定构造方法
}
}
3. 必要构造方法 如果某个构造方法必须被子类实现 使用required 修饰
class myclass {
var name:String
init(nameStr:String) {
name = nameStr;
}
required init(nameSrt:String,count:Int) {
name = nameSrt;
}
}
class myclassSub:myclass {
var age:Int
init(nameStr:String,b:Int,c:Int) {
age = b
super.init(nameSrt: "xw", count: 10)
}
// 这句不是闲的话会报错 “'required' initializer 'init(nameSrt:count:)' must be provided by subclass of 'myclass'”
// 此方法必须被子类实现
required init(nameSrt: String, count: Int) {
fatalError("init(nameSrt:count:) has not been implemented")
}
}
4.构造方法的继承特性
- 在继承关系中,如果子类没有覆写或者重写任何指定构造方法,则默认子子类会继承父类所有的指定的构造g方法
- 如果子类提供了父类的搜索的指定构造方法(无论是通过覆写还是重写),则子类会默认继承父类的便利构造方法
//创建一个基类
class baseClass {
init() {
print("baseClass init")
}
init(params:Int) {
print("baseClass init\(params)")
}
convenience init(params:String)
{
self.init(params: 10)
}
}
//此类中不进行任何构造方法的定义,默认会继承父类的所有的构造方法包括便利构造方法
class subClassOne: baseClass {
let a = 8
}
/*
var subclassOne1 = subClassOne.init()
var subclassOne2 = subClassOne.init(params: 9)
var subclassOne3 = subClassOne.init(params: "10")
*/
//此类中对父亲的无参数init()指定构造函数进行覆写,则不在继承父类的其他构造方法
class subClassTwo: baseClass {
override init() {//覆写诗子类对父类的方法重新实现,两个用同一个方法名,但子类可以添加自己的功能
super.init()
}
}
/*
var subclassTwo1 = subClassTwo.init()
父类的 convenience init(params:String)和init(params:Int) 不再继承
*/
// 此类通过重载的方式定义了自己的构造方法,就不再继承父类的其他构造方法
class subClassThree: baseClass {
init(param: Int) { // 重载是表示方法名一样,参数名或者参数类型不一样的
super.init(params: 10)
}
}
/*
var subclassThreThree1 = subClassThree.init(param: 10) 能够调用的构造方法只有这个,父类的构造方法不再继承
*/
//此类覆写了父类的所有的指定构造方法,父类的便利构造方法继续被继承下来
class subClassFour: baseClass {
override init() {
super.init()
}
override init(params: Int) {
super.init()
}
}
/*
var subclassThreFourq = subClassFour.init(params:"这是父类的便利构造方法")
*/
5.构造方法的安全检查
- 子类构造方法中,必须完成当前类搜有储存属性的构造,才能调用父类的构造方法,
- 子类的构造方法如果要自定义父类储存属性的值,必须在父类构造函数调用的后面,
- 实现子类构造方法时在调用父类的构造方法前,不能使用self,因为这时候self还未完成构造
class baseCheck {
var name:String
init(nameStr:String) {
name = nameStr;
}
}
class subCheck: baseCheck {
var years:Int
init(nameStr: String,age: Int) {
years = age //子类构造方法中,必须完成当前类搜有储存属性的构造,才能调用父类的构造方法,
//self.years = age 实现子类构造方法时在调用父类的构造方法前,不能使用self,因为这时候self还未完成构造
super.init(nameStr: nameStr)
self.name = "xw" //类的构造方法如果要自定义父类储存属性的值,必须在父类构造函数调用的后面,
}
}
6.可失败的构造方法与必要构造方法
一个构造方法可能需要一些特定的参数,当传递的参数不符合要求时,开发者需要让这次构造失败
class check {
var name:String
init(param:String) {
name = param
}
init? (param:String,real:Bool) {
guard real else {
return nil
}// // 当real为YES时才开始构造函数
name = param
}
}
7.析构方法
析构方法就是程序的销毁过程,如oc中的delloc,构造方法使用init()标识,析构方法使用deinit()来标识
class tempClass {
var a:String
init(params:String) {
a = params
}
deinit {
print("tempclass 对象销毁")
}
}
网友评论