> For the complete documentation index, see [llms.txt](https://zaidlang.gitbook.io/z/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zaidlang.gitbook.io/z/language/classes.md).

# Classes

Classes define an objects *behavior* and *state*. Behavior is defined by [methods](/z/language/method-calls.md) which live in the class. Every object of the same class supports the same methods. State is defined in fields, whose values are stored in each instance.

### Defining A Class <a href="#defining-a-class" id="defining-a-class"></a>

Classes are created using the `class` keyword, unsurprisingly:

```dart
class CoffeeMaker {
  //
}
```

This creates a class named `CoffeeMaker` with no methods or fields.

### Methods <a href="#methods" id="methods"></a>

To add functionality to our coffee maker class, we need to give it methods.

```dart
class CoffeeMaker {
    function brew() {
        printftw("Your coffee is now brewing.")
    }
}
```

This defines a `brew` method that takes no arguments. To add parameters, put their names inside the parentheses:

```dart
class CoffeeMaker {
    function brew(dosage, temperature) {
        printftw("Your %s of coffee is now brewing at %s degrees.".format(dosage, temperature))
    }
}
```

### Method Scope <a href="#method-scope" id="method-scope"></a>

Up to this point, "[scope](/z/language/variables.md#scope)" has been used to talk exclusively about [variables](/z/language/variables.md). In a procedural language like C, or a functional one like Scheme, that's the only kind of scope there is. But object-oriented languages like Zaidlang introduce another kind of scope: *object scope*. It contains the methods that are available on an object. When you write:

```dart
Coffee.brew()
```

you're saying "look up the method `brew` in the scope of the object `Coffee`". In this case, the fact that you want to look up a *method* `brew` and not a *variable* is explicit. That's what `.` does and the object to the left of the period is the object you want to look up the method on.

#### `this` <a href="#this" id="this"></a>

Things get more interesting when you're inside the body of a method. When the method is called on some object and the body is being executed, you often need to access that object itself. You can do that using `this`.

```dart
class CoffeeMaker {
    function setGrind(grind) {
        this.grind = grind
    }

    function printGrind() {
        this.setGrind("course")

        printftw(this.grind)
    }
}
```

The `this` keyword works sort of like a variable, but has special behavior. It always refers to the instance whose method is currently being executed. This lets you invoke methods on "yourself".

It's an error to refer to `this` outside of a method. However, it's perfectly fine to use it *inside* a method. When you do, `this` still refers to the instance whose *method* is being called:

```dart
class CoffeeMaker {
    function setGrind(grind) {
        this.grind = grind
    }

    function printGrindThrice() {
        this.setGrind("course")

        for (i in 1 .. 3) {
            printftw(this.grind)
        }
    }
}
```

This is unlike Lua and Dart which can "forget" `this` when you create a callback inside a method. Zaidlang does what you want here and retains the reference to the original object.

(In technical terms, a function's closure includes `this`. Zaidlang can do this because it makes a distinction between methods and functions.)

### Constructors <a href="#constructors" id="constructors"></a>

We've seen how to define classes and how to declare methods on them. Our coffee maker can brew coffee, but we don't actually have any way to control it. To create *instances* of a class, we need a *constructor*. You define one like so:

```dart
class CoffeeMaker {
    function constructor(grind, temperature) {
        printftw("Grind set to: %s".format(grind))
        printftw("Temperature set to: %s".format(temperature))
    }
}
```

The `constructor` keyword says we're defining a constructor. To make a coffee maker now, we can now pass through the set arguments to customize our class:

```dart
drip = CoffeeMaker.new("flat", "200")
chemex = CoffeeMaker.new("coarse", "202")
pourOver = CoffeeMaker.new("fine", "202")
frenchPress = CoffeeMaker.new("very course", "202")
```

Note that we didn't need to call the `constructor` method directly. A constructor is actually a method on the class. When we reference a class using `new()`, Zaidlang creates the new instance, then it invokes the *constructor* on that instance. This is where the constructor body you defined gets run.

This distinction is important because it means inside the body of the constructor, you can access `this`, assign fields, etc.

### Fields <a href="#fields" id="fields"></a>

All state stored in instances are stored in *fields*. Each field has a name, are bound to `this`, and act the same as variables.

```dart
class CoffeeMaker {
    function constructor(grind, temperature) {
        this.grind = grind
        this.temperator = temperature

        this.printSettings()
    }

    function printSettings() {
        printftw("Grind set to: %s".format(this.grind))
        printftw("Temperature set to: %s".format(this.temperature))
    }
}
```

### Inheritance <a href="#inheritance" id="inheritance"></a>

A class can inherit from a "parent" or *superclass*. When you invoke a method on an object of some class, if it can't be found, it walks up the chain of superclasses looking for it there.

To inherit another class, use `extends` when you declare your class:

```dart
class Bar extends foo {
  //
}
```

This declares a new class Bar that inherits from Foo.
