Skip to content
skotch
...

Classes and Objects

Skotch supports basic class declarations with primary constructors and instance methods:

class Calculator {
fun add(a: Int, b: Int): Int = a + b
fun multiply(a: Int, b: Int): Int = a * b
}
fun main() {
val calc = Calculator()
println(calc.add(2, 3)) // 5
println(calc.multiply(4, 5)) // 20
}

Classes with constructor properties and field access:

class Point(val x: Int, val y: Int) {
fun distFromOriginSquared(): Int = x * x + y * y
}
fun main() {
val p = Point(3, 4)
println(p.distFromOriginSquared()) // 25
println(p.x) // 3
println(p.y) // 4
}
  • Empty class declarations (class Foo)
  • Primary constructors with val/var parameters
  • Field access from outside the class (obj.field)
  • Field access from inside methods (implicit this)
  • Instance methods called via invokevirtual
  • Constructor calls (Foo(), Point(3, 4))
  • String templates using fields ("Hello, $name!")
FeatureDescription
Body propertiesvar count: Int = 0 in class body
Data classesSynthesized equals, hashCode, toString, copy
InterfacesDeclarations, default methods, multiple implementation
Sealed classesSealed hierarchies with exhaustive when
EnumsEnum constants, values(), members
ObjectsSingleton declarations, companion objects
Nested/inner classesStatic and non-static nested types
Inheritanceopen classes, override, abstract classes

Custom property getters and setters are compiled to synthetic methods:

class Counter {
var count: Int = 0
set(value) {
if (value >= 0) field = value // `field` is the backing field
}
}
fun main() {
val c = Counter()
c.count = 5 // invokes setter
println(c.count) // 5
c.count = -1 // rejected by setter (value < 0)
println(c.count) // still 5
}

Inner classes hold an implicit reference to the enclosing class instance:

class Outer(val x: Int) {
inner class Inner(val y: Int) {
fun sum(): Int = x + y // `x` from outer class
}
}
fun main() {
val outer = Outer(10)
val inner = outer.Inner(5) // pass outer ref implicitly
println(inner.sum()) // 15
}