9

According to Apple's documentation Swift does not necessary require override of initializer. In a following code example Bar inherits initializer of Foo:

class Foo {
  let value: Int
  init(value: Int = 5) {
    self.value = value
  }
}

class Bar: Foo {
}

As soon as we add some generic into Foo such as class Foo<T> { Xcode provides us a error Initializer does not override a designated initializer from its superclass. Is there a documentation or swift evolution discussion that explains why it is happening?


Update. It seems that generic is not a major cause for override requirement. Here are an option how to define a class with generic that does not require override of designated initializer:

protocol FooProtocol {
    associatedtype T
}

class Foo<U>: FooProtocol {
    typealias T = U

    let value: Int
    init(value: Int, otherValue: T) {
        self.value = value
        self.otherValue = otherValue
    }
}

class Bar: Foo<Int> {
}

However there is another interesting observation of behavior. Defining initializer like following cause override requirement:

init(value: Int = 5) {
    self.value = value
}

The funny thing thing that adding one more parameter as following into such designated initializer cause this override requirement to disappear:

init(value: Int = 5, otherValue: T) {
    self.value = value
}

Update 2. I can not find a logical explanation to this behavior, at this point I reported it as Compiler bug — https://bugs.swift.org/browse/SR-1375

Nikita Leonov
  • 5,684
  • 31
  • 37
  • I did some more testing and the problem appears to be _the default value_. Take the `=5` out of your examples and _none_ of them result in the compiler error. – matt May 01 '16 at 00:40

2 Answers2

1

I actually filled a bug report for inheriting from generic class:

enter image description here

It was back in November last year and didn't get an answer yet, so ¯_(ツ)_/¯

sunshinejr
  • 4,834
  • 2
  • 22
  • 32
  • Thanks. It is definitely helpful to know that I am not alone experiencing this issue. Meanwhile I can not count this message as an answer, as it neither documentation nor swift evolution discussion regarding this topic. – Nikita Leonov Apr 30 '16 at 18:50
  • I agree: very interesting, but this is a comment, not an answer. – matt Apr 30 '16 at 22:13
1

It's clearly a bug. Moreover, although the bug is elicited by subclassing a generic, its proximate cause is the default value. This compiles just fine:

class Foo<T> {
    let value: Int
    init(value: Int) {
        self.value = value
    }
}

class Bar: Foo<String> {
}

But this does not:

class Foo<T> {
    let value: Int
    init(value: Int = 5) {
        self.value = value
    }
}

class Bar: Foo<String> {
}

That sort of arbitrary distinction without a difference is a sure indication that this is a compiler bug.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • I suspect, though of course I can't prove, that behind the scenes what's proving confusing for the compiler is that to call `init(value: Int = 5)` without a `value` would be the same as calling `init`. I don't know why that's confusing in the case of a generic, but that's the direction your examples seem to point to. – matt May 01 '16 at 00:49