Swift ☞ 对比学习Swift构造器

回顾一下熟悉的OC

首先创建一个类

Swift ☞ 对比学习Swift构造器_第1张图片

实现方法如下:

Swift ☞ 对比学习Swift构造器_第2张图片

而当我们利用构造函数生成实例时有以下几种方法

这里写图片描述

在OC的例子中,构造器initWithName: age: 内部调用了另一个构造器,避免了代码重复,下面来围观Swift中如何实现。
在Swift中,当你创建一个类或者结构体的时候,它们的属性一定有初值(否则编译不过,例如let a: String?,此时a赋值为nil,所以属性一定有初值)。
如果类或者结构体没有自定义构造器,那么它们将获得默认构造器,用默认构造器创建出来的对象的属性值 是 类或者结构体声明时候的属性值。
class Person {
    var name: String?
    var age : Int = 10
}

let person = Person();
print(person.name,person)
           "nil 10\n"
struct Location {
    var longtitude: CGFloat = 2;
    var latitude  : CGFloat = 4;
}

let location = Location();
print(location.longtitude,location.latitude);
                   "2.0 4.0\n"
此时对于结构体,还可以得到逐一成员构造器
struct Location {
    var longtitude: CGFloat = 2;
    var latitude  : CGFloat = 4;
}

let location = Location(longtitude: 4, latitude: 4);
对于刚才提到的OC的例子,这里以结构体为例,同时引出代理构造器的概念。
struct Location {
    var longtitude:CGFloat = 2;
    var latitude: CGFloat = 4;
    init (longtitude: CGFloat) {
        self.longtitude = longtitude;
    }
    init (longtitude:CGFloat, latitude:CGFloat){
        self.init(longtitude: longtitude);
        self.latitude = latitude;
    }
}

let location = Location(longtitude: 10, latitude: 11);
print(location.longtitude,location.latitude);
对于类而言,引出指定构造器(向上代理)和便利构造器(横向代理)的概念

Swift ☞ 对比学习Swift构造器_第3张图片

复杂的代理图
Swift ☞ 对比学习Swift构造器_第4张图片

分析上面的两张图可以看出,便利构造器只能调用同类的其他构造器,并且必须以指定构造器结束,而指定构造器必须调用父类的指定构造器。

个人理解如下:

1.类的便利构造器就是对指定构造器封装一下,调用方法更简单,或者说更加范型一些。
例:

class Person {
    var name: String
    var age: Int
    init(name: String, age: Int) {//类中的指定构造器必须向上代理给父类的构造器,由于这个类是基类,所以不需要调用
        self.name = name;
        self.age = age;
    }

    convenience init(name: String) {
        self.init(name:name, age: 18);
    }
}
let aPerson = Person(name: "张三", age: 13);
print(aPerson.name,aPerson.age);
//如果我只关心18岁的一类人,使用便利构造器
let aPersonWhosAgeIs18 = Person(name: "李四");
print(aPersonWhosAgeIs18.name,aPersonWhosAgeIs18.age);

2.与OC不同的是,子类如果定义了指定构造器(不是重写),那么子类将失去继承父类构造器的能力。

class Soldier: Person {
    var rank: String
    init(rank: String,name: String, age:Int) {
        self.rank = rank//先保证当前类的所有存储属性变量均初始化,再向上代理。
        super.init(name: name, age: age);
    }
}
//由于子类自定义了指定构造器,导致实例只有这一种初始化方式
let soldier = Soldier(rank: "三道杠", name: "李四", age: 24);

未完待续…..

你可能感兴趣的:(Swift,swift,构造函数)