我想像这样使用Self in init参数:
class A { public init(finishBlock: ((_ operation: Self) -> Void)? = nil) {...} }
我知道我可以在这里使用“ A”,但是我想实现这一点,如果某个类从A继承,那么它的初始化器将知道操作是它的类类型,而不仅仅是A。所以例如,如果我这样写:
class B: A { public init(finishBlock: ((_ operation: Self) -> Void)? = nil) {...} public func fooOnlyInB() {} }
然后,我可以使用:
let b = B { (operation) in operation.fooOnlyInB() }
这可能吗?
不必使用Self或A在每个初始化器中使用,您可以简单地重写每个子类的初始化器以使用其自己的类型为operation。
Self
A
operation
之所以起作用,是因为A的初始值设定项声明operation的类型应符合A,并且在您覆盖它时,您可以自由使用Aas 的子类operation。但是,如果更改operation为不相关的类型,例如String或Int,则编译器将不会覆盖现有的初始化程序。
String
Int
首先,定义A其init:
init
class A { init(finishBlock: ((_ operation: A) -> Void)?) {...} }
现在要创建一个子类,您必须init改用该子类的类型operation。在对的调用中super.init,将upcast operation($0)强制为您的子类的类型,然后finishBlock使用cast进行调用operation。
super.init
$0
finishBlock
class B: A { override init(finishBlock: ((_ operation: B) -> Void)?) { // Perform custom initialisation... super.init { finishBlock?($0 as! B) } } func fooOnlyInB() { print("foo") } }
B的初始化器现在可以传递B的operation,这意味着你不需要自己再投吧!这是由于您可以init在这种情况下使用更具体的类型覆盖的事实B。
B
let b = B { operation in operation.fooOnlyInB() // prints "foo" }