Limitation with classes derived from generic classes in swift

前端 未结 5 1218
礼貌的吻别
礼貌的吻别 2020-12-08 09:26

I\'m trying to derive my class from generic class:

class foo {}
class bar : foo {}

But this code fails to compile with

相关标签:
5条回答
  • 2020-12-08 10:08

    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.

    0 讨论(0)
  • 2020-12-08 10:23

    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.

    0 讨论(0)
  • 2020-12-08 10:24

    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
        }
    }
    
    0 讨论(0)
  • 2020-12-08 10:30

    In Swift 2 it's possible to subclass a generic class:

    class Something {}
    
    class Base<T> {}
    
    class Fancy : Base<Something> {}
    
    0 讨论(0)
  • 2020-12-08 10:32

    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.

    0 讨论(0)
提交回复
热议问题