2015-01-05 3 views
10

У меня есть следующий класс:Generic наследования классов в Swift

class BaseCache<T: Equatable>: NSObject { 

    var allEntities = [T]() 

    // MARK: - Append 

    func appendEntities(newEntities: [T]) { 
     .... 
    } 
} 

Теперь я хочу подкласс, но я получаю досадную ошибку, что мой тип «не соответствует протоколу" Equatable»: enter image description here

Кажется, дженерики в Свифт - настоящая боль в заднице.

+0

Может быть проще просто добавить протокол в определение класса. 'Класс Aftership: Equatable {}' – rakeshbs

+0

Это невозможно, потому что Aftership SDK написан на Objective C –

+0

Может быть, добавьте == func внутри расширения, чтобы он фактически соответствовал протоколу. – ad121

ответ

16

Неверное определение вашего класса TrackingCache. Он повторяет общий параметр:

class TrackingCache<AftershipTracking>: BaseCache<AftershipTracking> { } 

Это должно быть оставлено из:

class TrackingCache: BaseCache<AftershipTracking> { } 

Это вызывает основную ошибку быструю Classes derived from generic classes must also be generic. Вы можете обойти эту проблему, указав тип параметра, который требуется, чтобы быть или наследоваться от AftershipTracking:

class TrackingCache<T: AftershipTracking>: BaseCache<AftershipTracking> { } 

Полный пример:

class BaseCache<T: Equatable>: NSObject { 
    var items: [T] = [] 

    func appendItems(items: [T]) { 
    self.items += items 
    didAppendItems() 
    } 

    func didAppendItems() {} // for overriding 
} 

class AftershipTracking: NSObject { 
    var identifier: Int 
    init(identifier: Int) { 
    self.identifier = identifier 
    super.init() 
    } 
} 

extension AftershipTracking: Equatable { } 

func ==(lhs: AftershipTracking, rhs: AftershipTracking) -> Bool { 
    return lhs.identifier == rhs.identifier 
} 

class TrackingCache<T: AftershipTracking>: BaseCache<AftershipTracking> { 
    override func didAppendItems() { 
    // do something 
    } 
} 

let a = TrackingCache<AftershipTracking>() 
let b = TrackingCache<AftershipTracking>() 

a.appendItems([AftershipTracking(identifier: 1)]) 
b.appendItems([AftershipTracking(identifier: 1)]) 

let result = a.items == b.items // true 
+0

Спасибо за ответ, но я уже пробовал это, и он не работал. Если я определяю свой класс как «класс TrackingCache : BaseCache ', я получаю сообщение об ошибке «Метод не отменяет какой-либо метод из его суперкласса» в каждой строке 'override func'. –

+0

Да, но это еще одна проблема. Ваш класс BaseCache проистекает из чего-то другого, кроме NSObject? Как только вы выберете общий класс из класса Objective-C, производный класс swift больше не сможет видеть супер-методы. Вы можете обойти это, введя промежуточный не общий подкласс в swift. Но это действительно отдельная проблема. Мой ответ - правильное решение вашего вопроса. – lassej

+0

BaseCache происходит непосредственно из NSObject, как указано выше. Даже если я удалю NSObject, это ничего не меняет –

0

это должно работать: < быстры 4>

class TrackingCache<T: AftershipTracking>: BaseCache<T> 

Другой пример:

protocol P { 

} 

class C: P { 

} 

class CS: C { 

} 

class L<T:P> { 
    let c: T 

    init(_ c: T) { 
     self.c = c 
    } 
} 

class LS<T:CS>:L<T> { 

} 

let i = LS(CS()) 

i.c 

cCS сейчас.

Смежные вопросы