**************************************************************************
** title:      Classes
** author:     Brian Frank
** created:    8 Dec 07
** copyright:  Copyright (c) 2007, Brian Frank and Andy Frank
** license:    Licensed under the Academic Free License version 3.0
**************************************************************************

Overview [#overview]
********************
Classes are the most basic kind of [type]`TypeSystem#types`:

  - 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 [#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 [#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]
============================
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]`Methods#abstract`.
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]
======================
Final classes cannot be subclassed.  Any attempt to extend from a final
class will result in a compiler error.

Const Classes [#const]
======================
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]`Fields#const`
   or fields with no storage:
     a. [abstract fields]`Fields#abstract`
     b. [native fields]`Natives#fields` (native code must ensure thread safety)
     c. [calculated fields]`Fields#calculated`
 - A const class cannot contain any [once methods]`Methods#once`
 - 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]`Concurrency#immutability`.

Obj [#obj]
**********
The root of all classes is the `sys::Obj` class.  'Obj' is the only
class which doesn't have a superclass itself.

Instances [#instances]
**********************
Fantom uses a [pure object oriented]`TypeSystem#pureOO` type system.
This means that all variables are an object which is an instance
of exactly one class.

Reflection [#reflection]
************************
The `sys::Type` class is used to represent a class at runtime.  You
can always get the class type of an object using the `sys::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



