Chapter 2 - Computer Science Home - William Paterson ...cs.wpunj.edu/~ndjatou/CS382-java.doc · Web...

322
Introduction to Java Programming Language Introduction Java is an imperative-based object-oriented programming language introduced by Sun Microsystems (which is now a subsidiary of Oracle) in 1995. Its syntax is derived from C and C++ but it has a simpler object model and fewer low low-level facilities. It was first created for developing software for embedded consumer electronic, such as toasters, microwave ovens, and interactive TV systems. But today, it is mostly used to develop software for networking, mobile devices, multimedia, games, web-based content and enterprise software. Java applications are typically compiled to an intermediate representation called bytecode that can run (be interpreted) on any Java Virtual Machine (JVM) regardless of computer architecture. In order to speed up the execution of java bytecode, Just-in-Time compilers are provided to translate the bytecode of a method into machine language when it is called for the first time during the execution of the program. You need to install the Java Runtime Environment (JRE) on your computer in order to execute java applications. It consists of the Java Virtual Machine (JVM), the Java core classes, and the supporting Java class libraries also known as the Java APIs (Applications Program Interfaces). You need a Java development environment or an integrated development environment (IDE) in order to create, compile, and execute Java applications. The latest version of the Java development environ provided by Sun © 2011 Gilbert Ndjatou Page 1

Transcript of Chapter 2 - Computer Science Home - William Paterson ...cs.wpunj.edu/~ndjatou/CS382-java.doc · Web...

Chapter 2

Introduction to Java Programming Language

Introduction

Java is an imperative-based object-oriented programming language introduced by Sun Microsystems (which is now a subsidiary of Oracle) in 1995.

Its syntax is derived from C and C++ but it has a simpler object model and fewer low low-level facilities.

It was first created for developing software for embedded consumer electronic, such as toasters, microwave ovens, and interactive TV systems. But today, it is mostly used to develop software for networking, mobile devices, multimedia, games, web-based content and enterprise software.

Java applications are typically compiled to an intermediate representation called bytecode that can run (be interpreted) on any Java Virtual Machine (JVM) regardless of computer architecture.

In order to speed up the execution of java bytecode, Just-in-Time compilers are provided to translate the bytecode of a method into machine language when it is called for the first time during the execution of the program.

You need to install the Java Runtime Environment (JRE) on your computer in order to execute java applications. It consists of the Java Virtual Machine (JVM), the Java core classes, and the supporting Java class libraries also known as the Java APIs (Applications Program Interfaces).

You need a Java development environment or an integrated development environment (IDE) in order to create, compile, and execute Java applications.

The latest version of the Java development environ provided by Sun Microsystems is Java SE Development Kit 8 (JDK8) that can be downloaded from the web site java.sun.com/javase/downloads/.

IDEs provide tools that support the software development process, including editors, and debuggers. Popular IDEs include Eclipse (www.eclipse.org) and Netbeans (www.netbeans.org).

Elements of Java Programming Language

Comments

Comments are the same as in C++.

Examples

/*-- Program to add two integer values --*/

// read the values

Identifiers

A. Rules for writing valid identifiers:

1. In Java, a letter denoted by L is defined as: a to z, A to Z, the underscore character _ or any Unicode character that denotes a letter in a language.

2. A digit denoted by D is defined as 0 to 9 or any Unicode character that denotes a digit in a language.

3. An identifier is defined as:(L | $)(L | D | $)*

4. However, by convention, user-defined identifiers do not start with the dollar sign $ or the underscore _ and the dollar sign $ is never used for user-defined identifiers.

5. C++ conventions for identifiers are also used in Java: use of the underscore character as a connector or start the second word with an uppercase letter. Examples: gross_pay, grossPay.

6. An identifier cannot be a Java Keyword. Java keywords are provided in Appendix 1.

7. Uppercase and lowercase letters are different.

Constant Data

There are six types of constant data in Java:

Boolean constants

character constants,

integer constants,

floating-point constants,

strings constants, and

Special constants

Boolean Constants

Boolean constants are the same as in C++:true and false.

However, 0 is not false and anything else is not true as in C++.

Character Constants

A character constant is either a single printable Unicode character enclosed between single quotes, or an escape sequence enclosed between single quotes.

Examples of printable characters:'A', '$', '8', (space bar), 'z'.

Examples of escape sequences:'\n', '\t',

'\'', '\\', \.

Escape sequences are used to represent characters that you can not type from the keyboard or characters that have a meaning for the compiler such as single quote, double quote, . . ., etc.

Unicode characters that you cannot type from the keyboard may be specified using a Unicode escape sequence in the form: \uXXXXwhere XXXX represents the hexadecimal code of that character.

Examples

\u00EA for

and \u00A5

for

Integer Constants

Integer constants are the same as in C++: positive or negative whole numbers.

An integer constant may be specified in one of the following bases:

Decimal

Example:26

Octal (base 8)

Example:032(the number 26 in octal)

Hexadecimal (base 16)

Example:0x1A(the number 26 in hexadecimal)

Floating-point constants

Floating-point constants are the same as in C++:

They may either be written in decimal notation or exponential notation.

They may be specified with the f or F suffix for the 32-bit value or the d or D suffix for the 64-bit value which is the default.

Examples

123.4

1.234e+2D

123.4f

String constants

A string constant is a sequence of zero or more Unicode characters (including escape sequences) enclosed between double quotes.

Examples

\nJohn Doe

Enter a value:\t

T\u00EAte(Tte)

Special Constants

There are two special constants:

null can be used as the value for any reference type (but not primitive type) variable.

A class literal (constant) is formed by taking a type name and appending .class to it. For example, String.class.

Variables, Basic Data Types, and Type Binding

Name of a variable:is an identifier.

Address of a variable:is not accessible in a program.

In Java, the number of bytes reserved for a memory location depends on the data type of the corresponding variable, and not on the machine on which you will be running the Java program.

Basic data types:Java basic data types with their range of values are provided in the following table:

Data Type

Type of Data

Range of Values

Size

boolean

Boolean value

true, false

char

A single character

Unicode character representations: \u0000 \uffff

2 byte

byte

integers

-27 (-128) to 27 1 (127)

1 bytes

short

integers

-215 (-32,768) to 215 1 (32,767)

2 bytes

int

integers

-231 (-2,147,483,648) to 231 1 (2,147,483,647)

4 bytes

long

integers

-263 (-9,223,372,036,854,775,808) to 263 1 (9,223,372,036,854,775,807)

8 bytes

float

Floating point decimals

Negative range: -3.4028235E+38 to -1.4E-45

Positive range: 1.4E-45 to 3.4028235E+38

4 bytes

double

Floating point decimals

Negative range: -1.7976931348623157E+308 to -4.9E-324

Positive range: 4.9E-324 to 1.7976931348623157E+308

8 bytes

The precisions of a floating point data types are provided as follows:

Data Types

Precision

float

7 digits

double

15 digits

Type Binding:

(static type binding with explicit declarations of variables).

In Java, a variable must be declared before it can be used.

The declaration statement is the same as in C++.

Examples

intnum,

// to hold the first value

number,// to hold the second value

sum;

// to hold their sum

Note

There is a Java class named type-wrapper class for each of the basic data types above. This class has the same name as the basic data type, but starts with an uppercase letter: Byte, Short, Integer, Long, Float, and Double.

Arithmetic Expressions

The rules for writing and evaluating valid arithmetic expressions are the same as in C++. However, unlike in C++, the order of operands evalution in Java is left-to-right.

Java also allows mixed-mode expressions as in C++: the following table shows the Java arithmetic operators and how the data type of the result is obtained from those of the operands.

Operation

Operator

Example

Promotion Rule

Addition

+

A + B

1. Operands with data type byte or short are converted to int.

2. If either operand is of type double, then the other operand is converted to double.

3. Otherwise, if either operand is of type float, then the other operand is converted to float.

4. Otherwise, if either operand is of type long, then the other operand is converted to long.

5. Otherwise, both operands are converted to int.

Subtraction

-

A B

Multiplication

*

A * B

Division

/

A / B

Modulus (Remainder)

%

A % B

Negation

-

-A

Assignment Statement

Its syntax is the same as in C++:

=;

Examples

char letter;

int num1, result;

double dnum;

letter = A;

num1 = 25;

dnum = 4.25;

result = num1 * 3;

// the new value of variable result is 75

Assignment conversion Rules

Java allows you to make certain assignment conversions by assigning a value of one type to a variable in another type as follows:

byteshortintlongfloatdouble

Example

byte bnum = 97;

int inum = 123;

long lnum;

double dnum;

lnum = bnum;

dnum = inum;

Conversions from one type to the right of an arrow above to another type to the left of the arrow are done by means of casts. However, there may be a loss of information in the conversion.

Example

double dnum = 9.997;

int inum = (int) dnum;

// the value of inum is: 9

Compound Assignments and the Assignment Operator

Compound assignments are specified in the same way as in C++ as follows:

= ;

Which is equivalent to the regular assignment:

= ;

Examples

Compound Assignments

Equivalent Simple Assignments

counter += 5;

counter = counter + 5;

power *= value;

power = power * value;

total -= value;

total = total - value;

remain %= 8;

remain = remain % 8;

result /= num - 25

result = result / (num - 25);

number *= -1;

number = -number;

In Java, the assignment is an operator with right-to-left associativity.

Example

num1 = num2 = number = 5;

//num1 = 5

num2 = 5

number = 5

Initial value of a Variable

The initial value of a variable with a basic data type can be specified when it is declared in the same way as in C++.

Examples

int num1 = 25,

num2,

sum = 0;

char letter , grade = 'A';

Naming Constants

In Java, you use the keyword final in the declaration of a variable to indicate that its initial value cannot be modified as follows:

final = ;

Example

final double PI = 3.14;

final int MAXVALUE = 150;

final variables correspond to const variables in C++. They are in general specified in upper case.

Increment and Decrement Operators

The increment and the decrement operators are the same as in C++.

Example

int inum1 = 12, inum2 = 50;

double dnum = 2.54;

inum1++;

inum2 = - - inum1 * 10 ;

++dnum;

Logical Expressions

A logical expression (or condition) are specified and evaluated in the same way as in C++.

A simple condition has the following syntax:

Relational Operators

C/C++ Symbol

Meaning

pis less than/p

p>

is greater than

= =

is equal to

=

is greater than or equal to

!=

is not equal to

A compound condition is built from simple conditions and logical operators.

Logical Operators

C++ Symbol

Meaning

Evaluation

&&

AND

&& is true if and only if both conditions are true

||

OR

|| is true if and only if at least one of the two conditions is true

!

NOT

! is true if and only if is false

In C++, 0 is false and anything else is true. But this is not the case in Java. So, the C++ condition !num (which is equivalent to num = = 0) is not valid in Java.

Precedence of Java Operators

Operator

Order of Evaluation

Precedence

!

Unary

right to left

7

*

/

%

left to right

6

+

-

left to right

5

program.out

For the bytecode Program.class to get its input from the file program.dat and to send its output to the file program.out, execute it as follows:

java Program < program.dat > program.out

Lab Procedure

A. Follow this procedure if you are using one of the lab computers

1. Use Notepad to create the file SETUPJAVA.BAT with the following content:

@echo off

set PATH=C:\Program Files\Java\jdk1.8.0_25\bin;%PATH%

E:

Where:

jdk1.8.0_25 is the version of the Java Development Kit installed on your PC

E:

is the name of the drive with your flash drive.

2. Save the file in your flash drive.

3. Perform the following activities before you can compile and execute your Java programs:

a. Use Notepad or any other editor to type your Java program source files and save them in your flash drive (make sure that your flash drive is in drive E and type the name of the source files in double quotes: e.g. Lab0.java).

b. Click the Start button, and then click All Programs, then Accessories, and then Command Prompt to open the Command Prompt window.

c. Type the command: DIR C:\Program Files\Java ( to list the content of the Java directory.

d. Make sure that the version number of the JDK is 1.8.0_25; otherwise change 1.8.0_25 in the SETUPJAVA.BAT file to the version number of the JDK displayed on your computer.

e. At the Prompt, execute the SETUPJAVA.BAT file as follows: E:\SETUPJAVA (

B. Follow this procedure if you are using a laptop or a computer at home

1. First find out the version number of your Java Development Kit as follows:

a. Click the Start button, and then click All Programs, then Accessories, and then Command Prompt to open the Command Prompt window.

b. Type the command: DIR C:\Program Files\Java ( to list the content of the Java directory. Your version of the JDK will be listed with its version number (for example: jdk1.8.0_25). Note that if you have downloaded the 32-bit version of JDK, you should type the command: DIR C:\Program Files (x86)\Java (

2. Update the PATH Environment variable to include the pathname:

C:\Program Files\Java\jdk1.8.0_25\bin (where 1.8.0_25 is the version number of JDK)

orC:\Program Files (x86)\Java\jdk1.8.0_25\bin (if you have a 32-bit version of JDK).

You update the PATH environment variable as follows:

a. Click Start, then Control Panel, then System and Security, then System.

b. Click Advanced System Settings, then Environment Variable.

c. Select Path in System Variables and then click Edit.

d. Use the right-arrow key to move the cursor to the end of the displayed string.

e. Type a semicolon followed by the pathname that you want to add.

f. Click OK.

3. Perform the following steps before you can compile and execute your Java programs:

a. Use Notepad or any other editor to type your Java program source files and save them in your flash drive (make sure that your flash drive is in drive E and type the name of the source files in double quotes: e.g. Lab0.java).

b. Click the Start button, and then click All Programs, then Accessories, and then Command Prompt to open the Command Prompt window.

c. Type E: (

to change to the drive that contains your flash drive.

Java Methods

Java methods have the same syntax as C++ functions; but they are defined in the class in which they belong: there are no function prototypes in Java.

A Java method may be specified as a class (static) method or an instance method.

Class methods and instance methods differ in the way they are called in a Java program.

Variables and methods defined in a Java class also have access specifiers.

The access specifiers with their access levels are provided as follows:

specifier

Can be accessed in:

Class

Package

Subclass

Everywhere

public

Yes

Yes

Yes

Yes

protected

Yes

Yes

Yes

No

No specifier

Yes

Yes

No

No

private

Yes

No

No

No

The general syntax of a class (static) method follows:

static ( )

{

}

The general syntax of an instance method follows:

( )

{

}

Where

is either private, public or is not specified

is either void or the data type of the value returned by the function

is a list of zero or more value parameters.

Parameters are specified in the same way that they are specified in C++, except that there are no reference parameters in Java: Java allows only value parameters.

In addition to values in the basic data types boolean, char, byte, short, int, long, float, and double, Java methods can return arrays, strings, and objects.

Defining and Calling a Class (static) Method

You call a class (static) method in any other method (class or instance) in the class in which it is defined in the same way that you call a user-defined function in C++.

Example P2

The following program reads two integer values and computes their product by calling the class method int computeProd1(int num1, int num2).

/*-------------------------------------------------------Program2 --------------------------------------------*/

/* Read two integer values, compute their product

*/

import java.util.Scanner;

public class Program2

{

public static void main( String [ ] args )

{

Scanner input = new Scanner( System.in );// for standard input

int first,

// to hold the first value

second;

// to hold the second

/*-------------------------------read the two values -------------------------------*/

first = input.nextInt( );

second = input.nextInt( );

/*---------------------------Compute and print their product--------------------------------*/

int product = computeProd1( first, second );

System.out.println( Their product is:\t + product );

}

/*---------------------------------------Class Method computeProd( )--------------------------------------*/

/* compute the product of two integer values and returns it

*/

static int computeProd1( int num1, int num2)

{

return( num1 * num2);

}

}

Defining and Calling an Instance Method

You call an instance method in a class (static) method as follows:

First define and initialize a reference variable with the location of an object of the class of the instance method.

Follow that variable with the dot (.) which is followed by the method name to call it.

You define and initialize a reference variable with the location of an object in one of the following ways:

a. = new ( );

b. ;

= new ( );

Example P3

The following program reads two integer values and computes their product by calling the instance method int computeProd2(int num1, int num2).

/*-------------------------------------------------------Program3 --------------------------------------------*/

/* Read two integer values, compute their product

*/

import java.util.Scanner;

public class Program3

{

public static void main( String [ ] args )

{

Scanner input = new Scanner( System.in );// for standard input

int first,

// to hold the first value

second;

// to hold the second

/*-------------------------------read the two values -------------------------------*/

first = input.nextInt( );

second = input.nextInt( );

/*---------------------------Compute and print their product--------------------------------*/

Program3 objRef = new Program3( );

int product = objRef.computeProd2( first, second );

System.out.println( Their product is:\t + product );

}

/*---------------------------------------Instance Method computeProd( )--------------------------------------*/

/* compute the product of two integer values and returns it

*/

int computeProd2( int num1, int num2)

{

return( num1 * num2);

}

}

You call an instance method in another instance method from the same class in the same way that you call a user-defined function in C++.

Example P4

The following program reads two integer values and computes their average by calling the instance method int computeAvg(int num1, int num2) which also calls the instance method int computeSum(int num1, int num2).

/*-------------------------------------------------------Program4 --------------------------------------------*/

/* Read two integer values, compute their product

*/

import java.util.Scanner;

public class Program4

{

public static void main( String [ ] args )

{

Scanner input = new Scanner( System.in );// for standard input

int first,

// to hold the first value

second;

// to hold the second

/*-------------------------------read the two values -------------------------------*/

first = input.nextInt( );

second = input.nextInt( );

/*---------------------------Compute and print their product--------------------------------*/

Program4 objRef = new Program4( );

int average = objRef.computeAvg( first, second );

System.out.println( Their average is:\t + average );

}

/*---------------------------------------Instance Method computeAvg( )--------------------------------------*/

/* compute the product of two integer values and returns it

*/

int computeAvg( int num1, int num2)

{

int total = computeSum( num1, num2);

return( total / 2);

}

/*---------------------------------------Instance Method computeSum( )--------------------------------------*/

/* compute the product of two integer values and returns it

*/

int computeSum( int num1, int num2)

{

return( num1 + num2 );

}

}

You can call a class (static) method in an instance method.

Example P5

The following program reads two integer values and computes their average by calling the instance method int computeAvg(int num1, int num2) which also calls the class method int computeSum(int num1, int num2).

/*-------------------------------------------------------Program5 --------------------------------------------*/

/* Read two integer values, compute their product

*/

import java.util.Scanner;

public class Program5

{

public static void main( String [ ] args )

{

Scanner input = new Scanner( System.in );// for standard input

int first,

// to hold the first value

second;

// to hold the second

/*-------------------------------read the two values -------------------------------*/

first = input.nextInt( );

second = input.nextInt( );

/*---------------------------Compute and print their product--------------------------------*/

Program5 objRef = new Program5( );

int average = objRef.computeAvg( first, second );

System.out.println( Their average is:\t + average );

}

/*---------------------------------------Instance Method computeAvg( )--------------------------------------*/

/* compute the product of two integer values and returns it

*/

int computeAvg( int num1, int num2)

{

int total = computeSum( num1, num2);

return( total / 2);

}

/*---------------------------------------Class Method computeSum( )--------------------------------------*/

/* compute the product of two integer values and returns it

*/

static int computeSum( int num1, int num2)

{

return( num1 + num2 );

}

}

Class variables

A class variable (static field) is any variable declared with the static modifier. It is the same as a static member variable in C++.

It is used as a C++ global variable and is accessed by both instance and class methods.

It is in general defined as follows:

static ;

Where

is either private, public or is not specified

A class variable may also have an initial value or be a final variable.

Example P6

The following program reads two integer values and computes the quotient and the remainder in the division of the first value by the second by calling the class method void computeQuotRem(int num1, int num2).

Note that since arguments are not passed by reference in Java, two class variables are needed to get the quotient and the remainder from function computeQuotRem( ).

/*-------------------------------------------------------Program6 --------------------------------------------*/

/* Read two integer values and compute the quotient and the remainder in the division

of the first value by the second

*/

import java.util.Scanner;

public class Program6

{

static int quotient;

// to hold the quotient

static int remain;

// to hold the remainder

public static void main( String [ ] args )

{

Scanner input = new Scanner( System.in );// for standard input

int first,

// to hold the first value

second;

// to hold the second

/*-------------------------------read the two values -------------------------------*/

first = input.nextInt( );

second = input.nextInt( );

/*-------------------Compute and print the quotient and the remainder-------------------*/

if( second == 0 )

System.out.println( Division by zero is not allowed!);

else

{

computeQuotRem( first, second );

System.out.println(The quotient is:\t + quotient );

System.out.println(The remainder is:\t + remain );

}

}

/*--------------------------------------Class Metod computeQuotRem( )--------------------------------------*/

/* compute the quotient and the remainder in the division of the first argument by the second

*/

static void computeQuotRem( int num1, int num2)

{

quotient = num1 / num2;

remain = num1 % num2;

}

}

Method (Name) Overloading

Two or more Java methods may have the same name, as long as there is a way to distinguish them based on their parameters: this feature is known as method name overloading.

The compiler determines the right version of the method to call from a set of overloaded methods by inspecting the arguments specified in the function call.

The program in example P7 illustrates the use of method name overloading in a source module.

Example P7

Method Name Overloading

/*----------------------------------------------------Porgram7 ------------------------------------------------------*/

/*Compute the average of two integer values, the average of three integer values

and the average of two double precision floating-point values.

*/

import java.util.Scanner;

public class Program7

{

int main()

{

int result1,

// the average of two integer values

result2;

// the average of three integer values

double result3;//the average of two floating-point values

result1 = ComputeAverage(4, 5);

// calling first method

result2 = ComputeAverage(5, 4, 6);// calling second method

result3 = ComputeAverage(4.0, 5.0);// calling third method

System.out.println( result1=\t + result1 );

System.out.println( result2=\t + result2 );

System.out.println( result3=\t + result3 );

return 0;

}

static int ComputeAverage(int value1, int value2)

{

return (value1 + value2) / 2;

}

static int ComputeAverage(int value1, int value2, int value3)

{

return (value1 + value2 + value3) / 3;

}

static double ComputeAverage(double value1, double value2)

{

return (value1 + value2) / 2;

}

}

OUTPUT

result1=4

result2=5

result3=4.5

One-Dimensional Arrays

In Java, a one-dimensional array variable is a reference variable: it is an explicit/implicit heap dynamic variable.

A one-dimensional array variable is declared as follows:

[ ] ;

Where is either a basic data type or a class name.

Examples

int [ ]studentIdList;

double [ ] studentScoreList;

char [ ] letterGrades;

String [ ] names;

You allocate and bind memory locations to a one-dimensional array variable by using the new operator as follows:

= new [ ];

Examples

studentIdList = new int [ 10 ];

// allocate an array of 10 integer elements

studentScoreList = new double[20];// allocate an array of 20 double precision elements

names = new String [ 50 ];

// allocate an array of 50 String elements

You can also allocate and bind memory locations to a one-dimensional array variable in a declaration statement as follows:

[ ] = new [ ];

Example

int [ ] studentIdList = new int [ 10 ];

// allocate an array of 10 integer elements

A one-dimensional array can also be initialized when it is declared as follows:

[ ] = { };

Example

int [ ] firstPrimes = { 2, 3, 5, 7, 11, 13, 17, 19 };

String [ ] firstNames = { John, Mark, Paterson, Joe, Peter, Pat, Allan };

The size (number of elements) of an array is accessed by using the length member variable.

Example

int size1 = firstPrimes.length;

// size1 is set to 8

int size2 = firstNames.length;

// size2 is set to 7

Accessing and Processing the Elements of a one-Dimensional Array

The elements of a one-dimensional array are accessed and processed in Java in the same way that they are accessed and processed in C++.

Example

/*----- code segment to compute the sum of the elements of the array first Primes---*/

int total = 0;

for ( int i = 0; i < firstPrimes.length; i ++ )

total + = firstPrimes [ i ];

Copying Arrays

The method arraycopy of the class System is provided in the standard Java library to copy the elements of a one-dimensional array into another one of the same data type. It is specified as followed:

System.arraycopy ( , , , , );

Where

is the array to copy from

is the starting index to copy from

is the array to copy to

is the starting index to copy to

is the number of element to copy

Example

char [ ] copyFrom = { d, e, c, a, f, f, e, i, n, a, t, e, d };

char [ ] copyTo = new char [ 7 ];

System.arraycopy( copyFrom, 2, copyTo, 0, 7 );

// set array copyTo as follows: copyTo[0] = c, copyTo[1] = a, copyTo[2] = f,

// copyTp[3] = f, copyTo[4] = e, copyTo[5] = i, and copyTo[6] = n

An array variable behaves like a C++ pointer variable. So, if you assign one array variable to another one using the assignment operator, both variables will refer to the array allocated for the assigned variable.

Example

char [ ] copyFrom = { d, e, c, a, f, f, e, i, n, a, t, e, d };

char [ ] copyTo;

copyTo = copyFrom;

// The above array now has two names: copyTo and copyFrom

// copyTo[i] and copyFrom[i] are interchangeable in any expression.

The statement:

copyTo[i] = a;

has the same effect as

copyFrom[i] = a;

We have the following memory representation after the assignment operation is performed:

d

e

c

a

f

f

e

i

n

a

t

e

d

copyFrom

copyTo

Enhanced for Statement

The enhanced for statement iterates through the elements of an array (one-by-one starting with the first element) without using a counter.

It syntax is as follows:

for( : )

Where:

is the name of the array

is a data type that is consistent with the data type of the elements in the array.

represents successive elements of the array, starting with the first.

Examples

/*----- code segment to compute the sum of the elements of the array firstPrimes ---*/

int total = 0;

for ( int element : firstPrimes )

total + = element;

System.out.println(The sum of the first Primes is:\t + total );

/*----- code segment to print the names in the array firstNames ---*/

for ( String element : firstNames )

System.out.println( element );

The enhanced for statement can only be used to access the values of the elements on an array: it cannot be used to modify the values of the elements of an array. The following code segment will generate an error:

/*----- invalid code segment to read values into an array ---*/

int [ ] list = new int [ 10 ];

for ( int element : list )

element = input.nextInt( );

Arrays as Parameters or Returned Values of Methods

In Java, a one-dimensional array is passed and processed in a method in the same way that a one-dimensional array is passed and processed in a function in C++, except that you do not have to pass the size of the array. Also, the argument that corresponds to a one-dimensional array in a method call is the name of an array as in a function call in C++.

In Java, a method can return a one-dimensional array variable which is not the case for a function in C++.

Example

/*------------------------------- Method arraySum --------------------------------------*/

/* receives as argument an array of integer values and computes and returns

the sum of its members */

static int arraySum( int [ ] list )

{

int total = 0;

for ( int i = 0; i < list.length; i ++ )

total + = list[i];

return ( total );

}

/*-------------------------------------- Method array5Incr --------------------------------------*/

/* receives as argument an array of integer values and adds 5 to each of its members */

static void array5Incr( int [ ] list )

{

for ( int i = 0; i < list.length; i ++ )

list[i] + = 5;

}

/*------------------------------------------- Method addAarrays ----------------------------------------------*/

/* receives as arguments two arrays of integer values with the same size, adds their corresponding elements, and stores the result in the corresponding element of a third array that it then returns*/

static int [ ] addArrays( int [ ] list1, int[ ] list2 )

{

int size = list1.length;

int [ ] temp = new int [size];

for ( int i = 0; i < size; i ++ )

temp[i] = list1[i] + list2[i];

return ( temp );

}

Some examples of method calls of these methods follow:

int [ ] valuesList1 = { 21, 25, 32, 45, 15, 8, 13, 35, 1, 17 },

valuesList2 = { 12, 52, 23, 54, 51, 8, 31, 53, 1, 71 },

valuesList3;

int sum;

// to hold the sum of the values in array valuesList1

/*--------------- compute and print the sum of the elements of array valuesList1 ----------*/

sum = arraySum( valuesList1 );

System.out.println( The sum of the elements is:\t + sum );

/*-------------------------- Add 5 to each element of array valuesList2 -----------------------*/

Array5Incr( valuesList2 );

/*-Add corresponding elements of arrays valuesList1 and valuesList2 and store the result in the corresponding element of array valuesList3 ----------------------------------------------------------------------------------------------*/

valuesList3 = addArrays( valuesList1, valuesList2 );

Two-Dimensional Arrays

Similarly to one-dimensional arrays, a two-dimensional array variable is a reference variable: it is an explicit/implicit heap dynamic variable.

It is declared as follows:

[ ][ ] ;

Where is either a basic data type or a class name.

Examples

int [ ][ ]studentScores;

double [ ][ ] totalSales;

char [ ][ ] document;

String [ ][ ] namesTable;

You allocate memory locations for a two-dimensional array variable by using the new operator as follows:

= new [ ][ ];

Examples

studentScores = new int [10][ 5 ];// allocate an integer array of 10 rows and 5 columns

totalSales = new double [ 15][10];// allocate a double precision array of 15 rows and 10 columns

document = new char [25][80];// allocate an character array of 25 rows and 80 columns

namesTable = new String [10 ][5];

You can also allocate memory locations for a two-dimensional array variable in a declaration statement as follows:

[ ][ ] = new [ ][ ];

Example

int [ ][ ] studentScores = new int [10][ 5 ]; // allocate an integer array of 10 rows and 5 columns

A two-dimensional array can also be initialized when it is declared as follows:

[ ][ ] = { { } };

Example

int [ ][ ] labScores = { { 8, 9, 7, 8, 10 },

{ 9, 8, 8, 8, 7 },

{ 8, 7, 9, 9, 10 }

};

String [ ][ ] students = { {John, Mark, Paterson },

{ Joe, Peter, Pat },

{ Dave, Bonnie, Pat },

{ Allan, Amy, Ellen }

};

When you create a two-dimensional array, the number of elements in a row does not have to be the same for all the rows.

Example

int [ ] [ ] pascalTriangle5 = { { 1 },

{ 1, 1 },

{ 1, 2, 1 },

{ 1, 3, 3, 1},

{ 1, 4, 6, 4, 1 },

{ 1, 5, 10, 10, 5, 1} };

Note that each row i (0 daysPerMonth [ month ]) )

{

System.out.println( Invalid date );

System.exit ( 1 );

}

}

}

Public class testDayOfYear

{

/*------- Program is executed with a month and a day as command line arguments -----*/

public static void main( String [ ] args )

{

DayOfYear today = new DayOfYear( ),

// to hold todays month and day

johnBirthday = new DayOfYear( 4, 25 );

// set Johns birthday

/*------------------------------------ read todays month and day ---------------------*/

Scanner input = new Scanner( System.in );

System.out.println( \nEnter today\s month and day:\t );

today.inputDate( input );

/*---------------------------output Johns birthday ----------------------------------------------*/

System.out.println( John\s birthday is:\t + johnBirthday.getStringDate( ) );

if ( today.equalTo( johnBirthday )

System.out.println( Happy Birthday John Doe );

/*------------ output the twelve months of the year ----------------------------------------*/

for( int ct = 1; ct obj2.year, and if they are equal, if obj1.month > obj2.month, and if they are equal, if obj1.day > obj2.day. Otherwise, it returns false.

B. Define a class named TestDate with the method main that does the following:

It first defines an object with the default date and then outputs this date as a string.

It defines an object named today and initializes it with todays date.

It outputs the message Todays day is:\t followed by todays date as a string.

It defines an object named dueDate and then reads values for its instance variables.

It uses the instance method isEqualTo( ) to compare the object today and dueDay and if they are equal, it outputs the message Your project is on time; otherwise, it uses the method isGreaterThan( ) to compare these objects again and then output either the message Your project is late or Your project is early as appropriate.

It finally reads or sets an object with an invalid date (for example, 25, 4, 2000).

Objects as Instance Variables of a Class

In Java, a class can have objects of other classes as instance variables.

In C++, special constructs are used to call the constructor for data member objects. But in Java, there is no need for it because an object variable is a reference to an object that is created somewhere else.

Example O11

As an example of a class with objects of other classes as instance variables, we define the following class Employee with the following instance variables:

first name

-class String

last name

-class String

birth day

-class DayOfYear (above)

hours

-integer

pay rate

-double precision

In addition to the constructors, the class also has:

The instance method read(Scanner scan ) that reads the first name, last name, birth day, hours, and pay rate of an employee, and

the instance method String getEmployeeString( ) that returns a string in the following format:

NAME:

BIRTH DAY:

GROSS PAY:

The instance methods of this class are tested in the method main of the class testDayOfYear.

import java.util.Scanner;

public class Employee

{

private String firstName;

// first name (object)

private String lastName;

// last name (object)

private DayOfYear birthDay;

// birth day (object)

private int hours;

// number of hours of work

private double payRate;

// Employees pay rate

/*----------------default constructor ----------------------------------*/

/* initialize object instance variables firstName, lastName, and birthDay to null and

instance variables hours and pay rate to 0 */

Public Employee ( )

{

hours = 0;

rate = 0.0;

}

/*----------------------------------- constructor with parameters -------------------------------*/

Public Employee( string fname, string lname, DayOfYear bday, int hrs, double prate)

{

firstName = fname;

lastName = lname;

birthDay = bday;

hours = hrs,

payRate = prate;

}

/*-------------------------------- Member function getEmployeeString( )---------------------------------*/

/* return the string consisting of the name, birth day and gross pay

*/

public String getEmployeeString( )

{

String st = String.format(\nNAME:\t%s\nBIRTH DAY:\t%s\nGROSS PAY:\t%f,

lastName + , + firstName, birthDay.getStringDate( ), (hours * payRate) );

return( st );

}

/*----------------------- Member function read( ) -----------------------------------------------*/

/* read the first name, last name, birth day, hours and pay rate of an object

*/

public void read( Scanner scan )

{

birthDay = new DayOfYear( );

System.out.print( \n Enter First Name:\t);

firstName = scan.next( );

System.out.print( \n Enter Last Name:\t);

lastName = scan.next( );

System.out.print( \n Enter Birth Day (month Day):\t);

birthDay.inputDate( scan );

System.out.print( \n Enter Hours:\t);

hours = scan.nextInt( );

System.out.print( \n Enter Pay Rate:\t);

payRate = scan.nextDouble( );

}

}

Public class testEmployee

{

/*------set the following information about a secretary, compute his gross pay and output his information:

first name: John; last name: Doe; day of birth: 3/25; hours of work: 35; pay rate: 10.75 */

/*-------------------------Define the object secretary and set his information --------------------------------*/

DayOfYear tempday new DayOfYear(3, 25);

Employee secretary = new Employee( John, Doe, tempday, 35, 10.75 );

/*------- compute his gross pay and output his information -----------------------------*/

String empst = secretary. getEmployeeString( );

System.out.println( empst );

/*------Read the information about an employee, compute his gross pay and output his information--------*/

Scanner input = new Scanner( System.in );

Employee emp = new Employee( );

emp.read( input );

/*------- compute his gross pay and output his information -----------------------------*/

String empst = emp. getEmployeeString( );

System.out.println( empst );

}

Note:

Object secretary could also be instantiated as follows:

Employee secretary = new Employee( John, Doe, new DayOfYear(3, 25 ) , 35, 10.75 );

Exercise O4

A. Using the class Date that you defined in Exercise O3, write the definition of the class named Employee with the following private instance variables:

first name

-class string

last name

-class string

ID number

-integer (the default ID number is 999999)

birth day

-class Date

date hired

-class Date

base pay

-double precision (the default base pay is $0.00)

In addition to the constructors, the class has the following public instance methods:

void readPInfo(Scanner scan ) that uses the Scanner object parameter to read the values for the instance variables first name, last name, ID number, birth day, and date of hire.

void readPayInfo(Scanner scan ) that uses the Scanner object parameter to read the value for the base pay instance variable.

String getPInfoString( ) that returns a string in the following format:

NAME:

ID NUMBER:

BIRTH DAY:

DATE HIRED: < string-date-hired >

void setBpay( double newBpay ) that sets the value of the base pay to the new value, newBpay.

double getBpay( ) that returns the value of the base pay instance variable.

double getGpay( ) that returns the value of the gross pay (which is the base pay).

double computeTax( ) that computes the tax deduction on the gross pay and returns it as follows:

If gross pay is greater than or equal to 1000, 20% of the gross pay;

If 800 90 )

grade = A;

else if ( score > 80 )

grade = B;

else if( score > 70 )

grade = C;

else if( score > 60 )

grade = D;

else

grade = F;

return ( grade );

}

public void print( );

{

System.out.println( name:\t + getName( ) );

System.out.println( Age:\t + getAge( ) );

System.out.println( Score:\t + score );

System.out.println( Grade:\t + getGrade( ) );

}

}

The following table lists the instance variables and methods of each of the classes above.

Class Person

Class Student

Instance Variables

name

age

name (inherited from class Person, but not accessible)

age (inherited from class Person, but not accessible)

score

Instance Methods

getName

getAge

print

getName (inherited from class Person)

getAge (inherited from class Person)

print (overrides the print method of class Person)

getGrade

Method Overriding

A method of the subclass is said to override a method of the super class when both methods have the same name, and the number, order, and type of their parameters are exactly the same.

Example: instance method print of class Student overrides instance method print of class Person.

If an instance method of the subclass overrides a method of the super class, then it must also have the same return type as the method of the super class.

Also, any reference of this method on an object of the subclass will referred to the definition of the method in the subclass.

Example: the output of the program that follows is:

Output

Name: Mark Fisher

Age:21

Name:Alan Ford

Age:18

Score:93

Grade:A

public class StudentTest

{

Public static void main(String [ ] args)

{

Person per = new Person(Mark Fisher, 21);

Student stu = new Student(Alan Ford, 18, 93);

per.print( );

Stu.print( );

}

}

An overridden instance method of the super class may be called in an instance method of the subclass by preceding the call statement with the keyword super followed by a period.

Example:

The overridden instance method print of super class Person is called in the instance method print of the subclass Student to output an objects name and age as follows:

public void print( );

{

super.print( );

// output a students name and age

System.out.println( Score:\t + score );

System.out.println( Grade:\t + getGrade( ) );

}

The @Override Annotation

It is always recommended to precede the definition of a method that overrides a method of the super class with the @Override annotation.

When this is done, the compiler checks to make sure that this method has the same name, and the number, order, and type of parameters as the method of the super class and issues an error message when this is not the case.

Example:Instance method print of subclass Student can then be rewritten as follows:

@Override

public void print( );

{

super.print( );

// output a students name and age

System.out.println( Score:\t + score );

System.out.println( Grade:\t + getGrade( ) );

}

Protected members of a Class

A protected instance variable/method of a base class is like a private instance variable/method of that class except that it can be directed accessed in an instance method of its subclasses.

You make an instance variable/method a protected instance variable/method by preceding its definition with the keyword protected instead of private.

Example

By making the instance variables name and age of class Person protected instead of private as follows:

protected String name;

protected int age;

We can write the overridden method print of the class Student as follows:

public void print( );

{

System.out.println( name:\t + name );

System.out.println( Age:\t + age );

System.out.println( Score:\t + score );

System.out.println( Grade:\t + getGrade( ) );

}

Relationship between a Super Class and a Subclass

An object of a subclass is also an object of the super class (without the additional instance variables and instance methods):

You can assign the reference of an object of a subclass to a reference variable of the super class.

However, you cannot use that reference variable to access the additional instance variables and methods of the subclass.

Example

The following assignment statement is legal:

Person pers = new Student(John Peter, 22, 85);

But the statement:

char grade = pers.getGrade( ));

is illegal because the instance method getGrade is not an instance method of the class Person.

Explicit Casting

A reference variable of the super class that holds the reference of an object of a subclass can be used to access an instance variable or instance method of the subclass that is not an instance variable or method of the super class by using the cast operator as follows:

Example

Given the following assignment statement:

Person pers = new Student(John Peter, 22, 85);

The following statements are legal

char grade = ((Student)pers).getGrade( );

or:

Student stu = (Student)pers;

char grade = stu.getGrade( ));

A method that is defined to return an object of the super class can return an object of a subclass without any lost of data.

Example

The following method is legal:

public Person someMethod( )

{

Student stu = new Student( Mark, 20, 83);

return( stu );

}

A method that has a reference variable of the super class as parameter can be called with an object of a subclass.

Example

Assume given the following method helper:

public static void helper( Person pers )

{

. . .

}

And the following declarations of objects:

Person mypers new Person(Peter, 23);

Student stu = new Student(Bob, 17, 75);

The following call statements are legal:

helper( mypers );

helper( stu );

An object of the super class is not an object of a subclass.

An object of the super class cannot then be used in a program where an object of the subclass is needed.

Example

The following statement is illegal:Student stu = new Person( Pat Reely, 21);

Dynamic Binding (Polymorphism)

When an instance method of the super class is overridden in a subclass,

A call to that instance method does not depend on the reference variable, but on the object instantiated for that reference variable.

It is bound (at run time) to the definition of the method in the class of that object.

Example

Assume given the following classes named Parent and Child:

class Parent

// class Parent

{

public void helper( )

{

printObject( );

}

public void printObject( )

{

System.out.println("parent");

}

}

class Child extends Parent

// class Child

{

public void printObject( )

{

System.out.println("child");

}

}

Given the following declarations of variables, the calls of the methods printObject and Helper will produce the output as indicated below:

Parent pobj = new Parent( );

Parent cobj1 = new Child( );

Child cobj2 = new Child( );

Method Calls

Output

pobj. printObject ( );

parent

cobj1. printObject ( );

child

pobj.helper( );

parent

cobj1.helper( );

child

cobj2.helper( );

child

Also assume given the following definition of the static method newHelper:

static void newHelper( Parent obj )

{

obj. printObject ( );

}

The following calls to the methods newHelper will produce the indicated output:

Method Calls

Output

newHelper ( pobj );

parent

newHelper ( cobj1 );

child

newHelper ( cobj2 );

child

Exercise O8

A. Write the definition of the subclass of class Employee (that you defined in Exercise O4) named BonusEmployee as follows:

1. It has one additional private instance variable named bonus (double precision) with the default value $0.0.

2. In addition to the constructors, it has the following public instance methods:

double getBonus( void )

that returns the value of the instance variable bonus.

3. Instance method void readPayInfo(Scanner scan ) is overridden in the class BonusEmploye: it now reads the values for the instance variables base pay and bonus.

4. Instance method double getGpay( ) is overridden in the class BonusEmploye: it now returns the sum of the value of the instance variable base pay and the value of the instance variable bonus.

5. Instance method String getPayInfoString( ) is overridden in the class BonusEmploye: it returns a string in the following format:

BASE PAY:

BONUS:

GROSS PAY:

TAX DEDUCTION:

NET PAY:

B. Define the class TestBonusEmployee with the method main( ) that is used to test your class as follows:

1. Method main first defines an object of the class Employee with the default values for its instance variables, and then prints its personal and pay information.

2. It defines an object of the class BonusEmployee with the default values for its instance variables, and then prints its personal and pay information.

3. It initializes an object of the class Employee as follows: first name: John; last name: Doe; ID #: 111111; Date of birth: 10/ 25/1991; Date of hire: 5/10/2010; and base pay: $1250; and then prints its personal and pay information.

4. It initializes an object of the class BonusEmployee as follows: first name: Jobe; last name: Daly; ID #: 222222; Date of birth: 1/ 5/1990; Date of hire: 6/30/2011; base pay: $850; and bonus: $250; then prints its personal and pay information.

5. It reads the personal and pay information of an object of the class Employee, and then outputs its personal and pay information.

6. It then reads the personal and pay information of an object of the class BonusEmployee and then outputs its personal and pay information.

Exercise O9

Given the class Employee that you defined in Exercise O4 and class BonusEmployee that you defined in Exercise O8, we define the objects eemp, bemp1, and bemp2 as follows:

Employee eemp = new Employee( );

Employee bemp1 = new BonusEmployee( );

BonusEmployee bemp2 = new BonusEmployee( );

1. Assuming that the input values are typed as followed: 1000 600 500 2000 400 900

Show the output of the following sequence of statements:

Scanner scan new Scanner( System.in );

eemp.readPayInfo( scan );

bemp1.readPayInfo( scan );

bemp2.readPayInfo( scan );

System.out.println( Gross Pay of eemp=\t + (eemp.getGpay( ) );

System.out.println( Gross Pay of bemp1=\t + (bemp1.getGpay( ) );

System.out.println( Gross Pay of bemp2=\t + (bemp2.getGpay( ) );

System.out.println( Tax of eemp=\t + (eemp.computeTax( ) );

System.out.println( Tax of bemp1=\t + (bemp1. computeTax ( ) );

System.out.println( Tax of bemp2=\t + (bemp2. computeTax ( ) );

2. Is the statement double bonus = bemp1.getBonus( ); legal? Explain your answer.

Exercise O10 (extra credit)

A. Write the definition of the derived class of class Employee (that you defined in Exercise O4) named HourlyEmployee as follows:

1. It has three additional instance variables named hours (integer) and payRate (double precision), and overtime (double precision). Their default values are 0 for hours, and $0.00 for payRate and overtime.

2. It also has a private instance method void computeBaseOvertimePay( ) that computes the base pay and the overtime pay as follows:

a. If the value of the instance variable hours is less than or equal to 35, then it does the following:

i. Set the value of the inherited instance variable base pay to payRate times hours.

ii. Set the value of the instance variable overtime to 0.00.

b. Otherwise, it does the following:

i. Set the value of the inherited instance variable base pay to payRate times 35.

ii. Set the value of the instance variable overtime to payRate times 1.5 times (hours 35).

3. The constructor with parameters has the following method header:

HourlyEmployee( string fn, string ln, int iD, Date bd, Date hd, int hrs, double prate)

Where hrs represents the number of hours of work and prate the pay rate.

It calls class Employees constructor with 0 as the argument for the data member base pay, and then calls the private instance method computeBaseOvertimePay( ) to set the values of the instance variables base pay and overtime.

4. In addition to the constructors, it has the following public instance methods:

a. int getHours( void )

returns the value of the data member hours.

b. double getPayRate( void )returns the value of the data member payRate.

c. double getOvertime( void )returns the value of the data member overtime.

5. Instance method void readPayInfo(Scanner scan ) is overridden in the class HourlyEmployee: it now reads the values of the instance variables hours and payRate, and then calls the private instance method computeBaseOvertimePay( ) to set the values of the instance variables base pay and overtime.

6. Instance method double getGpay( ) is overridden in the class HourlyEmployee: it now returns the sum of the values of the instance variables base pay and overtime.

7. Instance method String getPayInfoString( ) is overridden in the class HourlyEmployee: it returns a string in the following format:

HOURS:

PAY RATE:

BASE PAY:

OVERTIME:

GROSS PAY:

TAX DEDUCTION:

NET PAY:

B. Define the class TestHourlyEmployee with the method main that is used to test your class as follows:

1. Function main first defines an object of the class HourlyEmployee with the default values for its instance variables, and then prints its personal and pay information.

2. It initializes an object of the class HourlyEmployee as follows: first name: Mark; last name: Peter; ID #: 333333; Date of birth: 1/10/1995; Date of hire: 7/10/2012; hours: 50; and pay rate: $25; then prints its personal and pay information.

3. It initializes an object of the class HourlyEmployee as follows: first name: Jane; last name: Doe; ID #: 444444; Date of birth: 10/1/1998; Date of hire: 5/10/2011; hours: 30; and pay rate: $20; then prints its personal and pay information.

4. It then reads the personal and pay information of an object of the class HourlyEmployee and then outputs its personal and pay information.

Final Classes and Methods

A class declared as final cannot be extended (inherited) and

A method declared as final cannot be overridden.

You make a class/method final by placing the keyword final either before or after the access specifier in the class/method definition.

Example

1.

final public class MyClass

{

. . .

}

2.

public final class MyClass

{

. . .

}

3.

final public void myMethod( )

{

. . .

}

4.

public final void myMethod( )

{

. . .

}

Class Object

Class Object is a direct or indirect super class of every Java class (including arrays).

Its methods are therefore inherited by every Java class or array.

The class Object defines 11 methods, five of which are used in the context of multithreading.

The methods that we discuss here are the equals, getClass, and toString methods.

equals Method

The equals method has the following header:

public boolean equals(Object obj)

It returns true only if the reference variable on which it is called and the reference variable passed as argument refer to the same object in memory.

This method can be overridden in a class so that the contents of the two objects are compared instead.

getClass Method

This method has no parameters, and returns an object of the class Class (from the package java.lang).

The object that it returns contains the information about the objects type, including its class name that is returned by the instance method getName of the class Class.

Example:

Given the following declaration of object stu (where Student is the class defined in Example O16):

Student stu = new Student(John, 32, 87);

The output of the statementSystem.out.println( stu.getClass( ).getName( ));is:Student

toString Method

This method has no parameters, and returns a String representation of the object on which it is called: this string contains the package name and the name of the objects class followed by the @ sign and the hexadecimal representation of the object.

When you specify an object reference in your program where a string is required (such as an argument to the print( ) or println( ) method or strings concatenation), the toString( ) method is implicitly called on that object and the String object that it returns is used instead.

Example:

Given the following instantiation of an object (where Student is the class defined in Example O16):

Student stu = new Student(John, 32, 87);

The output of the statementSystem.out.println( stu ));

is: Student@b2fd4e:

Also, the statementString st = My + stu; will assign the string My Student@b2fd4e to st.

The toString( ) method is in general overridden in order to have a better string representation of the object.

Example: if it is overridden in the class Student as follows:

@Override

public String toString( )

{

String s =

\nName= + name + \nAge = + age + \nScore = + score + \nGrade = + getGrade( );

return( s );

}

Then given the following object instantiation:Student stu = new Student(John, 32, 87);

The output of the following statement System.out.println( stu ));

will be:

Output

Name = John

Age = 32

Score = 87

Grade = B

Exercise O11

1. Override the toString method of the class Date that you defined in Exercise O3: it returns the date as a string in the format: month/day/year.

2. Override the toString method of the class Employee that you defined in Exercise O4 as follows: it returns a string in the following format:

NAME:

ID NUMBER:

BIRTH DAY:

DATE HIRED: < string-date-hired >

GROSS PAY:

TAX DEDUCTION:

NET PAY:

3. Override the toString method of the class BonusEmployee that you defined in Exercise O8: it returns a string in the following format:

NAME:

ID NUMBER:

BIRTH DAY:

DATE HIRED: < string-date-hired >

BASE PAY:

BONUS:

GROSS PAY:

TAX DEDUCTION:

NET PAY:

4. Define the class TestToString with the method main that defines and instantiate an object of the class Date, an object of the class Employee, and an object of the class BonusEmployee. It then displays each of these objects by using the System.out.println( ) method.

5. Given an object named bug, write a statement that will display the name of the class of this object.

Abstract Classes and Abstract Methods

You make a class abstract by declaring it with the keyword abstract as follows:

public abstract class Animal

{

// code

}

You cannot create objects with an abstract class:

The purpose of an abstract class is to provide a superclass from which other classes can inherit and thus share a common design.

You declare an abstract method by using a statement that consists of the keyword abstract followed by the header of the method as follows:

public abstract void move( );

You make a method abstract when you do not want to provide its implementation.

A class that contains one or more abstract methods must be declared as abstract.

Subclasses that inherit an abstract class must provide the implementation of each of the abstract methods. Otherwise, they must also be declared as abstract.

Although you cannot create an object of an abstract class, you can declare a reference variable of that abstract class and then assign to it the reference to an object of a subclass.

The following example illustrates the use of an abstract class.

Example O17

A company sales two shapes of tiles (rectangular and triangular) and the price of a tile is the unit price per square inch times the area of the tile.

Because the area of each of these types of tiles depends on its shape, we process the information about these tiles as follows:

We first design a base abstract class named Tile to represent the information common to all tiles:

The instance variable unitPrice to hold a tiles unit price.

The instance method getUprice that returns the value of the instance variable unitPrice.

The instance method computeArea which is an abstract method because its definition depends on the shape of the tile.

The instance method computePrice that computes and returns the price of a tile, and

The instance method print that prints the price of a tile.

We then create derived classes RectangleTile and TriangleTile to represent the information about each shape of tile.

public abstract class Tile

{

private double unitPrice;

public Tile( )

{

unitPrice = 2.0;

}

public Tile ( double uprice )

{

unitPrice = uprice;

}

public double getUprice( void )

{

return unitPrice ;

}

public abstract double computeArea( void );

// abstract method

public double computePrice( )

{

double area;

area = computeArea( );

// calling the abstract method

return( unitPrice * area );

}

public void print( void )

{

System.out.println(The price of the tile is:\t + computePrice ( ));

}

}

Derived Classes:

/*-------------------------------- class RectangleTile -------------------------------------------*/

class RectangleTile extends Tile

// inherits class Tile

{

private double length;

private double width;

public RectangleTile( )

{

length = 0.5;

width = 1.0;

}

public RectangleTile(double len , double wth, double uprice )

{

super( uprice );

length = len;

width = wth;

}

public double computeArea( void )

{

return ( length * width );

// return the area of a rectangular tile

}

public void print( void )

{

System.out.println( The length is:\t + length );

System.out.println( The width is:\t + width);

System.out.println( The price of the tile is:\t + computePrice ( ));

}

}

/*-------------------------------- class TriangleTile -------------------------------------------*/

class TriangleTile extends Tile

// inherits class Tile

{

private double height;;

private double base;

public TriangleTile ( )

{

height = 0.5;

base = 1.0;

}

public TriangleTile (double ht , double bse, double uprice )

{

super( uprice );

height = ht;

base = bse;

}

public double computeArea( void )

{

return ( height * base / 2.0 );

// return the area of a triangular tile

}

public void print( void )

{

System.out.println( The height is:\t + height);

System.out.println( The base is:\t + base);

System.out.println( The price of the tile is:\t + computePrice ( ));

}

}

Exercise O12

Define the class TestTile with the method main that defines the following two objects:

Tile tile1 = new RectangleTile( 3.0, 5.0, 4.0 );

Tile tile2 = new TriangleTile( 2.0, 6.0, 8.0 );

And then outputs the information about these two objects.

Interfaces

A Java interface is used to specify what is to be done but not how it is to be done.

For example, a Vehicle should be capable of performing several tasks such as starting, stopping and changing speed. All types of vehicles, be it a car or a motorcycle should be capable of doing these tasks.

In such a case, we can define an interface Vehicle where these various methods are specified but the definition of these methods are given in the classes like Car and Motorcycle which implement these interfaces.

A Java interface consists of only final static variables and abstract methods: no implementation is provided for the methods.

You declare an interface as follows:

interface

{

}

The interface name follows conventions similar to those followed by class names: the first letter of each word in an interface is capitalized.

The access specifier may be either public or unspecified. When stated as public, the interface is available to all classes. When no access specifier is stated, default access restrictions are applied and the interface is accessible only from classes within the same package. private and protected access specifiers cannot be used here.

Variables in an interface are implicitly final, static and public.

And the methods are implicitly abstract and public.

Use of specifiers that overwrite these default specifiers is not allowed.

The following example shows the interface Vehicle with three abstract methods and a final static variable CODE.

publicinterfaceVehicle

{intCODE=347;

//implicitlystatic, public,andfinalpublic voidstart();

//methodisimplicitlypublicandabstractpublicvoidstop();

//methodisimplicitlyabstractpublicabstractvoidchangeSpeed(intnewSpeed);// access specifier and abstract not necessary}

Note that a variable declared in an interface must have an initial value because it is a final variable.

Implementing an Interface

A class implements an interface by providing the definition for each of its abstract methods.

A class that implements an interface is defined as follows:

class implements

{

}

A class that implements an interface may have constructors and other variables and methods.

Example

Class Aeroplane implements the interface Vehicle declared above as follows:

publicclassAeroplaneimplementsVehicle

{

private intmaxSpeed;

// the maximum speed of the plane

private int speed;

// the current speed

private String name;

// its name

public Aeroplane( )

{

maxSpeed = 500;

name = Air Plane;

}

public Aeroplane( int maxSp, String nme )

{

maxSpeed = maxSp;

name = nme;

}

publicvoidstart( )

{

speed = 50;

System.out.println("Takingoff:\t" + (CODE + 10) );

}

publicvoidstop( )

{

speed = 0;

System.out.println("Takinglanding:\t" + (CODE + 10) );

}

@Override

publicvoidchangeSpeed( intnewSp )

{

if( newSp > maxSpeed || newSp < 0 )

{

System.out.println( "Invalid speed" );

System.exit( 1 );

}

speed=newSp;

}

public void print( )

{

System.out.println(The vehicle name is:\t + name + \nIts code is:\t + (CODE + 10));

System.out.println(Its maximum speed is:\t + maxSpeed );

}

}

Notes:

a. The @Override annotation may be used before the definition of a method to ensure that we are using the correct method definition.

b. A variable declared in an interface (such as CODE) becomes a variable of each class that implements that interface: it can therefore be accessed in the definition of any method of that class.

c. A class that does not implement an interface can access a variable defined in that interface by preceding its name with the name of the interface as in the following example:

intcode=Vehicle.CODE;

d. A class can implement more than a single interface: these interfaces are included in the class declaration with a comma separated list as shown below.

publicclassAeroplaneimplementsVehicle,AnotherInterface

{

. . .

}

e. A class can extend a superclass in addition to implementing interfaces.

f. An interface can be implemented by more than one class.

g. If a class does not provide the implementations of all the methods declared in the interface, the class itself should be defined as abstract. These abstract methods can then be defined in classes which extend this one.

Interfaces as Data Types

An interface is also an ADT. However you cannot create objects with an interface.

You declare a variable with an interface data type to hold the reference of an object of a class that implements that interface.

Example

Given the interface Vehicle and its class implementation Aeroplane above, the following statements are legal:

Vehicle myVehicle=new Aeroplane( );

myVehicle.start( );

myVehicle.changeSpeed( 250 );

myVehicle.stop( );

However, the following statement is illegal because print is not a method of the interface Vehicle:

myVehicle.print( );

To be able to call this method, reference variable myVehicle needs to be first cast to an Aeroplane variable as follows:

((Aeroplane ) myVehicle).print( );

Or:

AeroplanemyAirPlane=(Aeroplane ) myVehicle;

myAirPlane.print( );

A method with return type an interface can return an object of a class that implements that interface as in the following example:

publicVehiclemeth( )

{

. . .

returnnewAeroplane();

}

A method with an interface parameter can be called with an object of a class that implements that interface as in the following example:

publicstatic voidsomeMethod(Vehiclev)

{

//code

}

//calltotheabovemethod

someMethod(newAeroplane());

Note

The above technique of considering an interface as a data type brings out the reason behind the use of an interface.

One can define a class that contains calls to the methods start( ) and stop( ) on Vehicle objects without any concerns about the type of Vehicle: an Aeroplane or a Car.

Since only objects of the classes that have implemented the Vehicle interface can be passed to the class, there is no need to worry if the class has the methods start( ) or stop( ).

However, to use method other than those defined in the interface, the object needs to be cast to an appropriate type.

Interfaces and Inheritance

Interfaces can also be extended just like classes by using the extends keyword as follows:

publicinterfaceSuperVehicleextendsVehicle

{

//code

}

The new interface will have all the variables and methods declared in its super interfaces.

Unlike classes, an interface can extend more than one interface by using a comma separated list as follows:

publicinterfaceSuperVehicle extendsVehicle, anotherInterface

{

//code

}

Note

Inheritance is in general used in the context of interfaces when extending an interface is necessary.

For example, consider that the above Vehicle interface has been implemented by many other developers. Now, if you add another method to this interface, all the classes created by the other developers would break as a class when implementing an interface should provide definitions for all the methods that have been declared in the interface.

The developers will have to modify their classes before they can be used once gain. To avoid such complication, interfaces are extended when one wishes to modify them by adding new methods.

Exercise O13

The payroll interface is defined as follows:

public interface Payroll

{

double TAXRATE = 0.15;

// tax rate

double getGrossPay( );

// to compute and return the gross pay

double getDeductions( );

// to compute and return the deductions

void printDetails( );

// to output the payroll

}

A. Write the definition of the class HourlyPay that implements the interface Payroll as follows:

It has two private instance variables hours (double) and payRate (double).

The constructor without parameters initializes the instance variable hours to 40 and payRate to 10.00

It has an additional private instance method double getOverTime( ) that does the following: it returns 1.5 *(hours 40) * payRate if the value of the instance method hours is greater than 40; and 0 otherwise.

Instance method getGrossPay( ) returns hours * payRate + overtime.

Instance method getDeduction( ) returns TAXRATE * gross pay.

Override the toString method of this class as follows: it uses the String.format( ) static method to create and return the following string:

PAY RATE:

HOURS:

OVERTIME:

GROSS PAY:

TAX DEDUCTION:

NET PAY:

Public instance method printDetails( ) prints the payroll information above.

B. Write the definition of the class TestHourlyPay with the method main that does the following:

Define an object and initializes it with the default constructor.

Call the printDetails( ) method to print its payroll information.

Define an object and initializes it with the hours 50 and pay rate $12.

Call the printDetails( ) method to print its payroll information.

Default Interface Methods (Java SE 8)

Nested Classes

The Java programming language allows you to define a class within another class. Such a class is called a nested class and is illustrated as follows:

class OuterClass

{

. . .

static class StaticNestedClass

{

. . .

}

class InnerClass

{

. . .

}

}

There are two categories of nested classes: static nested classes and non-static nested classes that are also called inner classes.

Static Nested Classes

A static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience:

An outer class can access the instance variables and methods of an enclosed static nested class only through an object reference.

A static nested class can access the instance variables and methods of the enclosing class only through an object reference.

However, static nested class StaticNestedClass enclosed in the class OuterClass is accessed in a class that is not StaticNestedClass or OuterClass by using the enclosing class name as follows: OuterClass.StaticNestedClass

For example, you create the object nestedObject of the class StaticNestedClass in a class that is not StaticNestedClass or OuterClass as follows:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass( );

Example

The program that follows consists of three classes: class StaticNestedClass is a static nested class of the class OuterClass and class StaticNestedClassTest contains the main method which calls the instance method printProd of the class OuterClass, and then the instance method printSum of the class StaticNestedClass.

Instance method printProd of the class OuterClass calls the instance method getInnerNum of the class StaticNestedClass and

Instance method printSum of the class StaticNestedClass calls the instance method getOuterNum of the class OuterClass.

public class StaticNestedClassTest

{

public static void main(String[ ] args)

{

OuterClass outerObject = new OuterClass( );

outerObject.printProd( );

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass( );

nestedObject.printSum( );

}

}

class OuterClass

{

private int outerNum;

public OuterClass( )

{

outerNum = 5;

}

public int getOuterNum( )

{

return( outerNum );

}

public void printProd( );

{

StaticNestedClass obj = new StaticNestedClass( );

System.out.println( outerNum * innerNum =\t + (outerNum * obj.getInnerNum( ) );

}

static class StaticNestedClass

{

private int innerNum;

public StaticNestedClass( )

{

innerNum = 10;

}

public int getInnerNum( )

{

return( innerNum );

}

public void printSum( )

{

OuterClass obj = new OuterClass( );

System.out.println( innerNum + outerNum =\t + (innerNum + obj.getOuterNum( ) );

}

} // end of class StaticNestedClass

} // end of class OuterClass

Notes:

The two statements:

OuterClass outerObject = new OuterClass( );

outerObject.printProd( );

could be replaced with the statement:(new OuterClass( )). printProd( );

And the two statements:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass( );

nestedObject.printSum( );

could be replaced with the statement: (new OuterClass.StaticNestedClass( )).printSum( );

Exercise O14

Complete the following program as specified by the inserted comments.

public class Other

{

public static void main(String[ ] args)

{

/*--- 1 ------ write the sequence of statements to call the method innerMethod2 ------------*/

}

}

class OuterClass

{

public void outerMethod( )

{

System.out.println(outer class);

/*---- 2 ----- write the sequence of statements to call the method innerMethod1 ------------*/

}

static class NestedClass

{

public void innerMethod1( )

{

System.out.println(nested class 1);

}

public void innerMethod2( )

{

System.out.println(nested class 2);

/*---- 3 ----- write the sequence of statements to call the method outerMethod------------*/

}

} // end of class StaticNestedClass

} // end of class OuterClass

Inner Classes

A non-static nested class is also referred to as an inner class.

An inner class cannot declare or define any static member.

An outer class can access the instance variables and instance methods of an enclosed inner class only through an object reference.

An inner class method has direct access to the variables and methods of the enclosing outer class.

You instantiate an inner class in a class that is not the outer class or the inner class itself, by first instantiating the outer class and then, creating the inner class object within the outer class object as follows:

OuterClass outerObject = new OuterClass( );

OuterClass.InnerClass innerObject = outerObject.new InnerClass( );

Or:

OuterClass.InnerClass innerObject = (new OuterClass( )).new InnerClass( );

Example

The program that follows consists of three classes: class InnerClass is an inner class of the class OuterClass and class InnerClassTest contains the main method which calls the instance method display of the class InnerClass.

Instance method update of the class OuterClass calls the instance method getInnerNum of the class InnerClass, and

Instance method display of the class InnerClass accesses the instance variable outerNum of the class OuterClass, and calls instance method printOuterNum of the class OuterClass.

public class InnerClassTest

{

public static void main(String[ ] args)

{

OuterClass outerObject = new OuterClass( );

OuterClass.InnerClass innerObject = outerObject.new InnerClass( );

innerObject.display( );

}

}

class OuterClass

{

private int outerNum;

public OuterClass( )

{

outerNum = 5;

}

public int getOuterNum( )

{

return( outerNum );

}

public void update( )

{

InnerClass obj = new InnerClass( );

outerNum += obj.getInnerNum( );

}

public void printOuterNum( )

{

System.out.println( outerNum:\t + outerNum);

update( );

System.out.println(\n updated outerNum:\t + outerNum );

}

class InnerClass

{

private int innerNum;

public InnerClass( )

{

innerNum = 10;

}

public int getInnerNum( )

{

return( innerNum );

}

public void display( )

{

System.out.println( innerNum + outerNum =\t + (innerNum + outerNum );

printOuterNum( );

}

} // end of class InnerClass

} // end of class OuterClass

Notes:

The two statements:

OuterClass outerObject = new OuterClass( );

OuterClass.InnerClass innerObject = outerObject.new InnerClass( );

could be replaced with the statement:

OuterClass.InnerClass innerObject = (new OuterClass( )).new InnerClass( );