Classes
Classes are reference types with methods, inheritance, and optional virtual dispatch. Unlike structs (value types), classes are typically heap-allocated.
Defining Classes
nic
class Counter {
pub value: i32;
pub init(self) -> unit {
self.value = 0;
return;
}
pub increment(self) -> unit {
self.value = self.value + 1;
return;
}
pub get(self) -> i32 {
return self.value;
}
}Methods take self as the first parameter to access instance fields.
Creating Instances
Use new to allocate class instances:
nic
fn main() -> unit {
let c: *Counter = new Counter();
c.increment();
c.increment();
let val: i32 = c.get(); // 2
release c; // must free heap memory
return;
}Auto-Dereferencing
Method calls and field access auto-dereference pointers:
nic
fn main() -> unit {
let c: *Counter = new Counter();
// No need for (*c).value or c->value
c.value = 10; // auto-deref for field access
c.increment(); // auto-deref for method call
release c;
return;
}Inheritance
Classes support single inheritance with ::
nic
class Animal {
pub name: i32;
pub age: i32;
pub init(self) -> unit {
self.age = 0;
return;
}
pub speak(self) -> i32 {
return 0;
}
}
class Dog : Animal {
pub breed: i32;
pub speak(self) -> i32 {
return 42; // Woof!
}
}
fn main() -> unit {
let d: *Dog = new Dog();
d.name = 10; // inherited field
d.breed = 3; // own field
release d;
return;
}Polymorphism
Derived class pointers can be assigned to base class pointers:
nic
fn main() -> unit {
let d: *Dog = new Dog();
d.name = 10;
let a: *Animal = d; // OK: *Dog is subtype of *Animal
release d;
return;
}Abstract Classes
Abstract classes cannot be instantiated directly:
nic
abstract class Shape {
pub area(self) -> f64 {
return 0.0;
}
}
class Circle : Shape {
pub radius: f64;
pub area(self) -> f64 {
return 3.14159 * self.radius * self.radius;
}
}
fn main() -> unit {
// let s = new Shape(); // ERROR: cannot instantiate abstract class
let c: *Circle = new Circle();
c.radius = 5.0;
let s: *Shape = c; // OK: polymorphic assignment
release c;
return;
}Virtual Methods
By default, methods use static dispatch. Use virtual for dynamic dispatch:
nic
abstract class Animal {
pub name: i32;
pub virtual speak(self) -> i32 {
return 0;
}
}
class Dog : Animal {
pub virtual speak(self) -> i32 {
return 1; // Woof!
}
}
class Cat : Animal {
pub virtual speak(self) -> i32 {
return 2; // Meow!
}
}
fn make_sound(animal: *Animal) -> i32 {
return animal.speak(); // dynamic dispatch via vtable
}
fn main() -> i32 {
let d: *Dog = new Dog();
let c: *Cat = new Cat();
let r1: i32 = make_sound(d); // returns 1
let r2: i32 = make_sound(c); // returns 2
release d;
release c;
return r1 + r2;
}Constructors and Destructors
Use init and deinit for lifecycle management:
nic
class Resource {
pub id: i32;
pub active: bool;
pub init(self) -> unit {
self.active = true;
return;
}
pub deinit(self) -> unit {
self.active = false;
return;
}
pub use(self) -> i32 {
return self.id;
}
}
fn main() -> i32 {
let r: *Resource = new Resource(); // init called
r.id = 42;
let result: i32 = r.use();
release r; // deinit called, then memory freed
return result;
}Constructors can also take parameters:
nic
class Point {
pub x: i32;
pub y: i32;
pub init(self, x_val: i32, y_val: i32) -> unit {
self.x = x_val;
self.y = y_val;
return;
}
}
fn main() -> i32 {
let p: *Point = new Point(10, 20); // calls init with args
return p.x + p.y; // 30
}Visibility
Fields and methods are private by default:
nic
class Account {
pub name: i32; // public
balance: f64; // private
pub deposit(self, amount: f64) -> unit {
self.balance = self.balance + amount;
return;
}
internal_check(self) -> bool {
return self.balance >= 0.0;
}
}Summary
| Feature | Syntax |
|---|---|
| Class | class Name { fields; methods } |
| Method | pub name(self, ...) -> Type { } |
| Inheritance | class Child : Parent { } |
| Abstract | abstract class Name { } |
| Virtual | pub virtual method(self) -> Type { } |
| Constructor | pub init(self, ...) -> unit { } |
| Destructor | pub deinit(self) -> unit { } |
| Instantiate | new ClassName() or new ClassName(args) |
Next
Learn about Memory Management with new, release, and defer.