Classes
class Person { // declaring a class
var lastName : String; // instance variables
var firstName : String = "unknown"; // default value
function toFullName() { // instance function
return "{firstName} {lastName}";
}
}
def a = Person { // creating new Person (more)
firstName: "John" // no comma or semicolon needed
lastName: "Doe"
};
assert(a.firstName == "John"); // property access
assert(a.toFullName() == "John Doe"); // calling a function
a.firstName = "George";
assert(a.firstName == "George");
def b = Person{}; // Omitting properties
assert(b.lastName == ""); // uninitialized default
assert(b.firstName == "unknown");
def c = new Person(); // Java constructor syntax
assert(c.lastName == ""); // uninitialized default
assert(c.firstName == "unknown");
var r: String = "start";
class InitTester {
var a = "vardefault" on replace { r = "{r}-{a}" };
init { r = "{r}-init" } // init block called after variable initialization
postinit { r = "{r}-postinit" } // postinit is called after init
}
var test = InitTester { a: "varinit" };
assert(r == "start-varinit-init-postinit");
import java.lang.Math; // import Java's Math class
class Point {
var x : Integer; var y : Integer;
}
class Shape {
var name : String;
var points : Point[];
}
class ShapeCollection {
var name : String;
var shapes : Shape[];
}
def myShapes = ShapeCollection {
name: "My Shapes"
shapes: [ // sequence as value
Shape {
name: "Triangle"
points: [ Point { x: 0.5 y: 0.5}, Point { x: 1.5 y: 1.5},
Point { x: 0.5 y: 2.5} ]
},
Shape {
name: "Square"
points: [ Point { x: 5 y: 5}, Point { x: 10 y: 5},
Point { x: 10 y: 10}, Point { x: 5 y: 10} ]
},
Shape {
name: "Near-Circle"
points: for (i in [0..<360])
Point { x: 5 + 5 * Math.cos(2.0 * Math.PI * i / 360.0)
y: 15 + 5 * Math.sin(2.0 * Math.PI * i / 360.0) }
}
]
};
class A { var x; var y; }
def a = A { x: 12, y: 12};
def b = A { x: 12, y: 12};
assert(a != b); // Equality not defined! => no 2 objects are equal
assert(a == a); // Same instance => equal
class B {
var x; var y;
override function equals(o: Object) : Boolean {
if (o instanceof B) { // implementing equality
def b2 = o as B;
(x == b2.x) and (y == b2.y)
}
else
false;
}
}
def d = B { x: 12, y: 12};
def e = B { x: 12, y: 12};
def f = B { x: 5, y: 12};
assert(d == e);
assert(d != f);
class Customer extends Person {
var customerNumber : Integer; // adds a new variable
override var firstName = "Bob"; // override to change default
// or provide a different on replace
override function toFullName() { // override to modify behaviour
// calls super implementation:
"{Person.toFullName()} (customer {customerNumber})"
}
}
def myCustomer = Customer {
firstName: "Tom" lastName: "Miller" customerNumber: 3437
};
def a : Person = myCustomer;
assert(a instanceof Person); // checks class of reference
assert(a instanceof Customer); // checks class of reference
assert(a.customerNumber == 3437); // a declared Person, not Customer
assert((a as Customer).customerNumber == 3437); // casting
var r2: String = "start";
class InitTesterA {
var a = "vardefault" on replace { r2 = "{r2}-{a}" };
init { r2 = "{r2}-initA" }
postinit { r2 = "{r2}-postinitA" }
}
class InitTesterB extends InitTesterA {
var b = "vardefault" on replace { r2 = "{r2}-{b}" };
init { r2 = "{r2}-initB" }
postinit { r2 = "{r2}-postinitB" }
}
var test2 = InitTesterB { a: "varinitA", b: "varinitB" };
assert(r2 == "start-varinitA-varinitB-initA-initB-postinitA-postinitB");
mixin class Counter { // defining a mixin
var counter: Integer;
function countUp() { counter++; }
}
mixin class Greeter { // defining a second mixin
function greet(name: String): String { "Hello {name}!" }
}
class GreetingCounter extends Counter, Greeter { // extending both mixins
function countAndGreet(name: String) {
"{greet(name)} You are visitor number {countUp()}."
}
}
def a : GreetingCounter = GreetingCounter{counter: 2};
assert(a.countAndGreet("Tim") == "Hello Tim! You are visitor number 2.");
def b = Counter{counter: 5}; // Mixins can not be instantiated

