3 Constructors in Nit behave differently.
5 Their objective is double :
7 * be compatible with full multiple-inheritance
8 * be simple enough to be KISS and compatible with the principle of least surprise.
11 ## `new` construction and simple classes
13 Classes in OO models are often a simple aggregates of attributes and methods.
15 By default, the `new` construction require a value for each attribute defined in a class without a default value.
20 var description: String
23 var p = new Product("ABC", "Bla bla", 15.95)
27 In subclasses, additional attributes are automatically collected.
32 var description: String
40 var book = new Book("ABC", "Bla bla", 15.95, "John Doe")
44 ## special `init` method
46 The special init method is automatically invoked after the end of a `new` construction.
47 It is used to perform additional systematic tasks.
49 Because the `init` is run at the end of the initialization sequence, initialized attributes are usable in the body.
54 var description: String
57 class OverpricedProduct
64 var op = new OverpricedProduct("ABC", "Bla bla", 15.95)
65 assert op.price.is_approx(159.50, 0.001)
69 ## Uncollected attributes
71 There is three cases for an attributes to not be collected in the `new`.
73 * Attributes with a default value
74 * Attributes with the annotation `noinit`
75 * Attributes introduced in refinement of classes
80 var description: String
86 var total_price: Float is noinit
89 total_price = price * (1.0 + tax_rate/100.0)
92 var tp = new TaxedProduct("ABC", "Bla bla", 15.95)
93 assert tp.total_price.is_approx(17.52905, 0.00001)
96 Note: The orchestration here is important. In order, the following is executed:
98 1. All defauts values are computed and set
99 2. Setters are invoked.
100 3. `init` is invoked.
102 Therefore, `total_price` cannot be initialised with a default value, because at the time of the computation of the default values, the attribute `price` in not yet initialised.
105 ## Generalized initializers
107 Initializers are methods that are automatically invoked by the new.
108 In fact, by default, the setter of an attribute is used as a initializer.
110 `autoinit` is used to register a method as a setter.
115 var description: String
120 fun set_xy(x, y: Int) is autoinit do z = x * 10 + y
123 var fp = new FooProduct("ABC", "Bla bla", 15.96, 1, 3)
127 Generalized setters are a powerful tool but often needed in only rare specific cases.
128 In most case, there is no reason that an argument of a `new` construction is not stored in the object as a real attribute.
133 As explained above, one of the main advantage of these constructors is their compatibility with multiple inheritance.
138 var description: String
141 class OverpricedProduct
151 var total_price: Float is noinit
154 total_price = price * (1.0 + tax_rate/100.0)
159 fun set_xy(x, y: Int) is autoinit do z = x * 10 + y
163 super OverpricedProduct
167 var mp = new MultiProduct("ABC", "Bla bla", 15.96, 1, 3)
168 assert mp.id == "ABC"
169 assert mp.price == 159.6
170 assert mp.total_price == 175.4
177 Named `init` are less flexible trough inheritance, thus should no be used.
178 They allow to have additional constructor for classes and more control in the construction mechanism.
190 init polar(r, phi: Float)
197 redef fun to_s do return "({x},{y})"
199 var p1 = new Point(1.0, 2.0)
200 assert p1.to_s == "(1,2)"
201 var p2 = new Point.origin
202 assert p2.to_s == "(0,0)"
203 var p3 = new Point.polar(1.0, 2.0)
204 assert p3.to_s == "(-0.4161,0.9092)"
210 nameless `init` defined with argument or with an explicit visibility are still accepted as a fallback of the old-constructors.
211 They should not be used since they will be removed in a near future.
216 `new` factories permit to completely shortcut the class instantiation mechanim.
217 It could be used to provide `new` syntax on non-concrete class (mainly `extern class`).
219 `new` factories behave like a top-level function that return the result of the construction.
220 It is basically some kind of syntactic sugar.
223 abstract class Person
228 return new Adult(age)
230 return new Child(age)