我有一个基于AnyObject的泛型类DataSource。 使用下标函数从缓存中提取一些项目。
当我作为DataSource的子类时,下标函数停止被认为是覆盖,随后在类型为SpecialDataSource的对象上调用它将调用超类版本。
class DataSource<T: AnyObject>: NSObject {
var cache: [T]?
subscript(idx: Int) -> T? {
if let hasStash = cache {
if idx < hasStash.count{
return hasStash[idx]
}
}
return nil
}
}
class SpecialDataSource<T> : DataSource<NSNumber> {
//The following declaration will generate:
//subscript does not override any subscript from its superclass
override subscript(idx: Int) -> T? {
if let hasStash = cache {
if idx < hasStash.count{
return hasStash[idx] as? T
}
}
return nil
}
}
在Playground中进行实验后,我发现如果SpecialDataSource声明是这样的话,就不会发生这种情况:
class SpecialDataSource<T> : DataSource<T>
我需要子类基于一个公共对象,所以我可以将它们中的一些填充到一个同构数组中。
因此该声明不提供该选项。
当我收到此错误时,听起来DataSource<NSNumber>
完全是不同的超类。
任何想法在这里出错了?我试图理解为什么我的SpecialDataSource似乎无法覆盖这个函数。
===============目前的解决方案===========
我能够解决这个问题的唯一方法是将下标的返回类型专门化为NSNumber,实际上覆盖确实完成了这项工作。
不确定是否有更好的解决方案。请告诉我。我很乐意尝试一下。
class SpecialDataSource2<T: NSNumber> : DataSource2<NSNumber> {
override subscript(idx: Int) -> NSNumber? {
if let hasStash = cache {
if idx < hasStash.count{
return hasStash[idx] as? T
}
}
return nil
}
}
答案 0 :(得分:0)
DataSource<NSNumber>
确实是一个不同的超类。生成不同的代码!
您是否真的有意义的是,您要专门使用父类来使用NSNumber。什么是更深层的意图/目标?如果您在子级和父级中都遵循T
模式会出现什么问题?
假设父类有另一个使用xyz
的方法T
。那么现在已经NSNumber
绑定了,xyz
期望NSNumber
。当然,任何子类都继承xyz
方法。但是现在假设您的子类用NSString
实例化了T.对于xyz
的实例,编译器应该对方法SpecialDataSource
做什么?你看到了固有的冲突吗?
As&#34;神奇灵活&#34;仿制药,它们实际上有很多非常具体的规则。
答案 1 :(得分:0)
一个选项可能是定义子类,如下所示:
class SpecialDataSource<T, U> : DataSource<T> { ... }
这增加了一些复杂性 - SpecialDataSource
现在需要两种通用类型。
但它也增加了灵活性。您可以拥有DataSource<NSNumber>
或DataSource<NSWhateverYouWant>
的超类。
另外,我相信你的子类的下标函数看起来像这样:
subscript(idx: Int) -> U? {
if let hasStash = cache {
if idx < hasStash.count{
return hasStash[idx] as? U
}
}
return nil
}
...并且没有必要覆盖(我不在我可以测试它的地方。)