Подтвердить что ты не робот

Переопределение вызова для удобства

Проблема

Override инициализатор удобства подкласса и он создает ошибку компиляции.

Detail

У меня возникают проблемы с пониманием того, почему Swift (v4.1) не позволяет мне переопределить мой инициализатор удобства. Читая документацию, я обнаружил, что эти два правила применимы к моему вопросу:

Правило 1 Если ваш подкласс не определяет какие-либо назначенные инициализаторы, он автоматически наследует все его инициализаторы, назначенные суперклассам.

Правило 2 Если ваш подкласс обеспечивает реализацию всех инициализаторов, назначенных суперклассам, либо путем наследования их в соответствии с правилом 1, либо путем предоставления пользовательской реализации как части определения, то он автоматически наследует все инициализаторы удобства суперкласса.

В приведенном ниже коде я подпадает под первое правило, и все мои инициализаторы удобства наследуются в ClassB. Кроме того, поскольку я унаследовал все назначенные инициализаторы в соответствии с правилом один, я также получаю все мои инициализаторы удобства, унаследованные.

class ClassA<T> {

    // This array would be private and not visible from ClassB
    var array: [T]?

    init() { }

    convenience init(array: [T]) {
        self.init()

        self.array = array
    }
}

class ClassB<T>: ClassA<T> {

    var anotherArray: [T]?

    // I feel like I should include the "override" keyword
    // but I get a compiler error when "override" is added before "convenience init".
    convenience init(array: [T]) {
        self.init()

        self.anotherArray = array
    }
}

// Works fine
let instanceA = ClassA(array: [1, 2])
// Compile error when override is added:
// error: Initializer does not override a designated initializer from its superclass
// note: attempt to override convenience initializer here
//     convenience init(array: [T]) {
//                 ^
let instanceB = ClassB(array: [1, 2])

Но вот что я не понимаю: ClassB имеет немного отличающуюся реализацию init(array:), и я хотел бы переопределить этот инициализатор удобства. Использование ключевого слова Override создает ошибку компиляции. Я неправильно понимаю эти понятия инициализации?

4b9b3361

Ответ 1

Причина override не нужна:

И наоборот, если вы пишете инициализатор подкласса, который соответствует инициализатору удобства суперкласса, этот инициализатор удобства суперкласса никогда не может быть вызван непосредственно вашим подклассом в соответствии с правилами, описанными выше в цепочке инициализации. Поэтому ваш подкласс не является (строго говоря), обеспечивающим переопределение инициализатора суперкласса. В результате вы не записываете модификатор override при предоставлении соответствующей реализации инициализатора удобства суперкласса.

Но, как написано, кажется, что это должно сработать - насколько я могу судить, это ошибка компилятора. Если вы измените имя аргумента array на инициализатор ClassB, например, array2, то он работает так, как ожидалось. Вы должны файл радар!