Swift2.0(13)构造方法
admin
2023-02-10 06:20:04
0
  • 构造方法

实例对象在被创建时,需要对存储属性初始化,两种方式:

     方法一:在声明属性的同时设定初值(之前一直使用这种方式)

     方法二:使用构造方法

构造方法init:在对象创建时自动调用并对实例对象的存储属性进行初始化

     a. 无需func关键字声明

     b. 参数列表里可以有多个参数,也可以没有参数,参数可以有默认值

     c. 支持重写和重载

     d. 没有返回值

     如:

    class Person{
       
var name:String
       
var age:Int
       
init(name:String, age:Int) {
           
self.name = name
           
self.age = age
        }
       
init(name1:String) {
           
self.name = name1
           
self.age = 11
        }
       
init(name2:String) {
           
self.name = name2
           
self.age = 12
        }
       
init() {
           
self.name = "123"
           
self.age = 20
        }
    }
   
var p1:Person = Person()
   
print("name:\(p1.name) age:\(p1.age)")//name:123 age:20
    var p2:Person = Person(name1: "iOS")
   
print("name:\(p2.name) age:\(p2.age)")//name:iOS age:11
    var p3:Person = Person(name2: "iOS")
   
print("name:\(p3.name) age:\(p3.age)")//name:iOS age:12
    var p4:Person = Person(name: "iPhone", age: 7)

    print("name:\(p4.name) age:\(p4.age)")//name:iPhone age:7

     init()方法是强制包含外部参数名的,即使未显式写出,也是有的,相当于参数名前有#,可以使用 _ 关闭这个强制功能

     这里有四个重载的init()方法,其中有两个方法仅仅外部参数名不同,也可以进行重载(普通函数不可以)

     

构造方法中的常量:

     常量属性,在构造方法内部是可以变的,即构造方法执行后才是真正的常量

     注意:子类的构造方法不能修改父类常量属性的值


  • 构造方法的分类

默认构造方法:适用于类、结构体、枚举

     当所有的存储属性都有默认值时由系统自动生成

     如果存储属性是一个可选类型,则不必设置默认值也能具有默认构造方法,其默认值为nil

指定构造方法:显式地写出并且可重载,需要为每个存储属性初始化

便捷构造方法:内部调用其他构造方法

     需要在init()前加convenience关键字声明

     只有在便捷构造方法中可以显式调用构造方法,如:

     convenience init() {

          self.init(name:"123", age:20)

     }

可失败构造方法:在某些情况下构造对象失败后,返回nil

     返回nil,意味着返回值类型是一个可选类型,语法:init?()

     可失败构造方法可以声明为便捷构造方法

     如:

     convenience init?(age:Int) {

          self.init(name:"123", age:age)

          if ( age < 0 ) {

               return nil

          }

     }

     var p1:Person? = Person(age: 5)

     隐式解绑的可失败构造方法,即返回值是解绑后的,语法init!()

          也就意味着返回值不再是一个可选类型,也就意味着可失败构造方法返回nil程序会崩溃


  • 继承中的构造过程

先来看一段代码:

    class Animal {
       
var age:Int
       
init() {
           
self.age = 10
           
print("Animal init.")
        }
    }
   
class Dog:Animal {
       
var name:String
       
override init() {
           
self.name = "abc"
           
print("Dog init.")
        }
    }
   
var p = Dog()

    print("age:\(p.age) name:\(p.name)")

     输出的结果:

          Dog init.

          Animal init.

          age:10 name:abc

     重要说明:子类的构造方法一定调用了父类的构造方法完成父类部分的初始化

父子类构造方法的调用顺序:

     上面例子中,在子类的init()中并没有显式调用,则父类的init()实在子类init()的最后隐式调用

     存在的问题是:在子类的init()中不能访问父类的属性

     解决方法:子类的init()中显式调用父类构造方法     

        override init() {
           
self.name = "abc"
           
super.init()
           
self.age++
           
print("Dog init.")

        }

     需要注意的是:显式调用父类构造方法,必须在子类存储属性初始化后进行

子类也可以添加构造方法,子类构造方法内部也可以指定调用其他构造方法

    class Animal {
       
var age:Int
       
init() {
           
self.age = 10
        }
       
init(age:Int) {
           
self.age = age
        }
    }
   
class Dog:Animal {
       
var name:String
       
override init() {
           
self.name = "abc"
           
super.init()
           
self.age++
        }
       
init(age:Int, name:String) {
           
self.name = name
           
super.init(age: age)
        }
       
    }
   
var p = Dog(age: 22, name: "ABC")

    print("age:\(p.age) name:\(p.name)")


  • 析构方法

与构造方法相反,对象即将被销毁前,会自动调用析构方法

     a. 析构方法 deinit 不带任何参数也没有返回值,不用func修饰

     b. 有默认析构方法,也可以显式写出代替

     c. 析构方法不能重载

     d. 子类实例对象销毁时,先调用子类的析构方法,再调用父类的析构方法

     e. 任何位置都不能显式调用deinit

    class Animal {
       
var age:Int
       
init() {
           
self.age = 10
        }
       
init(age:Int) {
           
self.age = age
        }
       
deinit {
           
print("Animal deinit.")
        }
    }
   
class Dog:Animal {
       
var name:String
       
override init() {
           
self.name = "abc"
           
super.init()
           
self.age++
        }
       
init(age:Int, name:String) {
           
self.name = name
           
super.init(age: age)
        }
       
deinit {
           
print("Dog deinit")
        }
    }
   
var p = Dog(age: 22, name: "ABC")

    print("age:\(p.age) name:\(p.name)")

    p = Dog()     //基于ARC机制,此时上一个Dog实例对象被销毁

     输出结果:

          age:22 name:ABC

          Dog deinit

          Animal deinit.


相关内容

热门资讯

德国总理:美国正在被伊朗羞辱 德国之声4月27日报道,德国总理默茨在访问一所学校时表示,在当前的持续冲突中,伊朗领导层正试图羞辱美...
理响中国|“长”歌以行,风云激... 光阴如梭,东方潮阔。这里是中国的长三角,世界的长三角。无论过去、现在还是未来,这片土地都因时代而生,...
白宫:特朗普及其国安团队开会讨... 新华社华盛顿4月27日电 美国白宫新闻秘书莱维特27日在记者会上证实,总统特朗普及其国家安全团队当天...
人民日报刊文:日本放开杀伤性武... 日本放开杀伤性武器出口推高地缘冲突风险(国际论坛)常思纯《人民日报》(2026年04月28日 第 0...
医疗保障法草案二审:明确生育保... 满足多样化健康保障需求本报记者 彭 波4月27日,医疗保障法草案二审稿提请十四届全国人大常委会第二十...
天津一景区发生自转旋翼机事故1... 澎湃新闻记者 吕新文中国民用航空华北地区管理局4月22日公布《豪客通航“10•1”天津长芦汉盐旅游区...
卡塔尔埃米尔与美国总统特朗普通... 当地时间24日,卡塔尔埃米尔塔米姆与美国总统特朗普通电话,重点就中东地区局势以及伊朗与美国谈判问题交...
男子30年前被扣押2859克黄... 澎湃新闻记者 王鑫家住辽宁省大连市的潘永嘉近日向澎湃新闻反映称,三十年前,他在大连周水子机场被盖州市...
商务部:取消反制欧盟两家金融机... 中华人民共和国商务部令二〇二六年 第1号鉴于欧盟已取消对中国两家金融机构的制裁措施,现公布《关于取消...
过去24小时共有5艘船只通过霍... 总台记者当地时间24日获悉,过去24小时内,共有5艘船只通过霍尔木兹海峡,其中包括一艘伊朗油轮。(总...