The Short Answer
You cannot use self.dynamicType()
without marking init()
as required
because there's no guarantee subclasses of Vehicle
will also implement init()
.
Exploring The Problem
Taking a look at The Swift Programming Language: Initialization, it's mentioned how
subclasses do not inherit their superclass initializers by default
The situations in which a subclass will inherit its superclass' initialisers are:
Assuming that you provide default values for any new properties you
introduce in a subclass, the following two rules apply:
Rule 1
If your subclass doesn’t define any designated initializers, it
automatically inherits all of its superclass designated initializers.
Rule 2
If your subclass provides an implementation of all of its superclass
designated initializers—either by inheriting them as per rule 1, or by
providing a custom implementation as part of its definition—then it
automatically inherits all of the superclass convenience initialisers.
Take a look at the example:
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
}
}
According to the information above, since MySubclass
defined the property otherNum
without an initial value, it doesn't automatically inherit init()
from MySuperclass
.
Now suppose I want to add the following method to MySuperclass
:
func myMethod() {
println(self.dynamicType().num)
}
You'll get the error you described because there is no guarantee subclasses of MySuperclass
will implement init()
(and in this example they don't).
To solve this problem you therefore need to mark init()
as required
, to ensure all subclasses of MySuperclass
implement init()
, and so calling self.dynamicType()
is a valid thing to do. It's the same problem as in your question: Swift knows Vehicle
implements init()
, however it doesn't know any subclasses will implement init()
and so you need to make it required
.
An alternative solution, which isn't suitable in your example, is to mark Vehicle
as final
, meaning Vehicle
can't be subclassed. Then you'll be able to use self.dynamicType()
; but you might as well just use Vehicle()
in that case.