# Confused about when I need "override"

**URL:** <https://forums.swift.org/t/confused-about-when-i-need-override/48970>\
**Category:** Using Swift\
**Created:** [May 27, 2021, 1:04am UTC](https://forums.swift.org/t/confused-about-when-i-need-override/48970 "2021-05-27T01:04:23Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ericsink](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ericsink/32/16618_2.png) [@ericsink](https://forums.swift.org/u/ericsink)\
**Post date:** [May 27, 2021, 1:04am UTC](https://forums.swift.org/t/confused-about-when-i-need-override/48970/1 "2021-05-27T01:04:23Z")

</div>

In the following snippet, I am trying to understand why swiftc says I need the `override` keyword for `D.bar()` but not for `D.foo()`.

```swift
class A {
}

class B : A {
}

class C {
    public func foo(x : A) {
    }

    public func bar(x : (A) -> Void) {
    }
}

class D : C {
    public func foo(x : B) {
    }

    // ERROR -- needs override
    public func bar(x : (B) -> Void) {
    }
}

```

The Swift compiler complains that `D.bar()` overrides `C.bar()` so it needs the `override` keyword. Through experimentation, I _think_ this is because `B` is a subclass of `A`, so the function type `(B) -> Void` is considered the same as `(A) -> Void`.

But if that's true, shouldn't similar reasoning apply to `D.foo()`? The compiler accepts this one without `override`. In fact, if I add the `override` keyword to `D.foo()`, it complains.

I'm using Swift 5.4.

Any insight here would be appreciated.

---

<div class="post-metadata">

**Author:** ![grynspan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/grynspan/32/15315_2.png) [@grynspan](https://forums.swift.org/u/grynspan)\
**Post date:** [May 27, 2021, 2:30am UTC](https://forums.swift.org/t/confused-about-when-i-need-override/48970/2 "2021-05-27T02:30:45Z")

</div>

Hi Eric!

This was subtle to think about, but I _don't_ think this diagnostic is wrong. `foo(x:)` does not override (merely overloads) because if it did override, it would violate the [Liskov substitution principle](https://en.wikipedia.org/wiki/Liskov_substitution_principle). In the case of `bar(x:)`, I don't see any way to produce an `A` where only a `B` is allowed, so the principle does not appear to be violated.

Let's walk through it. `bar(x:)` doesn't take an `A` or `B`, it takes a closure that then takes an `A` or `B`. In the context of `D.bar(x:)`, the only valid thing to pass to `x` is an instance of `B`. In the context of `C.bar(x:)`, any `A` can be passed. If somebody upcasts a `D` to `C`, then calls `bar(x:)` on it and passes a closure taking `A` instead of `B`, then any `B` passed to the closure by `D.bar(x:)` is still a valid argument to that closure. Thus, the principle is not violated.

If you've got a counterexample that violates the LSP, I'd love to see it—it would definitely be worth a compiler bug report!

---

<div class="post-metadata">

**Author:** ![Anachron](https://avatars.discourse-cdn.com/v4/letter/a/bc8723/32.png) [@Anachron](https://forums.swift.org/u/Anachron)\
**Post date:** [May 27, 2021, 9:46am UTC](https://forums.swift.org/t/confused-about-when-i-need-override/48970/3 "2021-05-27T09:46:39Z")

</div>

To add to the above explanation: in FP lingo, the appropriate terms are covariant and contravariance.

The question you need to ask is: can the method in the subclass be used to derive a correct and total implementation of the method in the super class?

In case of foo, this doesn’t work, because not all As are Bs. In case of Bar, it does work, because any function that handles arbitrary As can handle in particular all Bs. In one of the methods, A is in covariant position, in the other one in contravariant position.

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [May 27, 2021, 12:37pm UTC](https://forums.swift.org/t/confused-about-when-i-need-override/48970/4 "2021-05-27T12:37:54Z")

</div>

> [@ericsink](#):
>
> Through experimentation, I _think_ this is because `B` is a subclass of `A` , so the function type `(B) -> Void` is considered the same as `(A) -> Void` .

Close, but not quite correct:

The type `(B) -> Void` is a **supertype** of `(A) -> Void`.

Anywhere you have an instance of type `(A) -> Void`, you can upcast it to `(B) -> Void` and it will work fine. After all, the only thing you can do with a `(B) -> Void` is call it by passing in an instance of `B`, and any `B` is also an `A`.

More generally, if `A: B` and `U: V`, then the type `(B) -> U` is a supertype of `(A) -> V`, or equivalently, `(A) -> V` is a subtype of `(B) -> U`.

---

<div class="post-metadata">

**Author:** ![ericsink](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ericsink/32/16618_2.png) [@ericsink](https://forums.swift.org/u/ericsink)\
**Post date:** [May 27, 2021, 1:18pm UTC](https://forums.swift.org/t/confused-about-when-i-need-override/48970/5 "2021-05-27T13:18:14Z")

</div>

TIL more about covariance than I knew before.

Because this situation involves closures instead of, say, collections, my mind just didn't think of it in terms of coariance or contravariance. The relevant wikipedia page contains some good info on how these concepts play w.r.t. function types:

> **[Covariance and contravariance (computer science) | Function types](https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Function_types)**
>
> Languages with first-class functions have function types like "a function expecting a Cat and returning an Animal" (written Cat -\> Animal in OCaml syntax or Func\<Cat,Animal\> in C# syntax).
> Those languages also need to specify when one function type is a subtype of another—that is, when it is safe to use a function of one type in a context that expects a function of a different type. 
> It is safe to substitute a function f for a function g if f accepts a more general type of argument and returns a...

Below is my original code snippet, with less whitespace this time, and with the signatures of the `bar` methods "inverted", showing how contravariance for function parameters makes the subtyping go "in the opposite direction".

```swift
class A {}
class B : A {}
class C {
    public func foo(x : A) {}
    public func bar(x : (B) -> Void) {}
}
class D : C {
    public func foo(x : B) {}
    public func bar(x : (A) -> Void) {}
}

```

Thanks for the helpful replies!

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [May 27, 2021, 1:30pm UTC](https://forums.swift.org/t/confused-about-when-i-need-override/48970/6 "2021-05-27T13:30:26Z")

</div>

> [@ericsink](#):
>
> ```swift
> class A {}
> class B : A {}
> class C {
> public func foo(x : A) {}
> public func bar(x : (B) -> Void) {}
> }
> class D : C {
> public func foo(x : B) {}
> public func bar(x : (A) -> Void) {}
> }
> 
> ```

Just to be abundantly clear on this, now _neither_ `foo` nor `bar` is an override.

You can test this by adding print statements into the function bodies, like `print("C.foo")` and so forth. Then a function like this:

```swift
func foobar(_ c: C) {
  c.foo(x: A())
  c.bar{ _ in }
}

foobar(D())

```

Will show that the versions from `C` were used, not the versions from `D`. (The same thing holds if `foobar` is generic over `T: C`, or if it is an extension method on `C`.)

---

<div class="post-metadata">

**Author:** ![ericsink](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ericsink/32/16618_2.png) [@ericsink](https://forums.swift.org/u/ericsink)\
**Post date:** [May 27, 2021, 1:40pm UTC](https://forums.swift.org/t/confused-about-when-i-need-override/48970/7 "2021-05-27T13:40:19Z")

</div>

> [@Nevin](#):
>
> Just to be abundantly clear on this, now _neither_ `foo` nor `bar` is an override.

Yes. Good clarification. Thanks.

---

<div class="post-metadata">

**Author:** ![grynspan](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/grynspan/32/15315_2.png) [@grynspan](https://forums.swift.org/u/grynspan)\
**Post date:** [May 27, 2021, 3:01pm UTC](https://forums.swift.org/t/confused-about-when-i-need-override/48970/8 "2021-05-27T15:01:12Z")

</div>

> [@Anachron](#):
>
> To add to the above explanation: in FP lingo, the appropriate terms are covariant and contravariance.

Hah! I can never remember which is which so I just avoid saying either. 😄
