iOS Swift No.14 - 构造 2

第十四章 构造

3. Default Initializers (默认构造器)

swift里面的类型如结构体和类都会提供一个默认的构造器和属性值提供了一个默认值,也就是说类或结构体会有一个默认的构造器。这个默认的属性的值取决于它的类型,如果该属性的类型是Int那么这个属性的默认值就是0String?类型的它的默认值就是nil ,只要是在默认属性赋值了以后这个值就是该属性的默认值了。如果只是给该属性注释了一个类型那么这个属性的默认值就是类型值了。如String?默认值就是nil,Int默认值是0。

class ShoppingListItem {
    var name: String?
    /* 这里却不能给quantity注释类型Int 
    	让该class使用默认的值 
    	String?就可以的*/
    var quantity = 1
    var purchased = false
}
var item = ShoppingListItem()

3.1 Memberwise Initializers for Structure Type (结构体的成员逐一构造器)

结构体可以自动接受一个成员逐一构造器。如果你有看过我前面几期的博文,我有详细解释过成员逐一(Memberwise)这个词的具体意思。只要以后再遇到Memberwise这个词就知道它讲的是什么了。

如果在一个结构体的定义里面并没有定义任何构造器,那么该结构体使用了默认构造器,并且该构造器会自动接受一个成员逐一的构造器。即便该结构体的存储属性并没有一个默认值。成员逐一构造器是一个简短的方式,创建后结构体的实例会用成员逐一构造器来给结构体的成员属性传递或重新分配值。

struct Size {
    var width = 0.0, height = 0.0
}
/* 实例使用成员逐一构造器给
	结构体的属性传递或重新分配值 */
let twoByTwo = Size(width: 2.0, height: 2.0)

可以以忽略属性值的方式来调用成员逐一构造器,在上面的例子里。结构体Size的属性有他们各自的默认值,我们可以忽略默认值来调用成员逐一构造器。

// 实例化后并且传递height的值给结构体Size
let zeroByTwo = Size(height: 2.0)
// 调用成员逐一构造器
print(zeroByTwo.width, zeroByTwo.height)
// 实例化后的结构体
let zeroByZero = Size()
// 调用成员逐一构造器
print(zeroByZero.width, zeroByZero.height)

4 Initializer Delegation for Value Type (值类型的构造器代理)

一个构造器可以调用另一个构造器来执行某个实例构造的一部分,这中过程我们称之为构造器代理。构造器代理可以避免相同代码的重复率当我们在某个类型中使用了多个构造器的时候。

构造器代理的规则对于值类型(value type)和类类型(class type)不同的。值类型(结构体和枚举)并不支持属性继承。所以在这个值类型的构造器代理的规则会比较简单明了。是应为值类型中的构造器代理只能给他们自己的构造器。

类类型可以支持继承(详情见继承章节),顾名思义也就是类的某个属性值在被分配到一个合适的值的时候,因为类属性有继承的特性,所以呢在类类型的构造器代理的时候,类要确定它的存储属性是否也符合继承(详情见下面章节中的类继承和构在过程)值类型中 我们可以使用self.init来引用自另一个构造器且必须是相同值类型的情况下。可以在构造器里面调用self.inti。

需要注意的是 如果我们为值类型自定义了一个构造器,那么我们将不能再读取默认的构造器了。(或者是成员逐一构造器 如果这个值类型是结构体)。

struct Size {
	// 结构体Size的变量属性
    var width = 0.0, height = 0.0
}
struct Point {
	// 结构体Point的变量属性
    var x = 0.0, y = 0.0
}
struct Rect {
	// 结构体Rect的属性origin引用自结构体Point
    var origin = Point()
    // 结构体Rect的属性size引用自结构体Size
    var size = Size()
    // 该结构体的默认构造器
    init() {}
    init(origin: Point, size: Size) {
        self.origin = origin
        self.size = size
    }
    init(center: Point, size: Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)
        self.init(origin: Point(x: originX, y: originY), size: size)
    }
}

上述结构体Rect里面有三个构造器。第一个构造器相当于结构体Rect的一个默认的构造器,调用这个构造器将会返回一个Rect的实例。也将会引用该结构体内的属性origin和size的属性的值。结构体Rect这两个属性刚好是引用了其他结构体内的属性。所以这个属性值也就会被继承到新的结构体Rect内。

/* 实例化和调用结构体Rect
	就会返回该结构体的默认构造器 */
let basicRect = Rect() 
// 实例化和调用结构体Rect中的第二和第三个构造器
let originRect = Rect(origin: Point(x: 2.0, y: 2.0),
                      size: Size(width: 5.0, height: 5.0))
                      
let centerRect = Rect(center: Point(x: 4.0, y: 4.0),
                      size: Size(width: 3.0, height: 3.0))

猜你喜欢

转载自blog.csdn.net/weixin_45026183/article/details/105744684