Переопределение вызова для удобства
Проблема
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
создает ошибку компиляции. Я неправильно понимаю эти понятия инициализации?
Ответы
Ответ 1
Причина override
не нужна:
И наоборот, если вы пишете инициализатор подкласса, который соответствует инициализатору удобства суперкласса, этот инициализатор удобства суперкласса никогда не может быть вызван непосредственно вашим подклассом в соответствии с правилами, описанными выше в цепочке инициализации. Поэтому ваш подкласс не является (строго говоря), обеспечивающим переопределение инициализатора суперкласса. В результате вы не записываете модификатор override
при предоставлении соответствующей реализации инициализатора удобства суперкласса.
Но, как написано, кажется, что это должно сработать - насколько я могу судить, это ошибка компилятора. Если вы измените имя аргумента array
на инициализатор ClassB, например, array2
, то он работает так, как ожидалось. Вы должны файл радар!