Classes contain both *behavior* and *state*. Behavior is defined in *methods* which are stored in the class. State is defined in *fields*, whose values are stored in each instance.
Unlike most other dynamically-typed languages, in Wren you can have multiple methods in a class with the same name, as long as they take a different number of parameters. In technical terms, you can overload by *arity*. So this class is fine:
When you create an instance with `new`, its constructor will be invoked. It's just a method with a special name. Like methods, you can pass arguments to the constructor by adding a parenthesized parameter list after `new`:
Like other methods, you can overload constructors by arity.
## Operators
Operators are just special syntax for regular [method calls](method-calls.html) on the left hand operand (or only operand in the case of unary operators like `!` and `~`). You can define them like so:
:::dart
class Unicorn {
// Infix:
+(other) {
IO.print("Adding to a unicorn?")
}
// Prefix:
! {
IO.print("Negating a unicorn?!")
}
}
This can be used to define any of these operators:
:::dart
// Infix:
+ - * / % < > <= >= == != & |
// Prefix:
! ~ -
Note that `-` can be both a prefix and infix operator. If there's a parameter list, it's the infix one, otherwise, it's prefix. Since Wren supports overloading by arity, it's no problem for a class to define both.
Operator overloading is really useful for types like vectors and complex numbers where the reader knows what the operators will do, but can make code deeply confusing if overused. When in doubt, use a real name.
## Setters
[Assignment](variables.html) *cannot* be overloaded. It isn't an operator, and its semantics are built right into the language.
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.
By default, any new class inherits from `Object`, which is the superclass from which all other classes ultimately descend. You can specify a different parent class using `is` when you declare the class:
The metaclass hierarchy does *not* parallel the regular class hierarchy. So, if `Pegasus` inherits from `Unicorn`, `Pegasus`'s metaclass will not inherit from `Unicorn`'s metaclass. In more prosaic terms, this means that static methods are not inherited.
Constructors, however, initialize the instance *after* it has been created. They are defined as instance methods on the class and not on the metaclass. That means that constructors *are* inherited.