类的可失败构造器
如果类、结构体或是枚举类型的对象,在构造自身的过程中有可能失败,则为其定义一个可失败的构造器
变量初始化失败可能的原因:
1.传入了无效的参数值
2.缺少了所需的外部资源
3.特定的条件没有被满足
可以在类、结构体或者枚举类型的定义中,添加一个或多个可失败构造器,语法为:在init关键字后添加问号(init?)
结构体的可失败构造器
//结构体的可失败构造器
struct Animal {
let species:String
//init?定义可失败构造器
init?(species:String){
if species.isEmpty{
return nil
}
self.species = species
}
}
调用
let someCreature = Animal(species: "大熊猫")
if let panda = someCreature {
print("啥动物:\(panda.species)")
}
调用结果
啥动物:大熊猫
枚举类型的可失败构造器
enum TemperatureUnit {
// 开尔文,摄氏,华氏
case Kelvin, Celsius, Fahrenheit
//构造枚举可失败构造器
init?(symbol:Character){
switch symbol {
case "K":
self = .Kelvin
case "C":
self = .Celsius
case "F":
self = .Fahrenheit
default:
return nil
}
}
}
调用
let fahrenheitUnit = TemperatureUnit(symbol: "F")
if fahrenheitUnit != nil{
print("Fahrenheit是一个已定义的温度单位初始值,初始化成功")
}
let unknowUnit = TemperatureUnit(symbol: "X")
if unknowUnit == nil{
print("这不是一个已定义的温度单位,初始化失败。")
}
调用结果
Fahrenheit是一个已定义的温度单位初始值,初始化成功
这不是一个已定义的温度单位,初始化失败。
类的可失败构造器
class StudRecord {
let studname:String
//构建类的可失败构造器
init?(studname:String){
self.studname = studname
if studname.isEmpty{
return nil
}
}
}
调用
if let stname = StudRecord(studname: ""){
print("这是啥:\(stname.studname)")
}else {
print("传入了无效参数!")
}
if let stnamea = StudRecord(studname: "张三"){
print("这是啥:\(stnamea.studname)")
}
调用结果
传入了无效参数!
这是啥:张三
覆盖(重写)一个可失败构造器
class Planet {
var name:String
//构建可失败构造器
init?(name:String){
self.name = name
}
convenience init?(){
self.init(name: "NO")!
}
}
let plName = Planet(name: "Mercury")
print("行星的名字:\(plName!.name)")
let noplName = Planet()
print("没有名字:\(noplName!.name)")
class planets:Planet {
var count:Int
init(name:String,count:Int){
self.count = count
super.init(name: name)!
}
//用子类的非可失败构造器覆盖一个基类的可失败构造器
override convenience init(name: String) {
self.init(name: name, count: 3)
}
}
let subPlanets = planets(name: "earth")
print("subPlanets的名字:\(subPlanets.name) 计数值:\(subPlanets.count)")
调用结果
行星的名字:Mercury
没有名字:NO
subPlanets的名字:earth 计数值:3
注意:
1.可以用
子类的可失败构造器
覆盖基类的可失败构造器
2.也可以用子类的非可失败构造器
覆盖一个基类的可失败构造器
3.可以用一个非可失败构造器
覆盖一个可失败构造器
,但反过来却行不通
4.一个非可失败的构造器永远也不能代理调用一个可失败构造器
init!可失败构造器
通常使用(init?)方式定义可失败构造器,也可以使用(init!)这种方式定义可失败构造器
struct StudRecord {
let stname:String
//使用(init!)定义可失败构造器
init!(stname:String){
if stname.isEmpty{
return nil
}
self.stname = stname
}
}
调用
let stmark = StudRecord(stname: "小明")
if let name = stmark{
print("指定的学生名:\(name)")
}
let blankname = StudRecord(stname: "")
if blankname == nil {
print("未指定学生名")
}
调用结果
指定的学生名:StudRecord(stname: "小明")
未指定学生名
网友评论