鉴于受this question on Code Review启发的this answer on Stack Overflow,我带着这个问题回到Stack Overflow。
假设我有一个包含多个子类的类,请说UIControl
。我想用一个方法扩展这个类。该方法应该采用相同类型的对象作为其参数之一。但对于任何和所有这些类的子类,此方法只应接受其自己类型的参数。例如,UIButton
应仅接受UIButton
类型的参数,而UILabel
应仅接受UILabel
类型的参数。
已尝试过什么?
首先:
func foo<T: UIControl>(arg: T) {
// do stuff
}
这适用于编译和运行,但它不执行。无论我实际调用UIControl
的类型,我都可以传递任何foo
子类。
下一步:
func foo(arg: Self) {
// do stuff
}
此外:
func foo<T: Self>(arg: T) {
// do stuff
}
这些都不起作用,但这是一个想法。不编译,不能像这样使用Self
。
也尝试过:
func foo(arg: self.dynamicType) {
// do stuff
}
和
func foo(arg: typeof(self)) {
// do stuff
}
仍然没有一个工作 - 不会编译(这些错误的错误,合理的......)。
然后:我没有想法。
现在,一般来说,我们可能会争辩说使用泛型是好的,因为我们只会用它来做我们约束泛型的父有能力,但如果我们想要的话怎么办?将此对象返回给其他人,他们知道并需要它作为比我们定义的父类型更具体的东西吗?
例如,如果我们正在编写一个函数来添加回调:
func doCallBack<T: UIControl>(callback: (T) -> Void)) {
callback(self)
}
对我们来说重要的是,在回调块中,用户可以使用并引用参数作为其特定类型,但是当我们调用doCallBack
时,对我们来说也很重要。 UIButton
T
类型UIButton
只能是doCallBack
,但当我们在UILabel
上调用T
时,UILabel
对于每种UIControl
类型,类型只能是{{1}}等。
这可以完成吗?
答案 0 :(得分:1)
但对于任何和所有这些类的子类,此方法应该 只接受自己类型的参数。
对于继承的工作方式,这实际上是不可能的。
考虑
class Foo : UIControl
class Bar : Foo
因此Foo
必须有一个带有签名func foo(arg: Foo)
的方法。由于Bar
是Foo
的子类,因此它将继承签名为func foo(arg: Foo)
的方法(或使用该签名的方法覆盖它)。在任何情况下,参数类型都不能比Foo
窄,因为Bar
根据继承的要求,不能成为Foo
的正确替代品。因此,Bar
foo
方法不能只接受自己类型的参数&#34;。