// file: IMyConsts.java

/* ************************************************************
 *
 * Copyright (c) 1997 :
 * Ir. Marc W.F. Meurrens (A.Ir.Br.), Brussels,
 * Computer Graphics & Scientific Applications, scrl, Brussels
 *  marc.meurrens@acm.org
 *  http://homepages.ulb.ac.be/~meurrens
 *
 * This code was created and is used for academic and scientific purposes.
 * See  http://www.ulb.ac.be/esp/ip-Links/Java/joodcs
 * or  http://www.ulb.ac.be/esp/ip-Links/Java/joodcs/Meurrens.html
 * (this last page may be temporarily closed).
 * You may not use this code in commercial applications without prior author's agreement.
 * You may copy and use this code for personal or non-commercial purposes
 * but you may not remove this comment.
 *
 * Revisions:
 *
 * 10-10-97 class EnumColor: 
 *               shows that the EnumCol data members are normally not needed.
 * 10-09-97 "abstract + final class" problem: 
 *               the comment "(now?)" is added after our discussion with Guy Steele.
 * 09-20-97 MM: revisited for web publication
 *
 * *************************************************************
 *
 * This file demonstrates the use of static constants in interfaces.
 * Contrary to a common misunderstanding, constants of a non primitive type
 * are possible.
 * This file demonstrates compile time & run time constants
 * and shows when the run time constants are effectively initialized.
 *
 * Additionaly, this file demonstrates the need of 3 Java missing features
 * and how to bypass these missing features:
 *
 * - the lack of C++ enum like values
 * - the impossibility to declare a class simultaneously abstract and final
 * - the lack of a static initializer block in interfaces
 *
 ******************************************************************* */

import java.lang.Math ;
import java.lang.Double ;
import java.util.Vector ;

public interface IMyConsts
{
  // 1. compile time constants

            public static final int AGE = 7 ;
            public static final double PI2 = 2 * Math.PI ;
            public static final String COPYRIGHT = "(c) My Company" ;

  // 2. run time constants

            public static final String STR_PI = Double.toString( Math.PI ) ;
            public static final Vector VVV = new Vector(16, 8) ;

  // 3. public const of a nested type
  //    bypass the missing C++ enum like feature in Java

            public static final EnumCol GREEN = new EnumCol() ;
            public static final EnumCol RED = new EnumCol() ;
            public static final EnumCol ORANGE = new EnumCol() ;

  // 4. public array const

            public static final int[] SIZES = new int[20] ;
            public static final double[][] ARRAY = new double[3][4] ;
            public static final double[][] MATRIX = { {1,0,0} , {0,1,0} , {0,0,1} } ;

  // 5. bypass missing static initializer in interface
  //    (static initializer exists in classes, but NOT in interfaces)

            public static final Vector VCT = StaticInit.queryVCT() ;
            public static final double[] SERIE = StaticInit.querySERIE(AGE) ;

  // 6. nested class used to generate C++ enum-like constants
  //    bypass the missing C++ enum like feature in Java

            public static final class EnumCol
            {
                private static int g = 0 ;
                public  final  int i ;
                private EnumCol() 
                { 
                   i=g++;
                   System.out.println("DEMO      = ENTER EnumCol " + i ) ;
                }
            } // end nested class EnumCol

  // 6.BIS in most cases, a class such as EnumColor below is enough 

            public static final class EnumColor { private EnumColor() {} }

  // 7. nested class used to bypass the lack of a "static-initializer" feature

            public static abstract /* final */ class StaticInit
            // unfortunately, a class cannot (now?) be simultaneously declared final & abstract
            {
                private                 StaticInit() {} // see note below 
 
                protected static Vector queryVCT()
                {
                   System.out.println("DEMO      = ENTER queryVCT") ;
                   Vector v = new Vector() ;
                   v.addElement(new String("one")) ;
                   v.addElement(new Double(2)) ;
                   return (v) ;
                }
 
                protected static double[] querySERIE(int i_1_Nbr)
                {
                   System.out.println("DEMO      = ENTER querySERIE " + i_1_Nbr ) ;
                   double[] d_R = new double[i_1_Nbr] ;
                   int j ;
                   for(int i=0; i < i_1_Nbr ; i++)
                   {
                      j=i+1 ;
                      d_R[i] = 1 / (j*j) ;
                   }
                   return (d_R) ;
                }

            } // end nested class StaticInit

 // 8. nested demo class

            public static abstract /* final */ class Sdemo
            // unfortunately, a class cannot (now?) be simultaneously declared final & abstract
            {
                private Sdemo() {} // see note below 

                public static void main (String[] str_1_Args)
                {
                    System.out.println("DEMO      = BEGIN") ;
                    System.out.println("Age       = " + IMyConsts.AGE) ;
                    System.out.println("2 Pi      = " + IMyConsts.PI2) ;
                    System.out.println("Copyright = " + IMyConsts.COPYRIGHT) ;
                    System.out.println("Pi        = " + IMyConsts.STR_PI) ;
                    System.out.println("Orange    = " + IMyConsts.ORANGE.i) ;
                    System.out.println("Sizes     = " + IMyConsts.SIZES.length) ;
                    doIt( IMyConsts.GREEN ) ;
                    System.out.println("Array     = " + IMyConsts.ARRAY.length) ;
                    System.out.println("Matrix    = " + IMyConsts.MATRIX[1][1]) ;
                    System.out.println("Vector    = "
                                 + IMyConsts.VCT.elementAt(0)
                                 + " " + IMyConsts.VCT.elementAt(1)) ;
                    System.out.println("Serie     = " + IMyConsts.SERIE[5]) ;
                    System.out.println("DEMO      = END") ;
                }
 
                static void doIt(IMyConsts.EnumCol enu_1_Trafic)
                // bypass the missing C++ enum like feature in Java
                {
                    if(enu_1_Trafic == IMyConsts.RED)
                    {
                       System.out.println("DEMO      = STOP") ;
                    }
                    else
                    {
                       System.out.println("DEMO      = DRIVE CAREFULLY") ;
                    }
                }

            } // end nested class Sdemo

/*
 * NOTE: abstract final class, unique private CT
 *
 * We avoid instanciation by declaring the class as *abstract*,
 * (To declare a class as *abstract*, there is no need for abstract methods).
 * To avoid derivation, we would like to also declare the class as *final*.
 * Unfortunately, we may not (now?) declare a class simultaneously final & abtract.
 * We make the unique CT *private* to obtain the expected result.
 *

 */

} // end interface IMyConsts

/* OUTPUT

 > java IMyConsts$Sdemo

DEMO      = BEGIN
Age       = 7
2 Pi      = 6.283185307179586
Copyright = (c) My Company
DEMO      = ENTER EnumCol 0
DEMO      = ENTER EnumCol 1
DEMO      = ENTER EnumCol 2
DEMO      = ENTER queryVCT
DEMO      = ENTER querySERIE 7
Pi        = 3.141592653589793
Orange    = 2
Sizes     = 20
DEMO      = DRIVE CAREFULLY
Array     = 3
Matrix    = 1.0
Vector    = one 2.0
Serie     = 0.0
DEMO      = END

*/

// eof: IMyConsts.java