Classes
Overview
Classes are the most basic kind of type:
- Classes are scoped within a pod and globally identified with the qualified name
podName::ClassName
- Classes contain zero or more uniquely named slots
- Classes always inherit from exactly one super class (
sys::Obj
is the sole exception to this rule) - Classes may inherit zero or more mixins
Classes are declared using the class
keyword:
class MyNewClass {}
Class Modifiers
Classes may be annotated with the following modifiers:
public
internal
abstract
final
const
For example to declare an internal abstract class:
internal abstract class Foo {}
Protection
The public
and internal
keywords define the visibility of the class. A public
class may be used by everyone in the system. An internal
class is visible only to types within the declaring pod. If no protection keyword is specified, the class defaults to public.
Abstract Classes
Abstract classes are classes designed never to be instantiated directly. It is a compiler error to call the constructor of an abstract class. However abstract classes do have constructors for use by their subclasses.
Abstract classes may or may not contain abstract methods. Although all classes which contain abstract methods, must be declared abstract.
The opposite of an abstract class is called a concrete class.
Final Classes
Final classes cannot be subclassed. Any attempt to extend from a final class will result in a compiler error.
Const Classes
Const classes are immutable - once created, an instance is guaranteed to have no state changes. The following rules must be observed with const classes:
- A const class can contain only const fields or fields with no storage:
- abstract fields
- native fields (native code must ensure thread safety)
- calculated fields
- A const class cannot contain any once methods
- A const class must inherit from a const class or
sys::Obj
- A non-const class cannot inherit from a const class
Many fundamental primitive classes are const including Bool
, Int
, Float
, and Str
. Const classes and immutability play an import role in thread safety.
Obj
The root of all classes is the Obj
class. Obj
is the only class which doesn't have a superclass itself.
Instances
Fantom uses a pure object oriented type system. This means that all variables are an object which is an instance of exactly one class.
Reflection
The Type
class is used to represent a class at runtime. You can always get the class type of an object using the Type.of
method:
Type t := Type.of(obj)
Since all objects are instances of a class, this Type
object will always represent a class. Given a Type
which represents a concrete class, you can create new instances reflectively:
t.make // use default make constructor t.make(args) // use make constructor with arguments t.method("makeX").call // lookup and use a named constructor