Ответ 1
Короткий ответ
Вы не можете использовать self.dynamicType()
без маркировки init()
как required
, потому что нет никаких подклассов Vehicle
, которые также будут реализованы init()
.
Изучение проблемы
Взглянув на Язык быстрого программирования: Инициализация, он упомянул, как
Подклассыне наследуют свои инициализаторы суперкласса по умолчанию
Ситуации, в которых подкласс будет наследовать свои инициализаторы суперкласса:
Предполагая, что вы предоставляете значения по умолчанию для любых новых свойств, вы ввести в подкласс, применяются следующие два правила:
Правило 1
Если ваш подкласс не определяет какие-либо назначенные инициализаторы, он автоматически наследует все его инициализаторы, назначенные суперклассам.
Правило 2
Если ваш подкласс обеспечивает реализацию всего своего суперкласса назначенные инициализаторы - либо путем наследования их в соответствии с правилом 1, либо путем предоставляя пользовательскую реализацию как часть ее определения - тогда это автоматически наследует все инициализаторы удобства суперкласса.
Взгляните на пример:
class MySuperclass {
let num = 0
// MySuperclass is given `init()` as its default initialiser
// because I gave `num` a default value.
}
class MySubclass : MySuperclass {
let otherNum: Int
init(otherNum: Int) {
self.otherNum = otherNum
}
}
В соответствии с приведенной выше информацией, поскольку MySubclass
определил свойство otherNum
без начального значения, оно не наследует автоматически init()
из MySuperclass
.
Теперь предположим, что я хочу добавить следующий метод в MySuperclass
:
func myMethod() {
println(self.dynamicType().num)
}
Вы получите описанную вами ошибку, потому что нет никаких подклассов MySuperclass
для реализации MySuperclass
будет реализовывать init()
(и в этом примере это не так).
Чтобы решить эту проблему, вам необходимо пометить init()
как required
, чтобы гарантировать, что все подклассы MySuperclass
реализуют init()
, и поэтому вызов self.dynamicType()
- это правильная вещь. Это та же проблема, что и в вашем вопросе: Swift знает Vehicle
реализует init()
, однако он не знает, что какие-либо подклассы будут реализовывать init()
, и поэтому вам нужно сделать это required
.
Альтернативным решением, которое не подходит в вашем примере, является отметка Vehicle
как final
, то есть Vehicle
не может быть подклассифицирована. Тогда вы сможете использовать self.dynamicType()
; но вы можете просто использовать Vehicle()
в этом случае.