Overriding function signature--documented?

I was surprised and *pleased* to find that I could override a return type on a function, though the documentation says the compiler checks for a "match." This matching seems to treat the return type with subtle special consideration--but where is this documented? What am I missing?


Playground code:

class A {

}

class B : A {

}

class D {

func arbitraryFactory() -> A {

return A()

}

func identify(anID: A) {

print(anID)

}

}

class E : D {

override func arbitraryFactory() -> B { // subclass as return type similar enough to require "override"

return B()

}

func arbitraryFactory() -> E { // different enough not to require "override"

return E()

}

func identify(anID: B) { // subclass as input different enough not to require "override"

print(anID)

}

}

Replies

A Swift function signature includes its names, input parameters and its return type. So, if you wrote this:

let f = E().arbitraryFactory()

what would f's type be? The compiler would complain that f's type is ambiguous; it's not clear which of the two functions should be called, whether a B or an E should be returned. You'd need to make it explicit:

let f : B = E().arbitraryFactory()


The reason one requires an override and the other does not: returning an E doesn't conform to the 'super' function signature, but returning a B does, because a B is an A. What matters with the inherited function is that, when called, an A is returned; the overridden signature is allowed to be more specific about its return type.

With the identity function the same can't be said; the 'overridden' signature type isn't general enough with its input arguments - E().identify(A()) would call D's function, not E's, because E's isn't general enough.