5.1.18. Classes and Inheritance

This tutorial covers defining classes, constructors, super() and super.method(), abstract and virtual methods, inheritance with override, polymorphism, private members, and static fields/methods.

5.1.18.1. Defining a class

Classes are like structs with virtual methods and inheritance:

class Shape {
    name : string

    def Shape(n : string) {
        name = n
    }

    def abstract area : float

    def describe {
        print("{name}: area = {area()}\n")
    }
}

5.1.18.2. Inheritance and super

Single-parent inheritance with class Derived : Base. Use super() to call the parent constructor:

class Circle : Shape {
    radius : float

    def Circle(r : float) {
        super("Circle")       // calls Shape`Shape(self, "Circle")
        radius = r
    }

    def override area : float {
        return 3.14159 * radius * radius
    }
}

Use super.method() to call the parent’s version of a method, bypassing virtual dispatch:

class Rectangle : Shape {
    width : float
    height : float

    def Rectangle(w, h : float) {
        super("Rectangle")
        width = w
        height = h
    }

    def override describe {
        super.describe()      // calls Shape`describe(self)
        print("  (w={width}, h={height})\n")
    }
}

The compiler rewrites super() to Parent`Constructor(self, ...) and super.method() to Parent`method(self, ...).

5.1.18.3. Creating instances

Use new to create a class on the heap:

var c = new Circle(5.0)
c.describe()

5.1.18.4. Polymorphism

Base pointers hold any derived instance. Method calls dispatch virtually:

var shapes : array<Shape?>
shapes |> push(new Circle(3.0))
shapes |> push(new Rectangle(2.0, 5.0))

for (s in shapes) {
    s.describe()    // calls the correct area() for each type
}

5.1.18.5. Private members

class Counter {
    private count : int = 0
    def increment { count += 1 }
    def get_count : int { return count }
}

5.1.18.6. Static fields and methods

static fields are shared across all instances. def static methods access static fields but not self:

class Tracker {
    static total : int = 0
    id : int

    def Tracker {
        total += 1
        id = total
    }

    def static getTotal : int {
        return total
    }

    def static reset {
        total = 0
    }
}

Call static methods with backtick syntax:

print("{Tracker`getTotal()}\n")
Tracker`reset()

5.1.18.7. Key concepts

  • abstract — subclasses must implement

  • override — replaces a parent method

  • sealed — prevents further overriding or inheritance

  • self — implicit pointer to current instance

  • super() — calls parent constructor

  • super.method() — calls parent’s version of a method

  • def static — method without self, accesses static fields only

  • ClassName`method() — call static methods from outside

Note

Structs can also have methods via the [class_method] annotation from daslib/class_boost, which adds an implicit self parameter to static functions on structs.

See also

Classes, Structs in the language reference.

Full source: tutorials/language/18_classes.das

Next tutorial: Generic Programming