Dam*_*ycz 5 types initialization swift
我想在init参数中使用Self,如下所示:
class A {
public init(finishBlock: ((_ operation: Self) -> Void)? = nil) {...}
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以在这个地方使用"A",但我想实现这一点,如果某个类继承自A,那么它的初始化程序会将操作知道为类的类型,而不仅仅是A.所以例如,如果我写了:
class B: A {
public init(finishBlock: ((_ operation: Self) -> Void)? = nil) {...}
public func fooOnlyInB() {}
}
Run Code Online (Sandbox Code Playgroud)
然后我可以使用:
let b = B { (operation) in
operation.fooOnlyInB()
}
Run Code Online (Sandbox Code Playgroud)
这有点可能吗?
您可以简单地覆盖每个子类的初始化程序以使用其自己的类型作为 ,而不是在每个初始化程序中使用Selfor 。Aoperation
这是有效的,因为A的初始化器声明operation应该是符合 的类型A,并且当您重写它时,您可以自由地使用Aas的子类operation来代替。但是,如果更改operation为不相关的类型(例如String或 )Int,编译器将不会覆盖现有的初始化程序。
首先,定义A它init:
class A {
init(finishBlock: ((_ operation: A) -> Void)?) {...}
}
Run Code Online (Sandbox Code Playgroud)
现在要创建子类,您必须init使用子类的类型进行重写operation。在对 的调用中super.init,强制向上转换operation( $0) 为子类的类型,并finishBlock使用此强制转换进行调用operation。
class B: A {
override init(finishBlock: ((_ operation: B) -> Void)?) {
// Perform custom initialisation...
super.init { finishBlock?($0 as! B) }
}
func fooOnlyInB() {
print("foo")
}
}
Run Code Online (Sandbox Code Playgroud)
B的初始化程序现在传递B为operation,这意味着您不再需要自己投射它!这是因为您可以init使用更具体的类型覆盖 an ,在本例中是B.
let b = B { operation in
operation.fooOnlyInB() // prints "foo"
}
Run Code Online (Sandbox Code Playgroud)