默认构造函数
- 当类的所有属性都预先设置了值,并且没有自己定义任何构造函数,swift会为我们默认创造一个构造函数
class TV{
var working=false
func open(){
self.working=true
}
func close(){
self.working=false
}
}
let tv=TV()
自定义构造函数
- 当没有构造函数时候,需要自己定义构造函数,关键点:需要把类的所有没有初始化的函数初始化好
- 用法:class TV没有任何参数所以为(),用init关键字构建初始化函数,组合成init(){}
//用户初始化函数不需要传参的
class TV{
var working:Bool
func open(){
self.working=true
}
func close(){
self.working=false
}
init(){
working=false
}
}
let tv=TV()
//需要穿参数的
class TV{
var model:String
var working:Bool
func open(){
self.working=true
}
func close(){
self.working=false
}
//这里设置参数,证明用户初始化函数,需要传递一个参数
init(model:String){
working=false
//这里用self.model访问的属性model,是为了区别model,如果不加self访问的会是这个参数model,证明他们两个不是同一个值
self.model=model
}
}
let tv=TV(model:"一个新的开始")
继承和构造
- 继承类没有实现自己的构造函数时候,会继承基类的所有构造函数
//父类
class TV{
var model:String
init(model:String){
self.model=model
}
init(){
self.model="old-man"
}
}
let tv=TV(model:"old-man")
//子类
class GameTV:TV{
func playGame() -> Void{
print("start play game...")
}
//如果想要自己的初始化值需要重载init函数,和之前重载方式一样用override关键字进行重载定义
override init(){
super.init()
self.model="game-tv1"
}
}
- 继承类如果实现或者重载了基类的任意一个构造函数,那么继承类就不会自动继承基类的其他构造函数了,调用其他构造函数会报错
继承类的构造函数
- 如果继承类有一个参数没有默认值,调用基类的构造函数之前,要把继承类自己的参数先初始化后再调用基类的
- 继承类的属性先于基类初始化
- 继承类的属性必须在初始化之后,调用基类构造函数
//基类
class TV{
var model:String
init(model:String){
self.model=model
}
}
//报错写法
class GameTV:TV{
var playingGame:Bool
init(){
// self.playingGame=false要放到super.init之前
super.init(model:"lcd")
self.playingGame=false
}
}
//
//正确写法
class GameTV:TV{
var playingGame:Bool
init(){
self.playingGame=false
super.init(model:"lcd")
}
}
Tow phase
1.阶段1,初始化所有的属性
2.阶段2,初始化所有方法
Phase 1:
- 自身Stored Property必须全部初始化
- 调用基类的构造函数
- 在调用基类构造函数之前,不能访问基类的Stord Property
- 不能调用实例方法
Phase 2:
- 所有的基类的构造函数均已调用,所有Stored Property均有初始值
- 对构造函数而言,已经是一个可用的对象,可以调用实例方法
class Country{
let name: String
//这里加问号,表示City是optional,有值或者为空,因为phase 1阶段需要初始化所有属性,
//所以city不加的话,就相当于没有完成第一阶段,所以不加就会报错,但是可以在确定有值得情况下,把?变成!
var capitalCity: City?
init(name: String,capitalName:String)
{
self.name=name
self.capitalCity=City(name: capitalName, country: self)
}
}
class City{
let name:String
unowned var country:Country
init(name:String,country:Country) {
self.name=name
self.country=country
}
}
Designated Initializer:构造函数
- 至少有一个
- 可以是自动生成的
- 必须调用基类Designated Initializer
- 最佳实践:Designated 尽可能少
Convenience Initializer
- 便利的构造函数
- 可有可无
- 必须调用该类的Designated Initializer
Failable Initializer:构造函数有可能失败
- 返回Optional Value
- 可以重载,可以重载成非Failable Initializer
Class TV{
var model:String
//在这里需要将init变成optional类型,否则系统报错,需要明确这个返回类型。
init?(model:String){
if model.isEmpty{
return nil
}
self.model=model
}
}
//继承有可能为空的函数
//这里一定不会返回为空,
class SafeTV:TV{
override init(model:String){
if model.isEmpty{
//这里叹号表示不会运行失败,失败的话跑出运行时的异常,在编译的时候是可以通过的
super.init(model:"old-man")!
}
else{
super.init(model:model)!
}
}
}
image.png
网友评论