In subclasses, additional attributes are automatically collected.
~~~
+class Product
+ var id: String
+ var description: String
+ var price: Float
+end
class Book
super Product
var author: String
Because the `init` is run at the end of the initialization sequence, initialized attributes are usable in the body.
~~~
+class Product
+ var id: String
+ var description: String
+ var price: Float
+end
class OverpricedProduct
super Product
init
end
end
var op = new OverpricedProduct("ABC", "Bla bla", 15.95)
-assert op.price == 159.50
+assert op.price.is_approx(159.50, 0.001)
~~~
* Attributes introduced in refinement of classes
~~~
+class Product
+ var id: String
+ var description: String
+ var price: Float
+end
class TaxedProduct
super Product
var tax_rate = 9.90
end
end
var tp = new TaxedProduct("ABC", "Bla bla", 15.95)
-assert tp.total_price == 17.52905
+assert tp.total_price.is_approx(17.52905, 0.00001)
~~~
Note: The orchestration here is important. In order, the following is executed:
`autoinit` is used to register a method as a setter.
~~~
+class Product
+ var id: String
+ var description: String
+ var price: Float
+end
class FooProduct
super Product
fun set_xy(x, y: Int) is autoinit do z = x * 10 + y
As explained above, one of the main advantage of these constructors is their compatibility with multiple inheritance.
~~~
+class Product
+ var id: String
+ var description: String
+ var price: Float
+end
+class OverpricedProduct
+ super Product
+ init
+ do
+ price = price * 10.0
+ end
+end
+class TaxedProduct
+ super Product
+ var tax_rate = 9.90
+ var total_price: Float is noinit
+ init
+ do
+ total_price = price * (1.0 + tax_rate/100.0)
+ end
+end
+class FooProduct
+ super Product
+ fun set_xy(x, y: Int) is autoinit do z = x * 10 + y
+ var z: Int is noinit
+end
class MultiProduct
super OverpricedProduct
super TaxedProduct
end
var mp = new MultiProduct("ABC", "Bla bla", 15.96, 1, 3)
assert mp.id == "ABC"
-assert mp.price == 159.6
-assert mp.total_price == 175.4
+assert mp.price.is_approx(159.6, 0.001)
+assert mp.total_price.is_approx(175.4, 0.001)
assert mp.z == 13
~~~
redef fun to_s do return "({x},{y})"
end
var p1 = new Point(1.0, 2.0)
-assert p1.to_s == "(1,2)"
+assert p1.to_s == "(1.0,2.0)"
var p2 = new Point.origin
-assert p2.to_s == "(0,0)"
+assert p2.to_s == "(0.0,0.0)"
var p3 = new Point.polar(1.0, 2.0)
-assert p3.to_s == "(-0.4161,0.9092)"
+assert p3.to_s == "(-0.416,0.909)"
~~~