I\'m trying to derive my class from generic class:
class foo {}
class bar : foo {}
But this code fails to compile with
Ssreg,
Unfortunately this is official:
You can subclass a generic class, but the subclass must also be a generic class.
Let us hope Apple fixes this in a future version.
Meanwhile, let us see this as an opportunity to exploit aggregation instead of subclassing.
NOTE:
As a poor man's version of a solution, one could use typealias
:
class foo<T> {}
class bar<Int> : foo<Int> {}
typealias Bar = bar<Int>
This way, the rest of the code can be written just as if Apple already fixed the matter.
An alternative to the typealias
solution is to take the documentation literally:
You can subclass a generic class, but the subclass must also be a generic class.
So we make subclass a generic class, but of another type that we don't use for anything.
class foo<T> {
func doSomething(t:T) -> T {
return t;
}
}
class bar<S> : foo<Int> {
override func doSomething(t:Int) -> Int {
return t * t;
}
}
let b : bar = bar<AnyObject>()
b.doSomething(5) // 25 instead of 5
I prefer this approach to using typealias
because it doesn't pollute the namespace with an additional type. This is of particular importance if the subclass (bar
) is meant to be public
or internal
.
Edit
The documentation no longer includes the phrase about the limitation of generic subclasses. Hopefully this means that Apple plans to change this sooner than later.
This is now officially supported:
class Foo<RelatedType> {
var object: RelatedType? = nil
func myFunction(param: RelatedType) -> RelatedType? {
return nil
}
}
class Bar: Foo<String> {
override func myFunction(param: String) -> String? {
return self.object
}
}
In Swift 2 it's possible to subclass a generic class:
class Something {}
class Base<T> {}
class Fancy : Base<Something> {}
I had the same issue and I found a solution!
class SomeType {
}
class Foo<T> {
}
class Bar<T: SomeType>: Foo<T> {
}
Now you can do:
let bar = Bar()
This will default Bar's type to SomeType. The only drawback is that you can only do this for 'subclassable' types. So for Int
this will not work.