AutolangDocs

Classes & Inheritance

Autolang supports object-oriented programming using classes and single inheritance.

Primary Constructor

A primary constructor is declared directly in the class header. All parameters become members of the class automatically. You can also declare additional properties and functions in the class body.

class Person(val name: String, val age: Int, val id: Int) { // Optimized: All 3 fields are initialized natively at once fun printInfo() { println("${name} [${id}] is ${age} years old") } } val john = Person("John", 25, 1001) john.printInfo()

๐Ÿš€ Performance Tip

We highly recommend using the Primary Constructor for better performance. The compiler recognizes it as a dedicated initialization path and triggers a single native call to store all object data in one pass โ€” instead of sequential assignments.

Secondary Constructor

Use the constructor keyword when you need custom initialization logic or when a class extends another. super() must be the first statement.

class Vector2(val x: Float, val y: Float) class User extends Vector2 { constructor(x: Float, y: Float, name: String) { super(x, y) println("User ${name} created at ${x}, ${y}") } } User(10.0, 20.0, "Alice")
  • A secondary constructor is required when using extends
  • super(...) must be called and must be the first statement

Late Initialization

Use the lateinit modifier to declare a non-nullable property that will be initialized later, bypassing the compiler check for immediate initialization.

class GameEngine { lateinit var config: String fun init() { config = "Loaded Config" } fun start() { println(config) } } val engine = GameEngine() engine.init() engine.start()

Access Modifiers

Control member visibility with access modifiers:

  • public โ€” accessible everywhere (default)
  • private โ€” accessible only inside the same class
  • protected โ€” accessible inside the class and its subclasses
class Account { private var id: Int? protected var balance: Int? constructor(id: Int, balance: Int) { this.id = id this.balance = balance } public fun deposit(amount: Int) { balance = balance! + amount } } class SavingAccount extends Account { constructor() { super(1, 1000) println(balance) // allowed (protected) } } SavingAccount()

Method Override

Use @override to override a base method. Use @no_override to prevent subclasses from overriding a method (makes it "final").

class Animal(val name: String) { fun sound() { } } class Cat extends Animal { constructor() { super("cat") } @override fun sound() { println("Meow") } } class Dog extends Animal { constructor() { super("dog") } @override fun sound() { println("Woof") } } val dog: Animal = Dog() val cat: Animal = Cat() dog.sound() cat.sound()

Static Members

Static members belong to the class itself, not to any instance. Access them via ClassName.member.

class X extends Person { static val k: Int = 99 constructor() { super() } } class Person() println(X.k)

Index Operator Overloading

Define get and set functions to make your class support the [] index operator.

class DailyTemperatures { private val temps: Array<Int> = Array<Int>() fun get(index: Int): Int = temps.get(index) fun set(index: Int, value: Int) { temps.set(index, value) } fun add(t: Int) { temps.add(t) } } val data = DailyTemperatures() data.add(30) data.add(32) data[1] = 35 // calls data.set(1, 35) println("Temp: ${data[1]}") // calls data.get(1)

Type Checking

Use the is operator for runtime type checking.

class Animal() class Cat extends Animal { constructor(){ super() } } class Dog extends Animal { constructor(){ super() } } val x = Cat() println(x is Cat) // true println(x is Animal) // true println(x is Float) // false