簡體   English   中英

快速將專業類歸類

[英]subclassing specialized generic class in swift

我在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
    }

}

DataSource<NSNumber>確實是一個不同的超類。 生成了不同的代碼!

您正在專門使父類使用NSNumber並沒有什么意義。 更深層的意圖/目標是什么? 如果您在孩子和父母中都遵循T模式,那會出什么問題?

假設父類有另一個使用T方法xyz 好了,現在它已經綁定到NSNumber ,所以xyz期望一個NSNumber 當然,任何子類都繼承xyz方法。 但是現在假設您的子類是用NSString for T實例化的。對於SpecialDataSource的實例,編譯器應該對方法xyz做些什么? 您看到固有的沖突嗎?

正如“魔術上靈活”的泛型一樣,它們實際上帶有許多非常特定的規則。

一種選擇可能是像這樣定義子類:

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
}

...並且沒有必要進行覆蓋(我不在可以測試這一點的地方。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM