Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding generic function error in swift

Here's the code:

class Test<T> { 
    func foo<S:SequenceType where S.Generator.Element == T>(par : S){
        print("foo")
    }
}
class TestInh : Test<Int> { 
    override func foo<S:SequenceType where S.Generator.Element == Int>(par : S) { 
        print("loo")
    } 
}

And it yells such error:

repl.swift:8:19: error: method does not override any method from its superclass
    override func foo<S:SequenceType where S.Generator.Element == Int>(par : S) {
    ~~~~~~~~      ^

How could I override the method in super class Test<Int>?

==================additional=======================

When it comes to the code blow.

class Test<T> { 
    func foo(par : T){
        print("foo")
    }
}
class TestInh : Test<Int> { 
    override func foo(par : Int) { 
        print("loo")
    } 
}

Everything works fine. Not knowing what happened on where statement's appearing.

like image 526
AntiMoron Avatar asked Jan 04 '16 06:01

AntiMoron


2 Answers

When inheriting a non-generic class from a generic one, you should:

  • Use override with non-generic methods; but
  • Use no override with generic ones.

In both cases you can still call super implementation of the said method.

Therefore, this should work:

class Base<T> {
    func testGeneric<S: SequenceType where S.Generator.Element == T>(sequence: S) {
        print("Base \(__FUNCTION__)(sequence: \(sequence.dynamicType))")
    }

    func testNongeneric(element: T) {
        print("Base \(__FUNCTION__)(element: \(element.dynamicType))")
    }
}

class Subclass: Base<Int> {
    func testGeneric<S: SequenceType where S.Generator.Element == Int>(sequence: S) {
        super.testGeneric(sequence)
        print("Subclass \(__FUNCTION__)(sequence: \(sequence.dynamicType))")
    }

    override func testNongeneric(element: Int) {
        super.testNongeneric(element)
        print("Subclass \(__FUNCTION__)(element: \(element.dynamicType))")
    }
}

Test:

let base = Base<Double>()
let subclass = Subclass()

base.testGeneric([])        // Prints: Base testGeneric(sequence: Array<Double>)
subclass.testGeneric([])    // Prints: Base testGeneric(sequence: Array<Int>)
                            //         Subclass testGeneric(sequence: Array<Int>)

base.testNongeneric(0)      // Prints: Base testNongeneric(element: Double)
subclass.testNongeneric(0)  // Prints: Base testNongeneric(element: Int)
                            //         Subclass testNongeneric(element: Int)
like image 93
0x416e746f6e Avatar answered Sep 17 '22 10:09

0x416e746f6e


The reason you received the error is because the method signatures of the func and the override func are different:

func foo<S:SequenceType where S.Generator.Element == T>(par : S)

Is not the same as:

override func foo<S:SequenceType where S.Generator.Element == Int>(par : S)

If inheritance is important to you in this case then you will need to make your subclass a generic entity with a generic type declaration of T, and amend your override func as so:

class Test<T> {

  func foo<S:SequenceType where S.Generator.Element == T>(par : S) {
    print("foo")
  }
}

class TestInh<T> : Test<T> {

  override func foo<S:SequenceType where S.Generator.Element == T>(par : S) {
    print("loo")
  }
}

This should resolve your issue at hand. The reason this resolves is that the method signatures are now the same:

func foo<S:SequenceType where S.Generator.Element == T>(par : S)

Is the same as:

override func foo<S:SequenceType where S.Generator.Element == T>(par : S)

like image 38
wmcbain Avatar answered Sep 17 '22 10:09

wmcbain