e = Size() 294 } 295 然后使用三种方式提供三个自定义的构造方法: 296
297 第一种使用默认值来初始化origin和size,在功能和自动获得的默认构造器是一样的,没有执行任何定制的构造过程; 298
299 第二方式使用特定的origin和size实例来初始化,在功能上跟自动获得的逐一成员构造器是一样的; 300
301 第三种使用特定的center和size来初始化,先通过 center和size的值计算出origin的坐标,然后再调用init(origin:size)构造方法来将新的origin和size的值赋值给相对应的属性。 302
303 代码如下所示: 304
305
306 structRect { 307 var origin = Point() 308 var size = Size() 309 init(){} 310 init(origin:Point,size:Size){ 311 self.origin = origin 312 self.size = size 313 } 314 init(center:Point,size:Size){ 315 letoriginX = center.x-size.width/2
316 letoriginY = center.y-size.height/2
317 self.init(origin: Point(x: originX, y: originY), size:size) 318 } 319 } 320 运行结果如图-8所示: 321
322
323 图-8
324
325 步骤六:类类型的构造委托 326
327 Swift提供两种类型的类构造方法来确保所有类实例中存储属性都能获得初始值,分别是指定构造方法和便利构造方法。 328
329 定义三个类Food、RecipeIngredient以及ShoppingListItem,其中Food是基类包含一个String类型的name属性,并提供两个构造方法来创建Food实例,代码如下所示: 330
331
332 //类类型的构造委托
333 class Food { 334 var name :String 335 //指定构造方法
336 init(name :String) { 337 self.name = name 338 } 339 //便利构造方法
340 convenienceinit(){ 341 self.init(name:"unnamed") 342 } 343 } 344 Food类提供了一个指定构造方法和一个没有参数的便利构造方法,由于Food是基类所以在指定构造方法不需要调用super.init()来完成构造,而便利构造方法则通过指定构造方法给新实例提供一个默认名称,运行结果如图-9所示: 345
346
347 图-9
348
349 RecipeIngredient类是Food的子类,RecipeIngredient类构建了食谱中的一味调味剂,包含一个Int类型的属性quantity,并且定义了两个构造方法来创建RecipeIngredient,代码如下所示: 350
351
352 classRecipeIngredient : Food { 353 var quantity : Int 354 //指定构造器
355 init(name: String, quantity:Int) { 356 //必须先初始化本类定义的属性,才能调用父类的构造器
357 self.quantity = quantity 358 super.init(name: name) 359 //如果需要在子类中给继承来的属性赋值,需要写在super.init的后面 360 //self.name = name
361 } 362 //便利构造器,且覆盖了父类的构造器
363 override convenience init(name: String) { 364 self.init(name:name, quantity:1) 365 } 366 } 367 RecipeIngredient类的指定构造方法中调用父类的指定构造方法,RecipeIngredient类重写了父类的便利构造方法,并且在内部调用了类中的指定构造方法。 368
369 RecipeIngredient类的指定构造方法、便利构造方法以及父类的便利构造方法都可以用来创建RecipeIngredient类的新实例,运行结果如图-10所示: 370
371
372 图-10
373
374 ShoppingListItem类是RecipeIngredient的子类,包含一个Bool类型的属性purchased,默认值是false。ShoppingListItem类另外还包含一个计算属性Description,代码如下所示: 375
376
377 classShoppingListItem : RecipeIngredient{ 378 var purchased = false
379 var description : String { 380 var output = "\(self.quantity) x \(name)"
381 output += purchased ? "?" : "x"
382 return output 383 } 384 } 385 ShoppingListItem类的所有属性都有默认值,并且没有定义任何构造器,那么它将继承所有父类中的指定构造器和便利构造器,可以使用全部继承来的构造器创建新的实例,运行结果如图-11所示: 386
387
388 图-11
389
390 2.4 完整代码 391
392 本案例中,完整代码如下所示: 393
394
395 importUIKit 396 //存储属性的初始化
397 struct Fahrenheit { 398 var temperature : Double 399 init(){ 400 temperature = 32.0
401 } 402 } 403 var f = Fahrenheit() 404 f.temperature 405 //带参数的构造方法
406 struct Celsius { 407 vartemperatureInCelsius:Double = 0.0
408 init(fromFahrenheitfahrenheit:Double) { 409 temperatureInCelsius = (fahrenheit - 32.0)/1.8
410 } 411 init (fromKevinkelvin:Double) { 412 temperatureInCelsius = kelvin - 273.15
413 } 414 } 415 var c = Celsius(fromFahrenheit: 88) 416 c.temperatureInCelsius 417 var c2 = Celsius(fromKevin: 100) 418 c2.temperatureInCelsius 419 //构造方法的内部参数名和外部参数名
420 struct Color { 421 let red, green, blue : Double 422 init(red:Double, green:Double, blue:Double){ 423 self.red = red 424 self.green = green 425 self.b |