Class Members          Peter Komisar ©  Conestoga College  latest version 4.5  2004 


Practical Aspects of Object Oriented Programming



In object-oriented programming, data and operations are formally coupled in the
data structure called the class. The class acts as a container for it's members. Class
members include fields, which are also called variables. Variables hold values
that describe characteristics or properties of an object. The class member that
describes behavior is the method. Methods have counterparts in other languages
known as functions, procedures, routines or operations. Methods are the verbs or
action parts of a class. Java classes also hold constructors. These are special methods
whose sole job is to create what are called new instances or objects of a given class. 

In this study we wish to cover some of the aspects regarding constructors that tie into
inheritance that were not covered in the earlier note and the previous Java course.


Constructors & Overloading



Invoking a Constructor 

A constructor is a unique and privileged method which is used to create and initialize
new objects. Creating a class instance using the constructor with the new operator
is called instantiation. In the following example, declaration, instantiation and assignment
are all combined.

Example    AClass  reference = new AClass( );    // a constructor being invoked 

The above example shows a constructor being deployed in the instantiation process.

Defining a Constructor

When defining a constructor in a class definition the constructor has three distinguishing
elements.

   1) The constructor shares the same name as the class
   2) It is defined with no explicit return type.
   3) Like methods it's identifier is followed by a pair of closed round braces.

The implied return type of the constructor is the class object that is set up in memory.
Constructors are like methods in the the use of round braces to receive arguments
and the use of curly braces to define the scope of their actions. Following is the
general form of the constructor.
 

General form of a constructor as it would appear in a class definition

class  ClassName{
         ClassName( ){
             // the constructor with same name as class, no return type and round braces
            }
     } 

First consider a class called Car defined without any constructors defined.

 Example

class Car{
          // variables   
         int speed = 7;
         int braking = 7;
         int handling = 7;

         // method
         int getRating( ) { return speed + braking + handling; }
       }


Now lets look at a Car class and define a constructor in it. First notice the constructor
has the same name as the class, Car, and has no return type, unlike it's sibling, the
method.

   class Car{
 
       // variables defined in class scope initialized to the default value 0
         int speed;
         int braking;
         int handling;

          //   an no-args constructor
 Car( ){
           speed =7;
           braking= 7;
           handling = 7;
          }

           // class method
           int getRating( ) { return speed + braking + handling; }
       }


The no-args default constructor

You might be wondering what did this accomplish? We saw this class in a simpler
form and would find if we tested it that it would work the same without the constructor.
What really happened, in the absence of us overtly supplying a constructor, was that
a 'no-argument' default constructor was supplied for us by the java environment.
This supplied constructor did the work of initialization just as our explicitly defined
constructor worked.

// in the absence of an overtly supplied constructor the default no-args constructor is supplied


The Issue of Constructor Non-Participation In Inheritance

Inheritance allows a class to extend another class in such a way as to have access
to the resources of the parent class.  We are able to assign values to the parent
variables as if they had been defined in the child class. 

Constructors are not really considered to be class members though they are ostensibly
defined within the class definition. This follows from the fact that they are used to
create class objects rather than being a participating member of it. 

There is a special case that pertains to this discussion. If you define a class with
a constructor that takes arguments then the compiler doesn't bother supplying
the no-args default constructor for you. Now if a child class is built that attempts
to invoke the no-args constructor of the parent the compile will fail as that
version of the constructor in the parent is not defined. The solution here is to
provide a no-args constructor overtly whenever you decide to define constructors
for a class. This is shown in the next example.

// The no-args constructor is supplied automatically only if other constructors are not explicitly defined in a class.  


Constructor Overloading

You might noticed from tours of the documentation that more than one constructor
can be supplied for a class. In the following example we can build the Car class with
three constructors. We are defining the class without variables and methods to simplify
the view.

 Example   class Car{
                       Car( ) { // the no args constructor supplied explicitly
                                  }
                       Car(String options){
                                   // a constructor defined taking a String argument
                                  }
                      Car(String options, String customization){
                                   // a constructor defined taking two string arguments
                                 }

The compiler doesn't mind several constructors being built with the same name.
This is called constructor overloading. This is similar to method overloading where
the compiler is able to distinguish each constructor based on the order, type and
number of arguments. 




Using 'this' & 'super' in Constructors



Recall that the keyword 'this' could be used to reference variables
or method defined
in the scope of a container
class, that is, the class that contains those variables
and methods. The 'this' keyword
also has a special form that is used to reference
constructors defined inside a class.

 In the case of constructors, the 'this' keyword is used as an identifier together with
the form of the
constructor that it is being used to invoke. For instance the following
example shows
how to invoke a constructor in the current class that has an argument
list consisting of a String, and an int value.
  (Another way of to say this is that the form
matches a constructor defined in the current class
with a matching constructor signature.)


Example
  this( "x", 9 );

//  invokes a constructor in the current class that takes a String value and  an int


This is easier to show in code. Following is a complete example

Example    class Limo{
                       Limo(String stretch, int spec1, int spec2, int spec3){
                              // some complex processing
                             }
              Limo(String tinted, String stretch ){
                             this(stretch , 1,2,3);
                             // calls the adjacent constructor with matching argument list
                             // then do further construction, using tinted directive
                            }
                      }

Where the 'this' keyword used with constructors references constructors defined in
the containing class, the 'super' keyword can be used in constructors to reference
a target constructor defined in a parent class.

The super keyword is used in a similar way that the 'this' keyword, in a form that imitates
a constructor that needs to be invoked. The difference is the 'super' keyword is used to
invoke a matching constructor in the parent class. (This is where the trouble comes in that
we spoke of earlier, in that a no-args constructor may be invoked that is defined.) 

To example this we need to create a constructor where a child class subclasses a parent.
First we define Car class with two constructors.


Example

      class Car{
                  Car(String options){
                        // build car with standard options
                       }
                  Car(String options, String customization){
                        // build car with custom options
                       }
              // potential problem as the no-args constructor is not defined
                   }


Now we create a SportsCar class that extends the parent class, Car. Notice how
we use super to specifically invoke one of the parent constructors by matching the
argument lists.

        class SportsCar extends Car{
         SportsCar(String options ){
                        super(options);
                                // passes control to the parent constructor with matching signature
                        }
                 }

Notice now if we tried to use the no-args super( ) we would get a compiler error
because now that constructors have been defined in the Car class the no-args
constructor has not been supplied.

/* You might want to test this right now! Cut and paste the two classes and compile. (It won't
*  run
because there is no main method.) Then add a no-args version of super and try to compile.
 *  Observe the results. Rectify by adding the no-args constructor to the parent.)
*/

A final point on 'this' and 'super'. If the constructor form of these keywords are used
each must be the first statement in the constructor code block. This leads to the obvious,
conundrum, 'In a constructor that uses both, how can they both be first?  Both insist on
being the first call in a constructor. To use both, one must use the form shown in the
last example where one constructor calls 'super' and then the second constructor calls
'this'.

A last word about Java constructors, if this was a C++ course we would go onto a
discussion of destructors,
the counterpart of a  constructor. Java saves us the need
for destructors by taking care
of all the memory deallocation chores via the gc thread
or garbage collector.
 

// Both this( ) and super( ), used in their constructor forms, insist on being the first statement in a constructor.   

Following is another complete example showing super and this used inside constructors


Second Constructor Example

class Old{
      Old( ){
      System.out.println("No-args Old");
      }
      Old(String name){
      System.out.println("Hi " + name + "! I am Old's one arg constructor being invoked.");
      }
      }

class Young extends Old{
      Young(String name){
      super(name);
      System.out.println("Young having called String constructor of Old");
      }
      Young(String name, String day, String month){
      this(name);
      System.out.println("Young calls 'this' and adds it's own properties");
      System.out.println(" Day is: " + day + " and " + " Month is: " + month + "\n"); 
      }
      }

public class OY{
      public static void main(String[] args){

      System.out.println( " \n**** No arg Old ****\n " );
      new Old();

      System.out.println( " \n**** Single arg Young ****\n " );
      new Young("Bentley");

      System.out.println( " \n**** One arg Old ****\n " );
      new Old("Syvester");

      System.out.println( " \n**** Three args Young ****\n " );
      new Young("Melissa","Thursday","April");

      }
     
    }

Output

 **** No arg Old ****

 
No-args Old
 
**** Single arg Young ****
 
Hi Bentley! I am Old's one arg constructor being invoked.
Young having called String constructor of Old
 
**** One arg Old ****
 
Hi Syvester! I am Old's one arg constructor being invoked.
 
**** Three args Young ****
 
Hi Melissa! I am Old's one arg constructor being invoked.
Young having called String constructor of Old
Young calls 'this' and adds it's own properties
 Day is: Thursday and  Month is: Apri
l



Events in Constructor Invocation

The following table shows the specific order of activities followed during the construction process.

 

Events in Constructor Invocation 



 1) memory for the object is allocated
  2) before object allocation, memory is cleared and fields assume default settings
  3) the constructors are allowed to run, referencing other constructors, if called, via 
   'this' or 'super'
  4) if super is not called explicitly, the compiler inserts a call to super which calls 
    back recursively up through the class hierarchy until Object class is reached.
  5) Data fields with explicit initializers are executed. (for constructor-less 
   anonymous classes)
  6) The remaining constructor statements are executed.
.



The following code sample demonstrates the invocation of parent and grandparent constructors.

Sample Demonstrating Invocation of Ancestor Constructors

class Dark{
    Dark(){
    System.out.println("1. Dark");
    }

 public static void main(String[] args){
    new Dark();
    new Dawn();
    new Day();
   
    }
 }

class Dawn extends Dark{
  Dawn(){
     System.out.println("2. Dawn");
     }
   }

class Day extends Dawn{
    Day(){
     System.out.println("3. Day");
     }
  }


Output

1. Dark
1. Dark
2. Dawn
1. Dark
2. Dawn
3. Day

The redundancy in the output demonstrates how parent constructors are invoked recursively.

 


Classes of the java.lang Package



The java library of classes is enormous and growing! Incidently this note itself seems
large. This is
mainly due to the inclusion of tables that summarize the methods of the
classes we are
studying. The classes of the java.lang package do basic 'bread and butter'
activities. The functions these classes provide are so fundamental that they are
supplied
without the need to import the java.lang package.  Major players in this package are 
the
String class and  the Math class. There is also the set of wrapper classes, one for

each primitive type. There are other neccessary classes like System, class Class and
ClassLoader. Object class is defined in the lang package as is the Thread class. Java's
SecurityManager is also defined in the lang package. The lang package is also where
two dozen exception classes and twenty-one error classes are defined.  In this section
we look at the String, Math and wrapper classes.

Though in a different package, the util package, Vector is included too, because it has been
used so much throughout the java libraries.
Though Vector is often replaced by by classes
such as ArrayList contained in the collection package, it remains a classic Java workhorse.

// ArrayList adds some nice features however ArrayLists operations are not synchronized
// as are Vector's methods. In a multi-threaded environment, you would need to make sure
// calls on ArrayList are synchronized.



The String Class



In Java when you need a string of characters in your programs, you use an instance of the
String class. (We look at String class a little closer later in the course.) String objects hold
a series of adjacent characters in a way similar to an array. However, where with an array
you would reference an element of the array to get a character, with String you use one of
the class methods to manipulate the string.

String literals

A String literal is created when zero or more characters are enclosed in double quotes.


Example 
"A String literal"     // String literal


String literals are normally used in some context. For instance as an argument to a method.


Example
   setText(" String literal as a method argument " );


String literals are also used in assignments.


Example
   String string =  " A String literal assigned to a String reference variable. ";


String is a class so an object of String class can be created using a String class constructor.


Example
String s = new String("A string" );
 

Strings as Immutable Objects

Strings are said to be immutable. This means a String object is unchangeable. This
description can be misleading. It makes it sound as though a String object is somehow
final like a variable that has been marked final and can no longer be changed. What is
unchangeable is the String object that has been stored in memory. So how do we make
changes to a a String object? What actually occurs when java methods are used to change
a String object is that the string is copied into an instance of the mutable StringBuffer class.
The changes are made to this representation and then a new immutable String object is
built. The old reference is then made to point to the new object while the old dereferenced
object is discarded. Once no longer referenced, it is just a matter of time before the
background thread called the garbage collector deallocates the memory associated with
the old immutable String object.

//  When a change on a string is executed the string is written to a StringBuffer the
//  modifications are effected and then a new immutable String object is created.
// The reference to the string object is made to point to the new string and the old

// one is discarded.

 

The Overloaded Addition Operator

There is one case of operator overloading in Java. The addition operator, represented
by the '+' symbol, is overloaded to do String concatenation.  (Overloading in this context
is when a symbol is able to do more than one kind of operation in a language.) If one of the
operands to the operator, + is a String object, the other type will either be promoted to String
type (as in the case of primitives) or the toString( ) method will be called on it (in the case
of object types.) In the following case each primitive value represented by x and y will be
supplied in their String form.

Example       System.out.println(" x is " + x + "y is " + y );
 


Common String class Construction

Following are two common constructions of a String object. The first uses a constructor
while the second is a String literal assignment.

Example1 String s1 = new String( "common constructor");      // via  a  constructor

Example 2    String s2 = "a string literal";                      // assigning a string literal

There are several String constructors ( 9 ) and String objects can be created in a number
of ways. The following example shows a Sting object constructed from an array of char
type.

Example

String ball = "balloon";    // is equivalent to:

char parts[] = {'b', 'a', 'l','l','o','o','n'};
String ball2 = new String(parts);


Deep and Shallow Comparisons



When reference types are compared via the equality operator, ==, the addresses stored in
the references are compared. This is called a shallow comparison. If the equals( ) method
is used, the contents pointed to by the address stored in the reference is compared. This
is a deep comparison. The following two cases cover the different unique circumstances
that may occur and are easily extrapolated to other variations. 

Comparisons of Same Addresses and Same Stored Values

To complicate matters, the java environment maintains a pool of string literals. Each string
literal is represented
in the pool. Identical string literals are only represented once in the pool.
If an identical literal
is used twice in a program, it is only represented once in the literal pool.
When deep and
shallow comparison are made on the two references representing the same
string literal value
the result is that consistent with the idea that the reference both refer to the
same stored value and
simultaneously, the references also point to the same address.

Example 1

String xx = "X";
String xy = "X";

if (xx.equals(xy))         // a 'deep' comparison ( of values stored ) resolves to true

// . . .

if (xx = = xy)      // a second 'shallow' comparison between the same references also resolves to true

The second "shallow" comparison also resolves to true as the addresses where the string literal,
"X" is stored, is the same location.


Comparisons of  Different Addresses but Same Values

On the other hand, when a reference is created via the constructor housing a literal, first the
literal is recorded in the literal pool and then a new string is created, copied from the one in
the literal pool. This copy is stored at a different location so will not share the same address
as the one in the literal pool.

Example 2

String yy = "X";
String yx = new String("X");
if (yy.equals(yx))                 // a 'deep' comparison (of stored values) resolves to true
    // however
if (yy = = yx)                       // will resolve to false
 


Code Sample Demonstating Deep and Shallow Comparison

class sTz{
public static void main(String[]args){

  // First Scenario

  String xx = "X";
  String xy = "X";
   if (xx.equals(xy))
     System.out.println
     ("\n"+"A deep comparison tests true for comparison on literal assignmnents");
  if (xx == xy)
     System.out.println
     ("A shallow test yields true indicating one value is stored at one address \n");

   // Second Scenario

  String yy = "X";
  String yx = new String("X");

    if (yy.equals(yx))
       System.out.println
       ("Values are the same when assigned by literal or by literal-supplied constructor");
    if (yy == yx)
    ;
    else
    System.out.println
   ("Shallow tests false showing the two values are stored at different addresses");
    }
  }


String Class Documentation    //    documentation for reference   



Constructor Summary

Here are 9 String constructors that show String instances can be created from an
empty character sequence, a provided String object (where in fact a copy is created
and encapsulated in the new instance), a  StringBuffer instance, and arrays. (or parts
of arrays), of byte and char type, with or without specified character encodings.

 
 

 String( ) 

 Initializes a newly created String object so that it represents
 an empty character sequence.

 String(byte[] bytes) 

 Construct a new String by converting the specified array 
 of bytes using the platform's default character encoding.

 String(byte[] bytes, 
 int offset,  int length) 

 Construct a new String by converting the specified subarray 
 of bytes using the platform's default character encoding.

 String(byte[] bytes, int offset,
 int length, String enc) 

 Construct a new String by converting the specified subarray
 of bytes using the specified character encoding.

 String(byte[] bytes,
 String enc) 

 Construct a new String by converting the specified array 
 of bytes using the specified character encoding.

 String(char[] value) 

 Allocates a new String so that it represents the sequence of 
 characters currently contained in the character array argument.

 String(char[] value,
 int offset, int count) 

 Allocates a new String that contains characters from a
 subarray of the character array argument.

 String(String value) 

 Initializes a newly created String object that is a copy of 
 the argument  string.

 String(StringBuffer buffer) 

 Allocates a new string that contains the sequence of 
 characters currently contained in the string buffer argument.

   //  constructors deprecated because they didn't work properly are left out

 
Method Summary
   // the short summary from the JDK API documentation
 

 char charAt(int index) 

 Returns the character at the specified index. //An index ranges from 0  to length() - 1. // The first character of the sequence is at index 0

 int compareTo(Object o) 

 Compares this String to another Object.

 int compareTo(String StringB ) 

 Compares two strings lexicographically. // returns a negative int if string is less than argument, 0 if the same, and a positive int if greater than See API for details 

 int compareToIgnoreCase
 (String str)

Compares two strings lexicographically, ignoring case considerations.

String concat(String str)

 Concatenates the specified string to the end of this string.

 static String copyValueOf
 (char[] data)

 Returns a String that is equivalent to the specified character array.

static String copyValueOf
(char[] data, int offset, int count)

Returns a String that is equivalent to the specified character array.

boolean endsWith(String suffix)

Tests if this string ends with the specified suffix.

boolean equals(Object anObject)

 Compares this string to the specified object.

boolean equalsIgnoreCase
(String anotherString)

 Compares this String to another String, ignoring case considerations.

byte[] getBytes( )

 Convert this String into bytes according to the platform's default  character encoding, storing the result into a new byte array.

byte[] getBytes(String enc)

Convert this String into bytes according to the specified character
encoding, storing the result into a new byte array.

 void getChars(int srcBegin,  int
 srcEnd, char[] dst, int dstBegin)

Copies characters from this string into the destination character array.

 int hashCode( )

Returns a hashcode for this string.

 int indexOf(int ch)

Returns the index within this string of the first occurrence of the specified character.

 int indexOf(int ch, int fromIndex)

Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index.

 int indexOf(String str)

 Returns the index within this string of the first occurrence of the specified substring.

 int indexOf
 (String str, int fromIndex)

Returns the index within this string of the first occurrence of the specified substring, starting at the specified index.

 String intern( )

Returns a canonical representation for the string object.

 int lastIndexOf(int ch)

Returns the index within this string of the last occurrence of the specified character.

 int lastIndexOf
 (int ch, int fromIndex)

Returns the index within this string of the last occurrence of the specified character, searching backward starting at the specified index.

 int lastIndexOf(String str)

Returns the index within this string of the rightmost occurrence of the specified substring.

 int lastIndexOf
 (String str, int fromIndex)

 Returns the index within this string of the last occurrence of the specified substring.

 int length( )

Returns the length of this string.

 boolean regionMatches (boolean 
 ignoreCase, int toffset, String other,
 int ooffset, int len)

Tests if two string regions are equal.

boolean regionMatches(int toffset,
String other, int ooffset, int len)

Tests if two string regions are equal.

 String  replace
 (char oldChar, char newChar)

Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.

boolean startsWith(String prefix)

Tests if this string starts with the specified prefix.

 boolean startsWith
 (String prefix, int toffset)

Tests if this string starts with the specified prefix beginning a specified index.

 String substring(int beginIndex)

Returns a new string that is a substring of this string.

 String substring
 (int beginIndex, int endIndex)

 Returns a new string that is a substring of this string.

 char[] toCharArray()

Converts this string to a new character array.

 String toLowerCase( )

 Converts all of the characters in this String to lower case using the rules of the default locale, which is returned by Locale.getDefault.

 String toLowerCase
 (Locale locale)

 Converts all of the characters in this String to lower case using the rules of the given Locale.

 String toString()

This object (which is already a string!) is itself returned.

 String toUpperCase()

Converts all of the characters in this String to upper case using the rules of the default locale, which is returned by Locale.getDefault.

 String toUpperCase(Locale locale)

Converts all of the characters in this String to upper case using the rules of the given locale.

 String trim()

Removes white space from both ends of this string.

 static String valueOf(boolean b)

 Returns the string representation of the boolean argument.

 static String valueOf(char c)

Returns the string representation of the char argument.

 static String valueOf(char[] data)

Returns the string representation of the char array argument.

 static String valueOf
 (char[] data, int offset, int count)

Returns the string representation of a specific subarray of the char array argument.

 static String valueOf(double d)

Returns the string representation of the double argument.

 static String valueOf(float f)

Returns the string representation of the float argument.

 static String valueOf(int i)

Returns the string representation of the int argument.

 static String valueOf(long l)

Returns the string representation of the long argument.

 static String valueOf(Object obj)

Returns the string representation of the Object argument.


String Class Code Example

The following code example shows that the methods of the String class are
pretty straight forward to use.
 

import java.io.*;

class StringT{
public static void main(String[] args){

  char[] sa = {'S', 't', 'r', 'i', 'n','g'};
  String string = new String(sa);                              // one of String's constructors
  System.out.println("\n 1. string has the value " +string );

  String sb = "string";
  int i = string.compareTo(sb);                                                         // compareTo( )
  System.out.println(" 2. The lexigraphical comparison yields " + i );

  String cat=string.concat(sb);                                                          // concat( );
  System.out.println(" 3. sb concatenated to string is " + cat + "\n");

try{
  byte[] b= new byte[string.length( )];
  System.out.println(" 4. string length is " +string.length( )+"\n");
  for(int k=0;k<b.length;k++){
      b = string.getBytes("8859_1"); //  getBytes("8859_1") with character encoding
      System.out.println(b[k]);
      }
    }
    catch(UnsupportedEncodingException uee){  // have to catch unsupported encoding
    System.out.println("Unsupported Encoding");
    }

int j = string.indexOf("St");                                                                          // indexOf( )
System.out.println("\n 5. The first occurence of ring is at index " + j );
                         // This reports index 0 so think of the index like an offset starting at zero
int z = (int)'T';                                                               // casting a char type to an int
System.out.println(" 6. The char literal T cast to an int is "+ z);

System.out.println(" 7. before and after trim() \n");                                             // trim( )
System.out.println("    before length: " + "   xyz   ".length());  // calling on string literals
System.out.println("    after length: " + "   xyz   ".trim().length());
String string2=string.valueOf(sa);                                       // valueOf used on a char array
System.out.println("\n 8. This is sa array returned as a string " + string2);
 }
}


Wrapper Classes



Sometime you will need to treat a primitive type, ( i.e. int ), as an object. As an
example, a primitive type cannot be added directly to a Vector however often
a number would need to be added to a Vector. Vector can only receive object
types. Wrapper classes encapsulate primitive types in class objects so they can
be treated like object types. For instance, Integer is the wrapper class for integers.
A wrapper class exists for each of the primitive types.

The Wrapper class name for each primitive can be deduced by starting the
unabbreviated version of the primitive type name with capitals. For example, int
type's wrapper class is the Integer class, while the char type's wrapper is the
Character class. All the primitives and their corresponding wrapper classes are
listed in the following table.
 

 Wrapper Class for each Primitive Type
 

 Wrapper 

 Primitive

 Boolean

 boolean

 Character

 char

 Byte

 byte

 Short

 short

 Integer

 int

 Long

 long

 Float

 float

 Double

 double


Besides providing objects types for primitives, wrapper classes store useful constants
and methods to convert to and from String and other types. In the following example
one of the important roles wrapper classes serve is shown.  The Integer wrapper class
static parseInt( ) method converts a String value to an int value. A wrapper class is
built on the int by passing it into the Integer class constructor. As an example of the
convenience method that the wrappers offer, the int value is returned as a double
by the Integer object's floatValue( ) method. Notice we don't have to catch the
runtime NumberFormatException but nothing stops us from doing that.

Wrapper Classes Like String Class Represent Immutable Values

Another important point about the wrapper classes, they are like the String
class and represent immutable values.  There is a similarity between the wrapper
classes and the the String class in that the String class represents a wrapper for
a collection of primitive 'char' type and the wrapper classes serve as containers
for the other numerical primitive types.

 

Wrapper Class Code Example

                                                                       */

 * parseInt() is a static method called here on the class  * name  */

class Wrap{
public static void main(String[] args){
if(args.length < 1){
System.out.println("Enter a number at the command line");
System.exit(0);
}
try{
int i=Integer.parseInt(args[0]);
Integer theWrapperClass= new Integer(i);
float f = theWrapperClass.floatValue( );
// intValue( ) returns enclosed wrappers int value
System.out.println("Here's your number as a float: " + f);
}
catch(NumberFormatException nfe){
System.out.println("Your number is too big or has a format problem");
System.exit(0);
 }
}
}
 
//  The number output converts to exponential floating point form at 10 million.
  //  A
NumberFormatException is thrown when the range of an int is exceeded,
  //   ~  +/-  2.147 billion.
                


The Math Class         // for reference, won't be on final exam 



Math contains a collection of math methods and two constants. The constants are

Math.PI and Math.E. Both are public, static, final and double. The Math class
itself is made final so cannot be sub-classed.  It's constructor is private so it cannot
be
instantiated. It's methods and constants are static so can be accessed through the
class name. The result of this rigid definition, aside from tight control and security,
is that Math class is accessed through simple, static calls.

Example   Math.random( );


A Brief look at Math class Methods.


abs( )

There are four versions of abs( ), each which returns an absolute value for a value
provided which may be int, long, float, or double.  // resolves a -2 to a 2


ceil( )
& floor( )

These methods take and return doubles corresponding to the nearest int value above
or below the double provided  // ceil( ) will resolve a 1.1 to a 2 


max( )
& min( )

There are four versions of each max( ) and min( ) for int, long, float and double types.
These methods take two values and return the greater or the lesser of two, respectively.


random( )

random( ) returns a random number between 0.0 and just less than 1.0. This method
acts as a wrapper for the creation of an instance of the Random class which is one of
the utility methods supplied in the java.util package.

//  Random # formula:  random number =  (int) ( Math.random( ) * number_range) + 1


round( )

Two forms of this method are available to round a float (to an int) or a double (to a long)


sin( ), cos( )
& tan( )  
     // there are also asin acos atan & atan2
These methods take doubles and return the sine, cosine, and tangent as doubles.


sqrt(
double d )

sqrt( ) returns the square root of a double provided as an argument


pow(
double number, double power)

pow( ) returns a number evaluated to a given power


log( )

Returns the natural logarithm (base e) of a double value.


exp( )

Returns the exponential number e (i.e., 2.718...) raised to the power of a double value.


rint( )

takes a double, rounds to an int then returns this value as a double


IEEEremainder(double f1, double f2 )

returns an IEEE formulated remainder of a division

// supplemental information The remainder value is mathematically equal to f1 - f2 × n, where n
is the mathematical integer closest to the exact mathematical value of the quotient f1/f2, and if
two mathematical integers are equally close to f1/f2, then n is the integer that is even.)


toDegrees( )
// new since  JDK1.2
Converts an angle measured in radians to the equivalent angle measured in degrees.


toRadians( )
// new since  JDK1.2
Converts an angle measured in degrees to the equivalent angle measured in radians.

/* not catching number format exception (Try entering something like 5y5) */
 

Math Code Example

   class mathMethods{
      public static void main(String[] args){
         if(args.length <6){
             System.out.println("Enter 6 numbers at the command line");
             System.exit(0);
             }
      int a=Integer.parseInt(args[0]);
      int b=Integer.parseInt(args[1]);
      int c=Integer.parseInt(args[2]);
      int d=Integer.parseInt(args[3]);
      int e=Integer.parseInt(args[4]);
       int f=Integer.parseInt(args[5]);
      double t;
      int[] intArray=new int[]{a,b,c,d,e,f};

          for ( int i=0; i < intArray.length - 1; i++ ){
              int z=Math.min(intArray[i],intArray[i+1] );
              intArray[i+1]=z;
              }
      int small=intArray[intArray.length-1];
      System.out.println("The smallest number in this set is "+small);
      System.out.println
      (" The square root of this number is " + Math.sqrt(small ) +
      "\n which when rounded is " +Math.round( Math.sqrt(small) )  );
      }
   }
 


The Vector Class



One of the principle drawbacks of using arrays is they need to be fixed in length. They
don't lend themselves to dynamically changing size. A Vector is a Java class that acts
as a container similar to an array but one which can grow or shrink in size to allow objects
to be added or removed after the Vector has been created. While arrays are a built-in
feature of the Java language the Vector class is a regular Java library class and will
be referenced via the java.util package. Unlike arrays, which can be specified for any
type defined in Java (primitives, arrays, and Object types ), Vectors store one generic
type, that of Object. It is easy to add an item to a Vector but to get it back it has to be
cast to the appropriate type.

Vector, unlike the String, Math and the wrapper classes are not in the java.lang package.
To use the Vector class the java.util package needs to be imported or Vector's fully
qualified name needs to be used, java.util.Vector. Following is the class signature of
the Vector class and it's hierarchy.
 

Vector Class Signature

 public class Vector extends AbstractList implements List, Cloneable, Serializable

Vector Class Hierarchy

 java.lang.Object
   |
  +--java.util.AbstractCollection
         |
        +--java.util.AbstractList
               |
              +--java.util.Vector

 // the inheritance tree shows Vector is a type of List and also implements the List interface
// A list is an ordered collection (also known generically as a sequence).
 

A Vector is created via one of it's a 4 constructors. Vector has an empty constructor
and a constructor that takes a Collection object. It also has a constructor allowing
setting the initial capacity of the Vector, and a fourth constructor allows specifying
the initial capacity and the capacity increment. The capacity increment decides the
size that the vector will grow by and is automatically set to the size of the vector.

Vector implements the methods of the List interface plus about 15 other methods for
a total of about 40 methods. This shows you that Vector has quite a bit of  versatility
absent in the array.

Vector v=new Vector( 5 );  // this is a Vector with it's size set to 5.

You can use add( ) and addElement( ) methods to add items to the Vector and
remove( ) or removeElement( ) methods to remove items. Primitive types need to
be 'wrapped' in appropriate wrapper classes to be stored in a Vector. The
elements( ) method will return an Enumeration object which you can iterate with
Enumeration's hasMoreElements( ) and nextElement( ) methods. elementAt( )
returns a component at a specified index. It is interesting to note that the Vector
object will allow more items to be added than was declared to the constructor
as the initial capacity. But if an access is attempted beyond what has been added
( as in v.element(7) ) then the runtime exception ArrayOutOfBoundsException
is thrown. This indicates that an Object array is being used within the Vector
class. This array is copied to a bigger array when the stated capacity of the
Vector is exceeded.

// The fact an ArrayOutofBoundsException may be thrown telegraphs that
// Vector is a wrapper for an array accessorized with 'growable' algorithms


Vector Code Sample

import java.util.*;

class VectorTest{
public static void main(String[]args){
  Vector v=new Vector(3);
  Integer i1=new Integer(1);
  Integer i2=new Integer(2);
  Integer i3=new Integer(3);
  Integer i4=new Integer(4);

  v.add(i1);
  v.add(i2);
  v.add(i3);
  v.add(i4); // not like array. Vector adds past capacity.
  Integer five=(Integer)(v.elementAt(3));
  System.out.println(five.intValue());
  }
}

Constructor Summary      // from the jdk documentation
 

Vector( ) 

 Constructs an empty vector so that its internal data array 
 has size 10 and its standard capacity increment is zero.

Vector
(Collection c) 

 Constructs a vector containing the elements of the 
 specified collection, in the order they are returned by
 the collection's iterator.

 Vector
(int initialCapacity)

 Constructs an empty vector with the specified initial
 capacity and with its capacity increment equal to zero.

 Vector(int initialCapacity,
   int capacityIncrement)

Constructs an empty vector with the specified initial
 capacity and capacity  increment. 

Method List
 

 void  add (int index, 
        Object element)

 Inserts the specified element at the specified position 
 in this Vector.

 boolean add(Object o)

 Appends the specified element to the end of this Vector.

 boolean addAll
 (Collection c)

 Appends all of the elements in the specified Collection
 to the end of this Vector, in the order that they are 
 returned by the specified Collection's Iterator.

 boolean addAll
 (int index, Collection c)

 Inserts all of the elements in in the specified Collection
 into this Vector at the specified position.

 void  addElement 
 (Object obj)

 Adds the specified component to the vector end, 
 increasing its size by one.

int capacity()

 Returns the current capacity of this vector.

void clear ( )

 Removes all of the elements from this Vector.

Object clone( )

 new Returns a clone of this vector.

 boolean contains
 (Object elem)

 Tests if the specified object is a component in 
 this vector.

 boolean containsAll 
 (Collection c) 

 Returns true if this Vector contains all of the 
 elements in the specified Collection.

 void copyInto
 (Object[] anArray)

 Copies the components of this vector into
 the specified array.

Object elementAt(int index)

Returns the component at the specified index.

Enumeration elements()

 Returns an enumeration of the components of 
 this vector.

void ensureCapacity
(int minCapacity)

 Increases the capacity of this vector, if necessary,
 to ensure that it can hold at  least the number of 
 components specified by the minimum capacity 
 argument.

boolean equals(Object o)

 Compares the specified Object with this Vector
 for equality. 

Object firstElement( )

 Returns the first component (the item at index 0) 
 of this vector.

Object get(int index)

 Returns the element at the specified position in 
 this Vector.

int hashCode()

Returns the hash code value for this Vector.

int  indexOf(Object elem)

Searches for the first occurence of the given argument, 
testing for equality using the equals method.

 int  indexOf
 (Object elem, int index)

 Searches for the first occurence of the given argument, 
beginning the search at index, and testing for equality 
 using the equals method.

void  insertElementAt
(Object obj, int index)

 Inserts the specified object as a component in this 
 vector at the specified index.

boolean isEmpty()

 Tests if this vector has no components.

Object lastElement( )

 Returns the last component of the vector.

int lastIndexOf(Object elem)

 Returns the index of the last occurrence of the 
 specified object in this vector.

int lastIndexOf
(Object elem, int index)

 Searches backwards for the specified object, starting
 from the specified index, and returns an index to it.

Object remove(int index)

 Removes the element at the specified position in this 
 Vector.

boolean  remove(Object o)

 Removes the first occurrence of the specified element
 in this Vector If the Vector does not contain the element,
 it is unchanged.

 boolean  removeAll 
 (Collection c) 

 Removes from this Vector all of its elements that are 
 contained in the specified Collection.

 void removeAllElements()

 Removes all components from this vector and 
 sets its size to zero.

 boolean  removeElement
 (Object obj)

 Removes the first (lowest-indexed) occurrence of
 the argument from this vector.

 void removeElementAt
 (int index)

 Deletes the component at the specified index.

protected void removeRange
(int fromIndex, int toIndex)

 Removes from this List all of the elements whose index 
 is between fromIndex, inclusive and toIndex, exclusive.

 boolean retainAll
 (Collection c)

Retains only the elements in this Vector that are
 contained in the specified Collection.

 Object set
 (int index, Object element)

 Replaces the element at the specified position in this 
 Vector with the specified element.

 void setElementAt
 (Object obj, int index)

 Sets the component at the specified index of this 
 vector to be the specified object.

 void setSize(int newSize)

 Sets the size of this vector.

 int size() 

 Returns the number of components in this vector.

 List subList
 (int fromIndex, int toIndex)

 Returns a view of the portion of this List between 
 fromIndex, inclusive, and toIndex, exclusive.

 Object[] toArray()

 Returns an array containing all of the elements in
 this Vector in the correct order.

 Object[] toArray(Object[] a)

 Returns an array containing all of the elements in
 this Vector in the correct order.

 String toString()

 Returns a string representation of this Vector, 
 containing the String representation of each element.

 void trimToSize( )

 Trims the capacity of this vector to be the vector's 
 current size.


Self Test                                                                   Self Test With Answers



1)  Pick the incorrect statement. Constructors are unlike methods in that they have
     a) no return type
     b) are named after the class
     c) use round braces for arguments
     d) cannot be abstract


2) If used inside one of the constructors of a class called Cat which
    of the following would the constructor this( 1.1, 2.2 ) call?

a ) Cat (double x, double y ) { /* */ }
b)  Cat( int j, int k ) { /* */ }
c)  Cat(  ) { /* */ }
d)  Cat  ( float u, int p ) { /* */ }


3) What will the following print out? Select the correct answer.

String x1 = "X";
String x2 = "X";
if (x1.equals(x2))
System.out.println( "Positive")
else
System.out.println("Negative")

a ) Positive
b ) Negative


4) What will the following print out? Select the correct answer.
String x1 = "X";
String x2 = "X";
 

if (x1==x2)
System.out.println( "Positive")
else
System.out.println("Negative")

a )
b)

// Note: Will not have Math questions on final exam as was covered in earlier course

5) One of the following is not a valid wrapper class. Which is it?

a) Float
b) Int
c) Double
d) Long



6)  Which of the following statements is not correct?

a) The math class itself is final so can only be extended once
b) Math's constructor is private so it cannot be instantiated.
c) Math methods and constants are static
d) Math methods are only accessible through the Math class name
 

7) Math.floor(44.4) returns
a) 45
b) 45.0
c) 44
d) 44.0



8) Which of the following is not in the java lang package

a) Vector
b) Boolean
c) Math
d) String

9 ) Which of the following statements is not correct?

a) The number of objects added may exceed the capacity.
b) The no-args Vector constructor defaults to an initial capacity set to 5.
c) To return an element to it's original type typically requires a cast.
d) Vector can throw an exception is an element index is addressed
    higher than the number of elements that have been added to the
    Vector.
 




Exercise




Using Constructors

1 ) Create a parent class with three different constructors. Include one no arg
constructor. The other two constructors will be overloaded and takes different
arguments, distinguished either by type, number or order.

In a child class constructor invoke one of the parent constructors that takes arguments
using the keyword 'super'. Then in the child, use the 'this' keyword in another constructor
to invoke the constructor that has used the super keyword. Add some symbolic accessory
features to the second constructor, even just comments or actions represented  by
System.out.println statements.


Using Lang Classes

2) Create a class that takes a name in at the command line. Use methods of the String
class to convert the name to uppercase and pre- and  postfix the name with exclamation
marks. Then write to the command line the 'dressed' name in conjunction with a statement
something like  "!!! BOB !!! You have won a new car!"


3) Create two wrapper classes that store a height and width of a right angled triangle.
Pass these values in at the command line when the program is invoked. Store these
two classes in a Vector. Access the Vector elements and retrieve the wrapped values.
Figure out the hypotenuse using Math methods and store this value in another wrapper
class. Access the third wrapper class and write the three values in a statement to
screen. (i.e. A triangle with a width of ___ and a height of ____ has a hypontenuse
value of ______ )


// it would be tempting to just store the final value in the Vector but for exercise
// we take the long way around and store the two entered values in the Vector
// before accessing them to compute the hypotenuse.


PS. If you forgot the Pythagorean theorem, it states that the sum of the squares of
of the sides of a right angled triangle is equal to the square of the hypotenuse.

A 2  =    B 2    +  C 2


Optional Approaches    



Using Command Line IO


You can use the String[] supplied by main to enter values to your program. There
are a couple examples of this technique shown in the above note. This functionality
would typically be used to configure your application.  For instance, if your program
was creating a net connection, you could enter a port number other than the default.

 You may wish to use an 'inline' approach based classes in the io package as in the
following partial excerpt. Either way is good to practice. The following code is pretty
primitive. Making it more sophisticated has the disadvantage of making it complex.
It does show a formula for entering values at the command line.


import java.io.*;

class AverageTwoNumbers
{
  
public static void main(String[]args)
   {
   String value = "";
   int sum = 0;
   int average = 0;

   BufferedReader in = new BufferedReader
   (new InputStreamReader(System.in));
 
   System.out.println( " Enter a mark " );
   try{
        value = in.readLine( );
        int holding = 0;
      
        try{
             holding = Integer.parseInt(value);
             sum = sum + holding;
            }
        catch(NumberFormatException ne){
             System.out.println( "Your number was not well formed");
             }
        
   
        System.out.println( "You have entered: " + value);
        System.out.println(" Type in another value ");
   
        value = in.readLine( );

       
         try{
             holding = Integer.parseInt(value);
             sum = sum + holding;
             }      
          catch(NumberFormatException ne){
               System.out.println( "Your number was not well formed. Run again.");
               return;
               }
        
       
        average = sum /2;
        System.out.println("The average of the two numbers is: " + average);
     }
      catch(IOException io){System.out.println("IOException thrown");}

   }
 }    


Using JOptionPane

You can also use the handy JOptionPane to do IO at the keyboard. JOptionPane supplies
a handy lightweight GUI for entering and displaying data. Followng is sample code showing
JOptionPane being used. The Double wrapper class is also used. To add a degree of
robustness, we add exception catching for NumberFormatException.

JOptionPane Sample Code


import javax.swing.*;


public class LightGUI {
public static void main(String[]args){

try{

  double base;
  double height;

  String baseInput = JOptionPane.showInputDialog("What is the length of the base of the triangle?");
  base = Double.parseDouble(baseInput);

  String heightInput = JOptionPane.showInputDialog("And what is the height of the triangle?");
  height = Double.parseDouble(heightInput);

  double areaTriangle =  base * height  / 2 ;

  JOptionPane.showMessageDialog(null, "The area of your triangle is " + areaTriangle);
}
catch(NumberFormatException nfe){
 JOptionPane.showMessageDialog(null, "Your number is too large or incorrectly formatted.");
 }
System.exit(0);
}
}