struct Scene {
var minutes = 0
}
class Movie {
var title: String
var author: String
var date: Int
var scenes: [Scene]
init(title: String, author: String, date: Int) {
self.title = title
self.author = author
self.date = date
scenes = [Scene]()
}
convenience init(title:String) {
self.init(title:title, author: "Unknown", date:2016)
}
func addPage(page: Scene) {
scenes.append(page)
}
}
var myMovie = Movie(title: "my title") // Using convenicence initializer
var otherMovie = Movie(title: "My Title", author: "My Author", date: 12) // Using a long normal initializer
init(param1, param2, param3, ... , paramN) {
// code
}
// can call this initializer and only enter one parameter,
// set the rest as defaults
convenience init(myParamN) {
self.init(defaultParam1, defaultParam2, defaultParam3, ... , myParamN)
}
class Food {
let name: String
// MARK: - designated initializer
init(name: String) {
self.name = name
}
// MARK: - convenience initializer
convenience init() {
self.init(name: "[Unnamed]")
}
}
// MARK: - Examples
let food = Food(name: "Cheese") // name will be "Cheese"
let food = Food() // name will be "[Unnamed]"
class Food {
var name: String
init(name: String) {
self.name = name
}
convenience init() {
self.init(name: "[Unnamed]")
}
}
let namedMeat = Food(name: "Bacon")
// namedMeat's name is "Bacon”
因此,当您不需要为类指定每个属性时,它会派上用场。例如,如果我想创建所有以 HP 值100开始的冒险,我将使用下面的 方便 init并添加一个名称。这会大大减少代码。
class Adventure {
// Instance Properties
var name: String
var hp: Int
let maxHealth: Int = 100
// Optionals
var specialMove: String?
init(name: String, hp: Int) {
self.name = name
self.hp = hp
}
convenience init(name: String){
self.init(name: name, hp: 100)
}
}
class Animal {
var race: String // enum might be better but I am using string for simplicity
var name: String
var legCount: Int
init(race: String = "Dog", name: String, legCount: Int = 4) {
self.race = race
self.name = name
self.legCount = legCount // will be 4 by default
}
}
extension Animal {
convenience init(race: String, name: String) {
var legs: Int
if race == "Dog" {
legs = 4
} else if race == "Spider" {
legs = 8
} else {
fatalError("Race \(race) needs to be implemented!!")
}
// will initialize legCount automatically with correct number of legs if race is implemented
self.init(race: race, name: name, legCount: legs)
}
}
用法示例
// default init with all default values used
let myFirstDog = Animal(name: "Bello")
// convenience init for Spider as race
let mySpider = Animal(race: "Spider", name: "Itzy")
// default init with all parameters set by user
let myOctopus = Animal(race: "Octopus", name: "Octocat", legCount: 16)
// convenience init with Fatal error: Race AlienSpecies needs to be implemented!!
let myFault = Animal(race: "AlienSpecies", name: "HelloEarth")
class Z: X{
var temp2
init(a: Int, b: Int){
self.temp2 = b
super.init(a: a)
}
现在,在这种情况下,在为类 Z 创建实例时,必须同时提供值‘ a’和‘ b’。
let z = Z(a: 1, b: 2)
但是,如果您只想传递 b 的值,并且希望 rest 采用其他值的默认值,那么在这种情况下,您需要将其他值初始化为默认值。怎么等?因为你只需要在课堂之前把它设置好。
//This is inside the class Z, so consider it inside class Z's declaration
convenience init(b: Int){
self.init(a: 0, b: b)
}
convenience init(){
self.init(a: 0, b: 0)
}
class Player {
let name: String
let level: Int
init(name: String, level: Int) {
self.name = name
self.level = level
}
init(name: String) {
self.init(name: name, level: 0) //<- Call the initializer above?
//Sorry you can't do that. How about adding a convenience keyword?
}
}
Player(name:"LoseALot")
用方便关键字
class Player {
let name: String
let level: Int
init(name: String, level: Int) {
self.name = name
self.level = level
}
//Add the convenience keyword
convenience init(name: String) {
self.init(name: name, level: 0) //Yes! I am now allowed to call my fellow initializer!
}
}
如果您希望通过扩展类型来为类型创建自己的自定义初始值设定项,那么这也很有用。
class Player {
let name: String
let level: Int
init(name: String, level: Int) {
self.name = name
self.level = level
}
}
extension Player {
convenience init(name: String) {
self.init(name: name, level: 0)
}
}
class Animal {
var race: String
var name: String
var legCount: Int
init(race: String = "Dog", name: String, legCount: Int = 4)
{//—init 1
`enter code here`with all properties
self.race = race
self.name = name
self.legCount = legCount // will be 4 by default
print("came to init 1")
}
init(race: String, name: String) {//—init 2 with only two properties)
var legs = 0
if race == "Dog" {
legs = 4
} else if race == "Spider" {
legs = 8
}
legCount = legs
self.race = race
self.name = name
print("came to init 2")
}
convenience init(race: String) {
print("came to convenience init")
var legs = 0
let name = "default"
if race == "Dog" {
legs = 4
} else if race == "Spider" {
legs = 8
}
else {
fatalError("Race \(race) needs to be implemented!!")
}
// will initialize legCount automatically with correct number of legs if race is implemented
self.init(race: race, name: name, legCount: legs)
}
}
// default init1 with all default values used
let myFirstDog = Animal(name: "Bello")
// default init1 with all parameters set by user
let myOctopus = Animal(race: "Octopus", name: "Octocat", legCount: 16)
// default init2 with 2 parameters
let myOctopus1 = Animal(race:"Octopus1" , name:"Octocat1")
// convenience init for Spider as race
let mySpider = Animal(race: "Spider")