问题描述
我想像这样在初始化参数中使用 Self:
I would like to use Self in init parameters like so:
class A {
public init(finishBlock: ((_ operation: Self) -> Void)? = nil) {...}
}
我知道我可以在这个地方使用A",但我想实现这一点,如果某个类继承自 A,那么它的初始化程序将知道操作,因为它是类类型,而不仅仅是 A.例如,如果我写道:
I know I could use "A" in this place, but I would like to achieve that if some class inherits from A, then it's initializer would know operation as it's class type and not as just A. So for example if I wrote:
class B: A {
public init(finishBlock: ((_ operation: Self) -> Void)? = nil) {...}
public func fooOnlyInB() {}
}
然后我可以使用:
let b = B { (operation) in
operation.fooOnlyInB()
}
这有什么可能吗?
推荐答案
代替在每个初始化程序中使用 Self
或 A
,您可以简单地覆盖每个子类'初始化器使用它自己的类型作为 operation
.
Instead of using Self
or A
in each of the initialisers, you can simply override each subclass' initialiser to use its own type as operation
.
这是有效的,因为 A
的初始化声明 operation
应该是符合 A
的类型,当你覆盖它时,你有可以自由地使用 A
的子类作为 operation
代替.但是,如果您将 operation
更改为不相关的类型,例如 String
或 Int
,编译器将不会覆盖现有的初始化程序.
This works because A
's initialiser states that operation
should be a type that conforms to A
, and when you override it you have the liberty to use a subclass of A
as operation
instead. However, if you change operation
to an unrelated type such as String
or Int
, the compiler will not override the existing initialiser.
首先定义A
及其init
:
class A {
init(finishBlock: ((_ operation: A) -> Void)?) {...}
}
现在要创建子类,您必须使用子类的类型作为 operation
来覆盖 init
.在您对 super.init
的调用中,强制向上转换 operation
($0
) 到您的子类的类型,然后调用 finishBlock
使用这个铸造的 operation
.
Now to create a subclass, you must override init
using the subclass' type as operation
instead. In your call to super.init
, force upcast operation
($0
) to your subclass' type, and call finishBlock
with this casted operation
.
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
's initialiser now passes B
as operation
, which means that you don't need to cast it yourself anymore! This is thanks to the fact that you can override an init
with a more specific type, in this case B
.
let b = B { operation in
operation.fooOnlyInB() // prints "foo"
}
这篇关于初始化参数中的自我的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!