我有一个泛型类的形式为:继承,泛型和议定书的斯威夫特
class BaseClass<T> {
var prop: T
...
}
我然后有形式的多个子类:
class SubClassOne: BaseClass<SomeSubClass> {
...
}
class SubClassTwo: BaseClass<SomeOtherSubClass> {
...
}
凡类型参数SomeSubClass
和SomeOtherSubClass
都从一个共同的基类SomeBaseClass
继承。
我现在想定义一个变量来存储SubClassOne
和SubClassTwo
的实例。我已经尝试了许多可能性:
var obj: BaseClass
var obj: BaseClass<SomeBaseClass>
var obj: BaseClass<Any>
但第一次尝试导致错误Reference to generic type 'BaseClass' requires arguments in <...>
,另两个结果在错误Cannot assign value of type 'SubClassOne' to type ...
试图分配一个值时。我甚至想雨燕编译器欺骗的方式初始化数组的推断类型对我来说:
var testArray = [SubClassOne(), SubClassTwo()]
但是,即使这失败了,导致错误Heterogeneous collection literal could only be inferred to [Any]; add explicit type annotation if this is intentional
。实际上,成功允许存储两个子类的唯一类型注释是Any
或AnyObject
。是否可以使用更具体的类型来存储这些实例?如果不是,为什么?
这样做很重要的原因是我最终想从存储的变量obj
中获取属性prop
。如果obj
存储为Any
,我无法这样做。我也无法简单地将它投射到SubClassOne
或SubClassTwo
,因为我尝试访问属性的方法本身是一种通用方法,要投射到的哪一个取决于方法的一般类型参数:
func castObj<T>(asType: T.Type) {
(self.obj as? T).prop
}
这将被称为:castObj(asType: SubClassOne.self)
或castObj(asType: SubClassTwo.self)
。但是,我们遇到了同样的问题:我可以定义的唯一的泛型类型参数约束同时接受SubClassOne
和SubClassTwo
为Any
,然后Swift编译器会报告:Value of type 'T' has no member 'prop'
。
作为一种变通方法我试图界定一个封装所需性质的协议:
protocol HasProp {
var prop: SomeBaseClass { get }
}
然后,我已将此添加的SubClassOne
和SubClassTwo
声明。但是,这导致了另一个错误:Type 'SubClassOne' does not conform to protocol 'HasProp'
。这也使我困惑,因为SubClassOne
和SubClassTwo
都从BaseClass<SomeSubClass>
继承prop
,所以实际上符合协议。
总结:
- 是否有可能存储
SubClassOne
和SubClassTwo
情况下,更具体的类型可以访问的BaseClass
属性?如果不是,为什么? - 为什么子类不符合预期的协议?
- 如何更改设计以达到我想要的行为?
我试过这个了 - 我遇到了同样的问题,当试图首先为'obj'定义一个类型时。简单地'BaseClass'的类型约束不起作用,因为'引用泛型类型'BaseClass'需要参数在<...>'中。如果我尝试,例如'BaseClass',我们又回到了原来的错误:当我尝试调用方法时,无法将类型'SubClassOne.Type'的值转换为期望的参数类型'BaseClass .Type' 'castObj(asType:SubClassOne.self)' –
asaini007
这个函数是在'BaseClass'内还是外部定义的? –
它被定义在它外面 – asaini007