Init Methods
An init method is a special kind of method which is used when creating new objects. The syntax for init methods is:
class Foo {
init(<parameters>) {
<statements>
}
}
init
parameters are defined just like other method parameters, but unlike normal methods,
init
methods do not have a name or return type. init
methods are implicitly invoked when
creating new objects. For instance, if we define a Point
class as follows:
class Point : Immutable {
def x:Int
def y:Int
constructor(x:Int, y:Int) {
self.x := x
self.y := y
}
}
we can create a new Point
as follows:
def point := Point(5, 7)
This will create a new Point
object and invoke its init
method with parameters
5
and 7
.
Default Init Methods
If a class does define any init
methods, the compiler automatically provides it with a
default init. The default init looks like:
init() {
}
In other words, it is public, takes no parameters and does nothing. Defining any other init
methods will suppress the default init
. You may wish to create non-instantiable objects by
defining:
class CannotCreate {
@private
init() {
}
}
Assuming this is the only init
method, no one outside of this source code file can create an
instance of the class.
Init Rules
The object must be fully initialized before calling any instance methods on it or returning from
the init
method. An object is fully initialized when all of its fields which do not have
default values have been initialized and a superclass init
method has been
invoked.
Calling Superclass Inits
Frost requires a superclass init
method to be invoked after the subclass initializes its own
fields, and before the subclass calls any instance methods.
If you do not explicitly invoke another init
method, Frost appends an implicit call to the
no-argument superclass init
method, exactly as if your init
method ended with a call to
super.init()
. If there is no no-argument superclass init
, or if it is not legal to call the
superclass init
at this point (because you have already called an instance method), an error will
be generated.
Invoking Other Constructors
You may directly call another init
method in order to delegate to it, as in:
class Error {
def msg:String
init(msg:String) {
self.msg := msg
}
init(file:Path, line:Int) {
init("error at \{file.name()}:\{line}")
}
}
The object is considered to be fully initialized after the call to the other init
method resolves.
The call to the other init
method need not be the very first thing that happens, but the object
must be fully initialized prior to calling any instance methods on it.
An init method may only call one other init method, whether it delegates to a self
or to a
super
init
method.