我有一個泛型類的形式爲:繼承,泛型和議定書的斯威夫特
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