    [NAME]
    ALL.dao.class.definition

    [TITLE]
    Definition

    [DESCRIPTION]

    Classes are defined using the class keyword, followed by a class name and base/parent
    classes if any, and then the class body. The following is the simplest class:

       1  class SimplestClass
       2  {
       3  }

    which has no base classes and contains no member fields. In order for the class to have
    meaningful use, it must contains some fields to define the states or behavior of the
    class or its instance.

     0.1   Member Data Field

    Class supports three types data of fields:
      *  constant: declared with keyword const;
      *  static variable: declared with keyword static;
      *  instance variable: declared with keyword var;
    Such fields can be declared with or without explicit types, and with or without default
    or initialization values, in the same way as specifying types and/or default values for
    function parameters. For example, the following can be used for instance variables,

       1  var variable;
       2  var variable = init_value;
       3  var variable : typename;
       4  var variable : typename = init_value;

     0.2   Member Method Field

    Dao class supports multiple type of member methods such as constructor, static method,
    instance method and methods for overloaded operators.

    Class methods must be declared with keyword routine (or its alias keywords function or
    sub) for constructors and normal methods, or keyword operator for operator overloading.

    The access of class fields and methods can be restricted by three permission keywords:
      *  public: publically accessible without restriction;
      *  protected: accessible from the class and its derived classes;
      *  private: only accessible from the class;

     0.3   Class Instance

    The following is a simple class without a constructor:

       1  class Contact
       2  {
       3      const description = 'This is a class for contact information'
       4      var   name = 'Nobody'
       5      var   address = 'Nowhere'
       6
       7      routine Show(){ io.writeln( name, 'lives at', address ) }
       8  }

    There are two ways to create instances of such simple classes:
      *  Call the default constructor which will initialize the instance variables with their
         default values:

            1  obj = Contact()

      *  Enumerate the values of the instance variables:

            1  obj = Contact{ 'Mike', '123 Main Street' }

         Field names can be specified for the values, so that these values can appear in
         arbitrary order:

            1  obj = Contact{ address => '123 Main Street', name => 'Mike' }

         Please note, only simple classes without base classes and explicit constructors can
         use this kind of instance construction.

     0.4   Class Constructor

    In a class, the methods with the same name as the class itself are considerred as class
    constructors. When the class name is used for a function call, a class instance will be
    created and then the appropriate constructor will be invoked to initialize the instance.
    Here is the same class as above, but with a constructor:

       1  class Contact
       2  {
       3      const description = 'This is a class for contact information'
       4      var   name = 'Nobody'
       5      var   address = 'Nowhere'
       6
       7      routine Contact( name : string, address = 'Unknown' ){
       8          self.name = name
       9          self.address = address
      10      }
      11
      12      routine Show(){ io.writeln( name, 'lives at', address ) }
      13  }

    Now calling the constructor is the only way to create an instance of Contact:

       1  obj = Contact( 'Mike', '123 Main Street' )

    Class constructors can be overloaded in the same way as normal functions:

       1  class Contact
       2  {
       3      const description = 'This is a class for contact information'
       4      var   name = 'Nobody'
       5      var   address = 'Nowhere'
       6
       7      routine Contact( name : string, address = 'Unknown' ){
       8          self.name = name
       9          self.address = address
      10      }
      11      routine Contact( another : Contact ){
      12          name = another.name
      13          address = another.address
      14      }
      15
      16      routine Show(){ io.writeln( name, 'lives at', address ) }
      17  }

     0.5   Static Method

    Static methods can be defined by specifying the static keyword before the routine
    keyword. Such method can be invoked without class instance, for this, they are not
    allowed to use class instance variables.

       1  class Klass
       2  {
       3      var id = 123
       4      static info = 'Klass'
       5      static routine StaticMethod(){ id = 1 }  # Wrong;
       6      static routine StaticMethod(){ io.writeln( info ) }  # Correct;
       7  }
       8  obj = Klass::StaticMethod()