# Classes & types

> Object-oriented Langoost — class declarations, methods, single inheritance with extends and super, named type declarations, and object construction.

# Classes & types

Langoost supports objects, named types, and classes with single inheritance.

## Objects

The simplest structured value is an object literal — keys mapped to values,
accessed with dot or bracket notation:

```goost
let point = {x: 3, y: 4}
println(point.x)          // 3
point["y"] = 5            // update, or add a new key
```

Keys may also be written as string literals, which is handy for keys that aren't
identifiers (e.g. building queries):

```goost
let update = {"$set": {status: "active"}}
```

Objects are also Langoost's map type. See **[types & values](/docs/types)**.

## Type declarations

Give an object shape a name with `type`. This documents the structure and lets
you construct values with `Name{...}`:

```goost
type User = {
    id: int,
    name: string,
    email: string,
}

let u = User{id: 1, name: "alice", email: "alice@example.com"}
println(u.name)           // "alice"
```

Types describe structure; fields are not enforced at runtime (duck typing).

## Classes

A `class` groups methods. Construct an instance with `ClassName{...}` (setting
any fields), then call its methods with dot syntax:

```goost
class Counter {
    fn increment() {
        self.count += 1
        return self.count
    }
    fn value() {
        return self.count
    }
}

let c = Counter{count: 0}
c.increment()
c.increment()
println(c.value())        // 2
```

Inside a method, `self` refers to the instance.

## Inheritance

A class can `extend` one parent and call the parent's implementation with
`super`:

```goost
class Animal {
    fn speak() {
        return "..."
    }
    fn describe() {
        return "I say " + self.speak()
    }
}

class Dog extends Animal {
    fn speak() {
        return "woof"
    }
}

let d = Dog{}
println(d.describe())     // "I say woof"
```

## Interfaces

An `interface` names a set of methods a value must provide. Interfaces are
checked at runtime with the `is` and `as` operators:

```goost
interface Reader {
    fn read()
    fn close()
}

fn consume(x) {
    if x is Reader {          // → bool
        let r = x as Reader   // → x, or throws if it doesn't satisfy Reader
        process(r.read())
        r.close()
    }
}
```

`x is Reader` returns a bool; `x as Reader` returns the value if it satisfies
the interface, or throws `{kind: "InterfaceMismatch", message, want, got}`
otherwise. The check walks a class's parent chain. (Generics are deferred —
without static type checking they would be cosmetic.)

## Notes

Langoost classes are intentionally small. There are **no constructors**
(initialize fields in the `Name{...}` literal), and no static members or
visibility modifiers. For error types and recoverable failures, see
**[error handling](/docs/error-handling)**.