回顾一下熟悉的OC
首先创建一个类
实现方法如下:
而当我们利用构造函数生成实例时有以下几种方法
在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);
对于类而言,引出指定构造器(向上代理)和便利构造器(横向代理)的概念
复杂的代理图
分析上面的两张图可以看出,便利构造器只能调用同类的其他构造器,并且必须以指定构造器结束,而指定构造器必须调用父类的指定构造器。
个人理解如下:
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);
未完待续…..