Fundamental Concept For Java Programming
Fundamental Concept For Java Programming
1) string handling
2) event handling
3) Object collections
Outline: Vertical APIs
Vertical APIs are designed to perform specific functions.
1) distributed programming
2) Java XML processing
3) Java Web Services
4) J2EE web components
5) J2EE business components
Course Resources
1) books
a) Java 2 The Complete Reference, Herbert Schildt, Osborne, 5th
edition, 2002
b) The Java Tutorial, Sun Microsystems,
http://java.sun.com/docs/books/tutorial/, 2004
c) Thinking in Java, Bruce Ecker, 3rd edition, Prentice Hall, 2002
2) articles
Links available from the website http://www.emacao.gov.mo.
3) tools
a) JDK 1.5
b) Eclipse IDE
Course Logistics
1) duration - 36 hours
2) activities - lecture (hands-on), development
3) sessions/day - morning 09:00–13:00 and afternoon 14:30–16:30
4) number of sessions - 6 morning and 6 afternoon
5) style - interactive and tutorial
Course Prerequisite
1) some experience in object-oriented programming:
a) C++
b) Delphi
c) any other object-oriented language
2) basic understanding of TCP/IP networking concepts
Course Outline
1) introduction 3) object-orientation 4) horizontal libraries
2) language a) objects a) string handling
a) syntax b) classes b) event handling
b) types c) inheritance c) object collections
c) variables d) polymorphism
5) vertical libraries
d) arrays e) access
a) graphical interface
e) operators f) interfaces
b) applets
f) control flow g) exception handling
c) input/output
h) multi-threading
d) networking
6) summary
Overview
Topics under this module:
1) Java origin and history
2) Java technology
3) Java language
4) Java platform
5) simple Java program
6) Java documentation
7) setting up Java environment
Java Origins
Computer language innovation and development occurs for two
fundamental reasons:
BASIC, COBOL, FORTRAN, PASCAL optimized one set of traits, but not
the other.
OOP – methodology that helps organize complex programs through the use
of inheritance, encapsulation and polymorphism.
With Internet, the urgent need appeared to break the fortified positions of
Intel, Macintosh and Unix programmer communities.
Java was not designed to replace C++, but to solve a different set of
problems. There are significant practical/philosophical differences.
Java Technology
There is more to Java than the language.
Steps:
class MyProgram {
public static void main(String[] args) {
System.out.println(“First Java program.");
}
}
Running the Program
Type the program, save as MyProgram.java.
> dir
MyProgram.java
> javac MyProgram.java
> dir
MyProgram.java, MyProgram.class
> java MyProgram
First Java program.
Explaining the Process
1) creating a source file - a source file contains text written in the Java
programming language, created using any text editor on any system.
2) compiling the source file Java compiler (javac) reads the source file
and translates its text into instructions that the Java interpreter can
understand. These instructions are called bytecode.
class MyProgram {
Example:
1) Windows - add %JAVA_HOME%\bin to the beginning of the PATH
variable.
2) Linux - include PATH="$PATH:$JAVA_HOME/bin:.” in your
/etc/profile or .bashrc files.
java -version
a) procedural part
b) object-oriented part
Language Overview
a) syntax – whitespaces, identifiers, comments, separators, keywords
b) types – simple types byte, short, int, long, float double, char, boolean
c) variables – declaration, initialization, scope, conversion and casting
d) arrays – declaration, initialization, one- and multi-dimensional arrays
e) operators – arithmetic, relational, conditional, shift, logical, assignment
f) control flow – branching, selection, iteration, jumps and returns
/" 0
Course Outline
1) introduction 3) object-orientation 4) horizontal libraries
2) language a) objects a) string handling
a) syntax b) classes b) event handling
b) types c) inheritance c) object collections
c) variables d) polymorphism
5) vertical libraries
d) arrays e) access
a) graphical interface
e) operators f) interfaces
b) applets
f) control flow g) exception handling
c) input/output
h) multi-threading
d) networking
6) summary
Java Syntax
On the most basic level, Java programs consist of:
a) whitespaces
b) identifiers
c) comments
d) literals
e) separators
f) keywords
g) operators
class MyProgram {
public static void main(String[] args) {
System.out.println(“My first Java program.");
}
}
Separators
() parenthesis lists of parameters in method definitions and invocations,
precedence in expressions, type casts
{} braces block of code, class definitions, method definitions, local scope,
automatically initialized arrays
[] brackets declaring array types, referring to array values
Example:
byte b = -15;
Example:
short c = 1000;
Example:
int b = -50000;
Usage:
1) Most common integer type.
2) Typically used to control loops and to index arrays.
3) Expressions involving the byte, short and int values are promoted
to int before calculation.
Simple Type: long
64-bit integer type.
Example:
long l = 10000000000000000;
Usage:
1) useful when int type is not large enough to hold the desired value
Example: long
// compute the light travel distance
class Light {
public static void main(String args[]) {
int lightspeed = 186000;
long days = = 1000;
long seconds = days * 24 * 60 * 60;
long distance = lightspeed * seconds;
System.out.print("In " + days);
System.out.print(" light will travel about
");
System.out.println(distance + " miles.");
}
}
Simple Type: float
32-bit floating-point number.
Example:
float f = 1.5;
Usage:
1) fractional part is needed
2) large degree of precision is not required
Simple Type: double
64-bit floating-point number.
Example:
double pi = 3.1416;
Usage:
1) accuracy over many iterative calculations
2) manipulation of large-valued numbers
Example: double
// Compute the area of a circle.
class Area {
public static void main(String args[]) {
double pi = 3.1416; // approximate pi value
double r = 10.8; // radius of circle
double a = pi * r * r; // compute area
System.out.println("Area of circle is " + a);
}
}
Simple Type: char
16-bit data type used to store characters.
Range: 0 to 65536.
Example:
char c = ‘a’;
Usage:
1) Represents both ASCII and Unicode character sets; Unicode defines a
character set with characters found in (almost) all human languages.
2) Not the same as in C/C++ where char is 8-bit and represents ASCII only.
Example: char
// Demonstrate char data type.
class CharDemo {
public static void main(String args[]) {
char ch1, ch2;
ch1 = 88; // code for X
ch2 = 'Y';
System.out.print("ch1 and ch2: ");
System.out.println(ch1 + " " + ch2);
}
}
Another Example: char
It is possible to operate on char values as if they were integers:
class CharDemo2 {
public static void main(String args[]) {
char c = 'X';
System.out.println("c contains " + c);
c++; // increment c
System.out.println("c is now " + c);
}
}
Simple Type: boolean
Two-valued type of logical values.
Range: values true and false.
Example:
boolean b = (1<2);
Usage:
1) returned by relational operators, such as 1<2
2) required by branching expressions such as if or for
Example: boolean
class BoolTest {
public static void main(String args[]) {
boolean b;
b = false;
System.out.println("b is " + b);
b = true;
System.out.println("b is " + b);
if (b) System.out.println("executed");
b = false;
if (b) System.out.println(“not executed");
System.out.println("10 > 9 is " + (10 > 9));
}
}
Literals Revisited
Literals express constant values.
1) decimal – 123
2) octal – 0173
3) hexadecimal – 0x7B
Integer literal written with “L” (e.g. 123L) are of type long.
Literals: Floating-Point Types
Two notations:
1) standard – 2000.5
2) scientific – 2.0005E3
Floating-point literal written with “F” (e.g. 2.0005E3F) are of type float.
Literals: Boolean
Two literals are allowed only: true and false.
In particular:
Example:
“Hello World!”
Notes:
1) escape sequences can be used inside string literals
2) string literals must begin and end on the same line
3) unlike in C/C++, in Java String is not an array of characters
Exercise: Types
1) What is the value of b in the following code snippet?
byte b = 0;
b += 1;
2) What happens when this code is executed?
char c = -1;
3) Which of the following lines will compile without warning or error. Explain
each line.
float f=1.3;
char c="a";
byte b=257;
boolean b=null;
int i=10;
4) Write a java statement that will print the following line to the console:
To print a ‘ “ ‘, we use the ‘ \“ ‘escape sequence.
+
Course Outline
1) introduction 3) object-orientation 4) horizontal libraries
2) language a) objects a) string handling
a) syntax b) classes b) event handling
b) types c) inheritance c) object collections
c) variables d) polymorphism
5) vertical libraries
d) arrays e) access
a) graphical interface
e) operators f) interfaces
b) applets
f) control flow g) exception handling
c) input/output
h) multi-threading
d) networking
6) summary
Outline: Variables
1) declaration – how to assign a type to a variable
2) initialization – how to give an initial value to a variable
3) scope – how the variable is visible to other parts of the program
4) lifetime – how the variable is created, used and destroyed
5) type conversion – how Java handles automatic type conversion
6) type casting – how the type of a variable can be narrowed down
7) type promotion – how the type of a variable can be expanded
Variables
Java uses variables to store data.
Examples:
int a, b, c;
int d = 3, e, f = 5;
byte hog = 22;
double pi = 3.14159;
char kat = 'x';
Constant Declaration
A variable can be declared as final:
The value of the final variable cannot change after it has been initialized:
PI = 3.13;
Variable Identifiers
Identifiers are assigned to variables, methods and classes.
An identifier:
1) starts with a letter, underscore _ or dollar $
2) can contain letters, digits, underscore or dollar characters
3) it can be of any length
4) it must not be a keyword (e.g. class)
5) it must be unique in its scope
Naming conventions:
If a variable name consists of more than one word, the words are joined
together, and each word after the first begins with an uppercase letter.
int n = 1;
int m = n + 1;
{
…
}
{
int n;
}
n = 1;
Scope Nesting
Scopes can be nested:
{ … { … } … }
Variables declared in the outside scope are visible in the inside scope, but
not the other way round:
{
int i;
{
int n = i;
}
int m = n;
}
Example: Variable Scope
class Scope {
public static void main(String args[]) {
int x;
x = 10;
if (x == 10) {
int y = 20;
System.out.println("x and y: " + x + "
" + y);
x = y * 2;
}
System.out.println("x is " + x + “y is” + y);
}
}
Declaration Order
Method variables are only valid after their declaration:
{
int n = m;
int m;
}
Variable Lifetime
Variables are created when their scope is entered by control flow and
destroyed when their scope is left:
1) A variable declared in a method will not hold its value between different
T1 t1;
T2 t2 = t1;
1) integer types and floating-point types are compatible with each other
2) numeric types are not compatible with char or boolean
3) char and boolean are not compatible with each other
Examples:
byte b;
int i = b;
char c = b;
Widening Type Conversion
Java performs automatic type conversion when:
Example:
int i;
double d = i;
Narrowing Type Conversion
When:
int i;
byte b = i;
int i;
byte b = (byte)i;
Type Casting
General form: (targetType) value
Examples:
int i;
byte b = (byte) i;
float f;
int i = (int) f;
Example: Type Casting
class Conversion {
public static void main(String args[]) {
byte b;
int i = 257;
double d = 323.142;
System.out.println("\nConversion of int to byte.");
b = (byte) i;
System.out.println("i and b " + i + " " + b);
System.out.println("\ndouble to int.");
i = (int) d;
System.out.println("d and i " + d + " " + i);
}
}
Type Promotion
In an expression, precision required to hold an intermediate value may
sometimes exceed the range of either operand:
byte a = 40;
byte b = 50;
byte c = 100;
int d = a * b / c;
Java promotes each byte operand to int when evaluating the expression.
Type Promotion Rules
1) byte and short are always promoted to int
2) if one operand is long, the whole expression is promoted to long
3) if one operand is float, the entire expression is promoted to float
4) if any operand is double, the result is double
byte b = 50;
b = b * 2;
Arrays are:
1) declared
2) created
3) initialized
4) used
type array-variable[];
or
type [] array-variable;
Array Creation
After declaration, no array actually exists.
type array-variable[];
array-variable = new type[size];
This creates a new array to hold size elements of type type, which
reference will be kept in the variable array-variable.
Array Indexing
Later we can refer to the elements of this array through their indexes:
array-variable[index]
The Java run-time system makes sure that all array indexes are in the
correct range, otherwise raises a run-time error.
Example: Array Use
class Array {
public static void main(String args[]) {
int monthDays[];
monthDays = new int[12];
monthDays[0] = 31;
monthDays[1] = 28;
monthDays[2] = 31;
monthDays[3] = 30;
monthDays[4] = 31;
monthDays[5] = 30;
…
monthDays[12] = 31;
System.out.print(“April has ”);
System.out.println(monthDays[3] +“ days.”);
}
}
Array Initialization
Arrays can be initialized when they are declared:
Comments:
System.out.print(“April ”);
System.out.println(mthDys[3]+ “ days.”);
}
}
Multidimensional Arrays
Multidimensional arrays are arrays of arrays:
1) declaration
int array[][];
2) creation
3) initialization
1) assignment
2) arithmetic
3) relational
4) logical
5) bitwise
6) other
Operators and Operands
Each operator takes one, two or three operands:
j++;
i = j++;
i = (i>12) ? 1 : i++;
Assignment Operator
A binary operator:
variable = expression;
The value of the whole assignment expression is the value of the expression
on the right, so it is possible to chain assignment expressions as follows:
int x, y, z;
x = y = z = 2;
Arithmetic Operators
Java supports various arithmetic operators for:
1) integer numbers
2) floating-point numbers
-= v -= expr; v = v - expr;
*= v *= expr; v = v * expr;
/= v /= expr; v = v / expr;
%= v %= expr; v = v % expr;
Increment/Decrement Operators
Two unary operators:
• prefix version evaluates the value of the operand after performing the
increment/decrement operation
• postfix version evaluates the value of the operand before performing the
increment/decrement operation
Table: Increment/Decrement
++ v++ return value of v, then increment v
They are most often used in branching and loop control statements.
Table: Relational Operators
== equals to apply to any type
1) full op1 & op2 and op1 | op2 where both op1 and op2 are
evaluated
2) short-circuit - op1 && op2 and op1 || op2 where op2 is only
evaluated if the value of op1 is insufficient to determine the final outcome
Table: Logical Operators
& op1 & op2 logical AND
! ! op logical NOT
}
Bitwise Operators
Bitwise operators apply to integer types only.
>> op1 >> op2 shifts all bits in op1 right by the value of op2
<< op1 << op2 shifts all bits in op1 left by the value of op2
>>> op1 >>> op2 shifts op1 right by op2 value, write zero on the left
Example: Bitwise Operators
class BitLogic {
public static void main(String args[]) {
String binary[] = { "0000","0001","0010", … };
int a = 3; // 0 + 2 + 1 or 0011 in binary
int b = 6; // 4 + 2 + 0 or 0110 in binary
int c = a | b;
int d = a & b;
int e = a ^ b;
System.out.print("a =" + binary[a]);
System.out.println("and b =" + binary[b]);
System.out.println("a|b = " + binary[c]);
System.out.println("a&b = " + binary[d]);
System.out.println("a^b = " + binary[e]);
}
}
Other Operators
?: shortcut if-else statement
where:
i = 10;
k = i < 0 ? -i : i;
System.out.print("Abs value of “ + i + " is " + k);
i = -10;
k = i < 0 ? -i : i;
System.out.print("Abs value of “ + i + " is " + k);
}
}
Operator Precedence
Java operators are assigned precedence order.
if equivalent to
When operators have the same precedence, the earlier one binds stronger.
Table: Operator Precedence
highest
() [] .
++ -- ~ !
* / %
+ -
>> >>> <<
> >= < <=
== !=
&
^
|
&&
||
?:
= op=
lowest
Exercise: Operators
1) What operators do the code snippet below contain?
arrayOfInts[j] > arrayOfInts[j+1];
2) Consider the following code snippet:
int i = 10;
int n = i++%5;
a) What are the values of i and n after the code is executed?
b) What are the final values of i and n if instead of using the postfix
increment operator (i++), you use the prefix version (++i))?
3) What is the value of i after the following code snippet executes?
int i = 8;
i >>=2;
4) What’s the result of System.out.println(010| 4); ?
5 6 #
Course Outline
1) introduction 3) object-orientation 4) horizontal libraries
2) language a) objects a) string handling
a) syntax b) classes b) event handling
b) types c) inheritance c) object collections
c) variables d) polymorphism
5) vertical libraries
d) arrays e) access
a) graphical interface
e) operators f) interfaces
b) applets
f) control flow g) exception handling
c) input/output
h) multi-threading
d) networking
6) summary
Control Flow
Writing a program means typing statements into a file.
Without control flow, the interpreter would execute these statements in the
order they appear in the file, left-to-right, top-down.
Control flow statements, when inserted into the text of the program,
determine in which order the program should be executed.
Control Flow Statements
Java control statements cause the flow of execution to advance and branch
based on the changes to the state of the program.
1) if
2) if-else
3) if-else-if
4) switch
if Statement
General form:
if (expression) statement
1) simple
if (expression) statement;
2) compound
if (expression) {
statement;
}
if-else Statement
Suppose you want to perform two different statements depending on the
outcome of a boolean expression. if-else statement can be used.
General form:
if (expression) statement1
else statement2
if (expression1) statement1
else if (expression2) statement2
else if (expression3) statement3
…
else statement
Semantics:
1) statements are executed top-down
2) as soon as one expressions is true, its statement is executed
3) if none of the expressions is true, the last statement is executed
Example: if-else-if
class IfElse {
public static void main(String args[]) {
int month = 4;
String season;
if (month == 12 || month == 1 || month == 2)
season = "Winter";
else if(month == 3 || month == 4 || month == 5)
season = "Spring";
else if(month == 6 || month == 7 || month == 8)
season = "Summer";
else if(month == 9 || month == 10 || month == 11)
season = "Autumn";
else season = "Bogus Month";
System.out.println("April is in the " + season + ".");
}
}
switch Statement
switch provides a better alternative than if-else-if when the execution
follows several branches depending on the value of an expression.
General form:
switch (expression) {
case value1: statement1; break;
case value2: statement2; break;
case value3: statement3; break;
…
default: statement;
}
switch Assumptions/Semantics
Assumptions:
1) expression must be of type byte, short, int or char
2) each of the case values must be a literal of the compatible type
3) case values must be unique
Semantics:
1) expression is evaluated
2) its value is compared with each of the case values
3) if a match is found, the statement following the case is executed
4) if no match is found, the statement following default is executed
switch(count) {
case 1:
switch(target) {
case 0:System.out.println(“target is zero”);
break;
case 1:System.out.println(“target is one”);
break;
}
break;
case 2: …
}
Since, every switch statement defines its own block, no conflict arises
between the case constants in the inner and outer switch statements.
Comparing switch and if
Two main differences:
1) switch can only test for equality, while if can evaluate any kind of
boolean expression
2) Java creates a “jump table” for switch expressions, so a switch
statement is usually more efficient than a set of nested if statements
Iteration Statements
Java iteration statements enable repeated execution of part of a program
until a certain termination condition becomes true.
1) while
2) do-while
3) for
while Statement
General form:
Semantics:
1) simple
2) compound
while (expression) {
statement;
}
Example: while
class MidPoint {
public static void main(String args[]) {
int i, j;
i = 100;
j = 200;
while(++i < --j) {
System.out.println(“i is " + i);
System.out.println(“j is " + j);
}
System.out.println(“The midpoint is " + i);
}
}
do-while Statement
If a component statement has to be executed at least once, the do-while
statement is more appropriate than the while statement.
General form:
do statement
while (expression);
Semantics:
General form:
where:
int a, b;
class ForVar {
public static void main(String args[]) {
int i = 0;
boolean done = false;
for( ; !done; ) {
System.out.println("i is " + i);
if(i == 10) done = true;
i++;
}
}
}
Empty for
In fact, all three components may be omitted:
1) break
2) continue
3) return
In addition, Java supports exception handling that can also alter the control
flow of a program. Exception handling will be explained in its own section.
break Statement
The break statement has three uses:
class BreakLoop {
public static void main(String args[]) {
for (int i=0; i<100; i++) {
if (i == 10) break;
System.out.println("i: " + i);
}
System.out.println("Loop complete.");
}
}
break in Nested Loops
Used inside nested loops, break will only terminate the innermost loop:
class NestedLoopBreak {
public static void main(String args[]) {
for (int i=0; i<3; i++) {
System.out.print("Pass " + i + ": ");
for (int j=0; j<100; j++) {
if (j == 10) break;
System.out.print(j + " ");
}
System.out.println();
}
System.out.println("Loops complete.");
}
}
Control Transfer with break
Java does not have an unrestricted “goto” statement, which tends to
produce code that is hard to understand and maintain.
1) unlabelled
2) labeled
break label;
label: { … }
class BreakError {
public static void main(String args[]) {
one: for(int i=0; i<3; i++) {
System.out.print("Pass " + i + ": ");
}
for (int j=0; j<100; j++) {
if (j == 10) break one;
System.out.print(j + " ");
}
}
}
continue Statement
The break statement terminates the block of code, in particular it terminates
the execution of an iterative statement.
The continue statement forces the early termination of the current iteration
to begin immediately the next iteration.
Two forms:
return;
return expression;
Example: Return
class Return {
public static void main(String args[]) {
boolean t = true;
System.out.println("Before the return.");
if (t) return; // return to caller
System.out.println("This won't execute.");
}
}
Exercise: Control Flow
1) Write a program that prints all the prime numbers between 1 and 49 to
the console.
In other words, except for the first two numbers each Fibonacci number
is the sum of the two previous numbers.
4+7 4
Course Outline
1) introduction 3) object-orientation 4) horizontal libraries
2) language a) objects a) string handling
a) syntax b) classes b) event handling
b) types c) inheritance c) object collections
c) variables d) polymorphism
5) vertical libraries
d) arrays e) access
a) graphical interface
e) operators f) interfaces
b) applets
f) control flow g) exception handling
c) input/output
h) multi-threading
d) networking
6) summary
Data versus Operations
Data (nouns) versus operations (verbs):
data1
… nouns
dataN
operation1 { … }
… verbs
operationN { … }
Procedural Programming
Procedural programming is verb-oriented:
Programming Languages:
1) C
2) Pascal
3) Fortran, etc.
Example: Procedural Program
program AddNums {
Integer a;
Integer b;
a = 100;
b = 200;
midPoint(a, b);
1) state
2) behavior
1) SmallTalk
2) C++
3) C#
4) Java
Object-Oriented Concepts
Three main concepts:
1) encapsulation
2) inheritance
3) polymorphism
Encapsulation
Illustration:
Therefore, objects from the classes related by inheritance may receive the
same requests but respond to such requests in their own ways.
Polymorphism 1
Polymorphism 2
Polymorphism 3
Polymorphism 4
Polymorphism 5
Polymorphism 6
Polymorphism 7
Exercise: OOP Concepts
1) Why Object-oriented programming?
2) Explain the three main concepts of Object-orientation.
3) How does Object-orientation enables data security?
4) Explain how to achieve Polymorphism through Inheritance.
4+7
Course Outline
1) introduction 3) object-orientation 4) horizontal libraries
2) language a) objects a) string handling
a) syntax b) classes b) event handling
b) types c) inheritance c) object collections
c) variables d) polymorphism
5) vertical libraries
d) arrays e) access
a) graphical interface
e) operators f) interfaces
b) applets
f) control flow g) exception handling
c) input/output
h) multi-threading
d) networking
6) summary
Objects
Everything in Java is an object.
Object lifecycle:
1) creation
2) usage
3) destruction
Object Creation
A variable s is declared to refer to the objects of type/class String:
String s;
3) etc.
s2 = s1;
s1 = null;
s1.equals(s2) == true
class classname {
type instance-variable-1;
…
type instance-variable-n;
type method-name-1(parameter-list) { … }
type method-name-2(parameter-list) { … }
…
type method-name-m(parameter-list) { … }
}
Example: Class
A class with three variable members:
class Box {
double width;
double height;
double depth;
}
A new Box object is created and a new value assigned to its width variable:
mybox.width = 10;
mybox.height = 20;
mybox.depth = 15;
class Box { … }
class BoxDemo {
public static void main(…) { … }
}
class BoxDemo2 {
public static void main(String args[]) {
Box mybox1 = new Box();
Box mybox2 = new Box();
double vol;
mybox1.width = 10;
mybox1.height = 20;
mybox1.depth = 15;
Variable Independence 2
mybox2.width = 3;
mybox2.height = 6;
mybox2.depth = 9;
Box myBox;
int n = 1;
b1 = null;
type name(parameter-list) {
… return value; …
}
Components:
1) type - type of values returned by the method. If a method does not
return any value, its return type must be void.
2) name is the name of the method
3) parameter-list is a sequence of type-identifier lists separated by
commas
4) return value indicates what value is returned by the method.
Example: Method 1
Classes declare methods to hide their internal data structures, as well as for
their own internal use:
class Box {
double width, height, depth;
void volume() {
System.out.print("Volume is ");
System.out.println(width * height * depth);
}
}
Example: Method 2
When an instance variable is accessed by code that is not part of the class
in which that variable is defined, access must be done through an object:
class BoxDemo3 {
public static void main(String args[]) {
Box mybox1 = new Box();
Box mybox2 = new Box();
mybox1.width = 10; mybox2.width = 3;
mybox1.height = 20; mybox2.height = 6;
mybox1.depth = 15; mybox2.depth = 9;
mybox1.volume();
mybox2.volume();
}
}
Value-Returning Method 1
The type of an expression returning value from a method must agree with
the return type of this method:
class Box {
double width;
double height;
double depth;
double volume() {
return width * height * depth;
}
}
Value-Returning Method 2
class BoxDemo4 {
public static void main(String args[]) {
Box mybox1 = new Box();
Box mybox2 = new Box();
double vol;
mybox1.width = 10;
mybox2.width = 3;
mybox1.height = 20;
mybox2.height = 6;
mybox1.depth = 15;
mybox2.depth = 9;
Value-Returning Method 3
The type of a variable assigned the value returned by a method must agree
with the return type of this method:
vol = mybox1.volume();
System.out.println("Volume is " + vol);
vol = mybox2.volume();
System.out.println("Volume is " + vol);
}
}
Parameterized Method
Parameters increase generality and applicability of a method:
double volume() {
return width * height * depth;
}
vol = mybox1.volume();
System.out.println("Volume is " + vol);
vol = mybox2.volume();
System.out.println("Volume is " + vol);
}
}
Constructor
A constructor initializes the instance variables of an object.
It is called immediately after the object is created but before the new
operator completes.
Box() {
System.out.println("Constructing Box");
width = 10; height = 10; depth = 10;
}
double volume() {
return width * height * depth;
}
}
Example: Constructor 2
class BoxDemo6 {
public static void main(String args[]) {
Box mybox1 = new Box();
Box mybox2 = new Box();
double vol;
vol = mybox1.volume();
System.out.println("Volume is " + vol);
vol = mybox2.volume();
System.out.println("Volume is " + vol);
}
}
Parameterized Constructor 1
So far, all boxes have the same dimensions.
class Box {
double width;
double height;
double depth;
vol = mybox1.volume();
System.out.println("Volume is " + vol);
vol = mybox2.volume();
System.out.println("Volume is " + vol);
}
}
finalize() Method
A constructor helps to initialize an object just after it has been created.
1) The garbage collector keeps track of how many references an object has.
2) It removes an object from memory when it has no longer any references.
3) Thereafter, the memory occupied by the object can be allocated again.
4) The garbage collector invokes the finalize method.
Keyword this
Keyword this allows a method to refer to the object that invoked it.
1) it is illegal to declare two local variables with the same name inside the
same or enclosing scopes
2) it is legal to declare local variables or parameters with the same name as
the instance variables of the class.
class Stack {
int stck[] = new int[10];
int tos;
Stack() {
tos = -1;
}
Example: Stack 2
void push(int item) {
if (tos==9) System.out.println("Stack is full.");
else stck[++tos] = item;
}
int pop() {
if (tos < 0) {
System.out.println("Stack underflow.");
return 0;
}
else return stck[tos--];
}
}
Example: Stack 3
class TestStack {
public static void main(String args[]) {
Stack mystack1 = new Stack();
Stack mystack2 = new Stack();
for (int i=0; i<10; i++) mystack1.push(i);
for (int i=10; i<20; i++) mystack2.push(i);
System.out.println("Stack in mystack1:");
for(int i=0; i<10; i++)
System.out.println(mystack1.pop());
System.out.println("Stack in mystack2:");
for(int i=0; i<10; i++)
System.out.println(mystack2.pop());
}
}
Method Overloading
It is legal for a class to have two or more methods with the same name.
double test(double a) {
System.out.println("double a: " + a);
return a*a;
}
int test(double a) {
System.out.println("double a: " + a);
return (int) a*a;
}
Overloading and Conversion 1
When an overloaded method is called, Java looks for a match between the
arguments used to call the method and the method’s parameters.
When no exact match can be found, Java’s automatic type conversion can
aid overload resolution:
class OverloadDemo {
void test() {
System.out.println("No parameters");
}
void test(int a, int b) {
System.out.println("a and b: " + a + " " + b);
}
Overloading and Conversion 2
void test(double a) {
System.out.println("Inside test(double) a: " + a);
}
}
class Overload {
public static void main(String args[]) {
OverloadDemo ob = new OverloadDemo();
int i = 88;
ob.test();
ob.test(10, 20);
ob.test(i);
ob.test(123.2);
}
}
Overloading and Polymorphism
In the languages without overloading, methods must have a unique names:
int abs(int i)
long labs(int i)
float fabs(int i)
class Box {
double width, height, depth;
All Box objects can be created in one way: passing all three dimensions.
Example: Overloading 1
Three constructors: 3-parameter, 1-parameter, parameter-less.
class Box {
double width, height, depth;
Box(double w, double h, double d) {
width = w; height = h; depth = d;
}
Box() {
width = -1; height = -1; depth = -1;
}
Box(double len) {
width = height = depth = len;
}
double volume() { return width * height * depth; }
}
Example: Overloading 2
class OverloadCons {
public static void main(String args[]) {
Box mybox1 = new Box(10, 20, 15);
Box mybox2 = new Box();
Box mycube = new Box(7);
double vol;
vol = mybox1.volume();
System.out.println("Volume of mybox1 is " + vol);
vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol);
vol = mycube.volume();
System.out.println("Volume of mycube is " + vol);
}
}
Object Argument 1
So far, all method received arguments of simple types.
class Test {
int a, b;
Test(int i, int j) {
a = i; b = j;
}
boolean equals(Test o) {
if (o.a == a && o.b == b) return true;
else return false;
}
}
Object Argument 2
class PassOb {
public static void main(String args[]) {
Test ob1 = new Test(100, 22);
Test ob2 = new Test(100, 22);
Test ob3 = new Test(-1, -1);
System.out.println("ob1==ob2: " + ob1.equals(ob2));
System.out.println("ob1==ob3: " + ob1.equals(ob3));
}
}
Passing Object to Constructor 1
A special case of object-passing is passing an object to the constructor.
class Box {
double width, height, depth;
Box(Box ob) {
width = ob.width;
height = ob.height;
depth = ob.depth;
}
Passing Object to Constructor 2
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
double volume() {
return width * height * depth;
}
}
Passing Object to Constructor 3
class OverloadCons2 {
public static void main(String args[]) {
Box mybox1 = new Box(10, 20, 15);
Box mybox2 = new Box(mybox1);
double vol;
vol = mybox1.volume();
System.out.println("Volume of mybox1 is " + vol);
vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol);
}
}
Argument-Passing
Two types of variables:
1) simple types
2) class types
class Test {
void meth(int i, int j) {
i *= 2;
j /= 2;
}
}
Simple Type Argument-Passing 2
With by-value argument-passing what occurs to the parameter that receives
the argument has no effect outside the method:
class CallByValue {
public static void main(String args[]) {
Test ob = new Test();
int a = 15, b = 20;
System.out.print("a and b before call: “);
System.out.println(a + " " + b);
ob.meth(a, b);
System.out.print("a and b after call: ");
System.out.println(a + " " + b);
}
}
Class Type Argument-Passing 1
Objects are passed to the methods by reference: a parameter obtains the
same address as the corresponding argument:
class Test {
int a, b;
Test(int i, int j) {
a = i; b = j;
}
void meth(Test o) {
o.a *= 2; o.b /= 2;
}
}
Class Type Argument-Passing 2
As the parameter hold the same address as the argument, changes to the
object inside the method do affect the object used by the argument:
class CallByRef {
public static void main(String args[]) {
Test ob = new Test(15, 20);
System.out.print("ob.a and ob.b before call: “);
System.out.println(ob.a + " " + ob.b);
ob.meth(ob);
System.out.print("ob.a and ob.b after call: ");
System.out.println(ob.a + " " + ob.b);
}
}
Returning Objects 1
So far, all methods returned no values or values of simple types.
class Test {
int a;
Test(int i) {
a = i;
}
Test incrByTen() {
Test temp = new Test(a+10);
return temp;
}
}
Returning Objects 2
Each time a method incrByTen is invoked a new object is created and a
reference to it is returned:
class RetOb {
public static void main(String args[]) {
Test ob1 = new Test(2);
Test ob2;
ob2 = ob1.incrByTen();
System.out.println("ob1.a: " + ob1.a);
System.out.println("ob2.a: " + ob2.a);
ob2 = ob2.incrByTen();
System.out.print("ob2.a after second increase: “);
System.out.println(ob2.a);
}
}
Recursion
A recursive method is a method that calls itself:
1) all method parameters and local variables are allocated on the stack
2) arguments are prepared in the corresponding parameter positions
3) the method code is executed for the new arguments
4) upon return, all parameters and variables are removed from the stack
5) the execution continues immediately after the invocation point
Example: Recursion
class Factorial {
int fact(int n) {
if (n==1) return 1;
return fact(n-1) * n;
}
}
class Recursion {
public static void main(String args[]) {
Factorial f = new Factorial();
System.out.print("Factorial of 5 is ");
System.out.println(f.fact(5));
}
}
Example: Recursion and Arrays 1
A method that recursively prints out a given number of elements in a table:
class RecTest {
int values[];
RecTest(int i) {
values = new int[i];
}
void printArray(int i) {
if (i==0) return;
else printArray(i-1);
System.out.print("[" + (i-1) + "] ");
System.out.println(values[i-1]);
}
}
Example: Recursion and Arrays 2
class Recursion2 {
public static void main(String args[]) {
RecTest ob = new RecTest(10);
int i;
for(i=0; i<10; i++)
ob.values[i] = i;
ob.printArray(10);
}
}
Arrays Revisited
All arrays are implemented as objects.
In particular, all arrays have the length attribute to return the number of
elements that an array may hold:
class Length {
public static void main(String args[]) {
int a1[] = new int[10];
int a2[] = {3, 5, 7, 1, 8, 99, 44, -10};
int a3[] = {4, 3, 2, 1};
System.out.println("length of a1 is " + a1.length);
System.out.println("length of a2 is " + a2.length);
System.out.println("length of a3 is " + a3.length);
}
}
Example: Arrays as Objects 1
An improved Stack example, able to handle stacks of any size:
class Stack {
private int stck[];
private int tos;
Stack(int size) {
stck = new int[size]; tos = -1;
}
System.out.println("Stack in mystack1:");
for (int i=0; i<5; i++)
System.out.println(mystack1.pop());
System.out.println("Stack in mystack2:");
for (int i=0; i<8; i++)
System.out.println(mystack2.pop());
}
}
Static Class Members
Normally, the members of a class (its variables and methods) may be only
used through the objects of this class.
1) variables
2) methods
3) initialization block
static int a;
static { … }
The block is executed exactly once, when the class is first loaded.
Example: Static 1
class UseStatic {
static int a = 3;
static int b;
static void meth(int x) {
System.out.print("x = " + x + “ a = “ + a);
System.out.println(“ b = " + b);
}
static {
System.out.println("Static block initialized.");
b = a * 4;
}
public static void main(String args[]) {
meth(42);
}
}
Static Member Usage 1
How to use static members outside their class?
class StaticDemo {
static int a = 42;
static int b = 99;
static void callme() {
System.out.println("a = " + a);
}
}
Static Member Usage 2
Static variables/method are used through the class name:
StaticDemo.a
StaticDemo.callme()
Example:
class StaticByName {
public static void main(String args[]) {
StaticDemo.callme();
System.out.println("b = " + StaticDemo.b);
}
}
Nested Classes
It is possible to define a class within a class – nested class.
The scope of the nested class is its enclosing class: if class B is defined
within class A then B is known to A but not outside.
Access rights:
class Outer {
int outer_x = 100;
void test() {
Inner inner = new Inner();
inner.display();
}
class Inner {
void display() {
System.out.println("outer_x = " + outer_x);
}
}
}
Example: Inner Classes 2
A demonstration class to create an object of the Outer class and invoke the
test method on this object:
class InnerClassDemo {
public static void main(String args[]) {
Outer outer = new Outer();
outer.test();
}
}
The Inner class is only known within the Outer class. Any reference to
Inner outside Outer will create a compile-time error.
Inner Members Visibility 1
Inner class has access to all member of the outer class.
The reverse is not true: members of the inner class are known only within
the scope of the inner class and may not be used by the outer class.
This is the Outer class with a variable, two methods and Inner class.
The first method refers to the Inner class correctly through an object:
class Outer {
int outer_x = 100;
void test() {
Inner inner = new Inner();
inner.display();
}
Inner Members Visibility 2
Inner class declares variable y and refers to the Outer class variable:
class Inner {
int y = 10;
void display() {
System.out.println("outer_x = " + outer_x);
}
}
void showy() {
System.out.println(y);
}
}
Inner Members Visibility 3
As a result, this program will not compile:
class InnerClassDemo {
public static void main(String args[]) {
Outer outer = new Outer();
outer.test();
}
}
Inner Class Declaration
So far, all inner classes were defined within the outer class scope.
class InnerClassDemo {
public static void main(String args[]) {
Outer outer = new Outer();
outer.test();
}
}
Exercise: Classes 1
1) What's the difference between an object and a class?
2) Explain why constructors don’t have return types.
3) Can this keyword be used within the context of a static method?. Why?.
4) What’s Overloading?
5) Explain the mechanism of Argument passing in Java. Is it by value or by
reference?
6) Explain the mechanism that Java uses to remove objects from memory
when they are no longer needed.
7) An object has a handle to some non-Java resources such as file or
window character font. How would you ensure that these resources are
freed before the object is destroyed?
Exercise: Classes 2
1) Create a class with a default constructor (no arguments) that prints a
message. Create an object of this class.
2) Add an overloaded constructor to the class in 1 which takes a String
argument and prints it along with your message.
3) Make a two dimensional array of objects of the class you created in 2.
4) Create a class Counter with an adequate data member. Write four
methods, one to get the value of the counter, one to increment the
counter, one to decrement the counter, and one to reset the counter to
zero. Make sure that the value of the counter never gets less than zero.
5) Create an object of your class Counter and assign it to two different
variables. Change the state of the object, calling your method on one
variable. See what happens if you call the get-value-method on the other
variable.
Course Outline
1) introduction 3) object-orientation 4) horizontal libraries
2) language a) objects a) string handling
a) syntax b) classes b) event handling
b) types c) inheritance c) object collections
c) variables d) polymorphism
5) vertical libraries
d) arrays e) access
a) graphical interface
e) operators f) interfaces
b) applets
f) control flow g) exception handling
c) input/output
h) multi-threading
d) networking
6) summary
Inheritance
One of the pillars of object-orientation.
void showi() {
System.out.println("i: " + i);
}
}
Example: Sub-Class
class B extends A {
int j;
void showj() {
System.out.println(“j: " + j);
}
void sum() {
System.out.println("i+j: " + (i+j));
}
}
Example: Testing Class
class SimpleInheritance {
public static void main(String args[]) {
A a = new A();
B b = new B();
a.i = 10;
System.out.println("Contents of a: ");
a.showi();
b.i = 7; b.j = 8;
System.out.println("Contents of b: ");
subOb.showi(); subOb.showj();
System.out.println("Sum of I and j in b:");
b.sum();
}
}
Inheritance and Private Members 1
A class may declare some of its members private.
class A {
int i;
private int j;
void setij(int x, int y) {
i = x; j = y;
}
}
Inheritance and Private Members 2
Class B has no access to the A’s private variable j.
class B extends A {
int total;
void sum() {
total = i + j;
}
}
Example: Box Class
The basic Box class with width, height and depth:
class Box {
double width, height, depth;
Box(double w, double h, double d) {
width = w; height = h; depth = d;
}
Box(Box b) {
width = b.width;
height = b.height; depth = b.depth;
}
double volume() {
return width * height * depth;
}
}
Example: BoxWeight Sub-Class
BoxWeight class extends Box with the new weight variable:
The following sub-class of Box adds the color attribute instead of weight:
class SuperClass { … }
class SubClass extends SuperClass { … }
SuperClass o1;
SubClass o2 = new SubClass();
o1 = o2;
o2 = o1
Example: Sub-Class Objects 1
class RefDemo {
public static void main(String args[]) {
BoxWeight weightbox = new BoxWeight(3, 5, 7, 8.37);
Box plainbox = new Box(5, 5, 5);
double vol;
vol = weightbox.volume();
System.out.print("Volume of weightbox is “);
System.out.println(vol);
System.out.print("Weight of weightbox is “);
System.out.println(weightbox.weight);
plainbox = weightbox;
vol = plainbox.volume();
System.out.println("Volume of plainbox is " + vol);
}
}
Super-Class Variable Access
plainbox variable now refers to the WeightBox object.
No. The type of a variable, not the object this variable refers to, determines
which members we can access!
This is illegal:
super(parameter-list);
class SuperClass { … }
BoxWeight(Box b, double w) {
super(b); weight = w;
}
}
Example: Super Constructor 2
class DemoSuper {
public static void main(String args[]) {
BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3);
BoxWeight mybox2 = new BoxWeight(mybox1, 10.5);
double vol;
vol = mybox1.volume();
System.out.println("Volume of mybox1 is " + vol);
System.out.print("Weight of mybox1 is “);
System.out.println(mybox1.weight);
vol = mybox2.volume();
System.out.println("Volume of mybox2 is " + vol);
System.out.print("Weight of mybox2 is “);
System.out.println(mybox2.weight);
}
}
Referencing Sub-Class Objects
Sending a sub-class object:
BoxWeight(Box b, double w) {
super(b); weight = w;
}
Uses of Super
Two uses of super:
super();
super.variable;
super.method(…);
When a sub-class declares the variables or methods with the same names
and types as its super-class:
class A {
int i = 1;
}
class B extends A {
int i = 2;
System.out.println(“i is “ + i);
}
class B extends A {
int i;
B(int a, int b) {
super.i = a; i = b;
}
void show() {
System.out.println("i in superclass: " + super.i);
System.out.println("i in subclass: " + i);
}
}
Example: Super and Hiding 2
Although the i variable in B hides the i variable in A, super allows access
to the hidden variable of the super-class:
class UseSuper {
public static void main(String args[]) {
B subOb = new B(1, 2);
subOb.show();
}
}
Multi-Level Class Hierarchy 1
The basic Box class:
class Box {
private double width, height, depth;
Box(double w, double h, double d) {
width = w; height = h; depth = d;
}
Box(Box ob) {
width = ob.width;
height = ob.height; depth = ob.depth;
}
double volume() {
return width * height * depth;
}
}
Multi-Level Class Hierarchy 2
Adding the weight variable to the Box class:
BoxWeight(BoxWeight ob) {
super(ob); weight = ob.weight;
}
}
Multi-Level Class Hierarchy 3
Adding the cost variable to the BoxWeight class:
Ship(Ship ob) {
super(ob); cost = ob.cost;
}
Ship(double w, double h,
double d, double m, double c) {
super(w, h, d, m); cost = c;
}
}
Multi-Level Class Hierarchy 4
class DemoShip {
public static void main(String args[]) {
Ship ship1 = new Ship(10, 20, 15, 10, 3.41);
Ship ship2 = new Ship(2, 3, 4, 0.76, 1.28);
double vol;
vol = ship1.volume();
System.out.println("Volume of ship1 is " + vol);
System.out.print("Weight of ship1 is”);
System.out.println(ship1.weight);
System.out.print("Shipping cost: $");
System.out.println(ship1.cost);
Multi-Level Class Hierarchy 5
vol = ship2.volume();
System.out.println("Volume of ship2 is " + vol);
System.out.print("Weight of ship2 is “);
System.out.println(ship2.weight);
System.out.print("Shipping cost: $“);
System.out.println(ship2.cost);
}
}
Constructor Call-Order
Constructor call-order:
class A {
A() {
System.out.println("Inside A's constructor.");
}
}
class B extends A {
B() {
System.out.println("Inside B's constructor.");
}
}
Example: Constructor Call-Order 2
class C extends B {
C() {
System.out.println("Inside C's constructor.");
}
}
class CallingCons {
public static void main(String args[]) {
C c = new C();
}
}
Exercise: Inheritance 1
1) Define a Class Building for building objects. Each building has a door
as one of its components.
a) In the class Door, model the fact that a door has a color and three
states, "open" , "closed", "locked“ and “unlocked". To avoid
illegal state changes, make the state private, write a method
(getState) that inspects the state and four methods (open, close,
lock and unlock) that change the state. Initialize the state to "closed"
in the constructor. Look for an alternative place for this initialization.
b) Write a method enter that visualizes the process of entering the
building (unlock door, open door, enter, ...) by printing adequate
messages, e.g. to show the state of the door.
c) Write a corresponding method quit that visualizes the process of
leaving the house. Don't forget to close and lock the door.
d) Test your class by defining an object of type Building and
visualizing the state changes when entering and leaving the building.
Exercise: Inheritance 2
3) Extend question 1 by introducing a subclass HighBuilding that
contains an elevator and the height of the building in addition to the
components of Building. Override the method enter to reflect the
use of the elevator. Define a constructor that takes the height of the
building as a parameter.
4) Define a subclass Skyscraper of HighBuilding, where the number
of floors is stored with each skyscraper.
What happens, if you don't define a constructor for class Skyscraper
(Try it)?
Write a constructor that takes the number of floors and the height as a
parameter. Test the class by creating a skyscraper with 40 floors and
using the inherited method enter.
& " $
Course Outline
1) introduction 3) object-orientation 4) horizontal libraries
2) language a) objects a) string handling
a) syntax b) classes b) event handling
b) types c) inheritance c) object collections
c) variables d) polymorphism
5) vertical libraries
d) arrays e) access
a) graphical interface
e) operators f) interfaces
b) applets
f) control flow g) exception handling
c) input/output
h) multi-threading
d) networking
6) summary
Inheritance and Reuse
Reuse of code: every time a new sub-class is defined, programmers are
reusing the code in a super-class.
What happens when a method is invoked using the base class reference?
The object responds in accordance with its true type.
What if the user pointed to a different form of object using the same
reference? The user would observe different behavior.
This is polymorphism.
Method Overriding
When a method of a sub-class has the same name and type as a method of
the super-class, we say that this method is overridden.
A(int a, int b) {
i = a; j = b;
}
void show() {
System.out.println("i and j: " + i + " " + j);
}
}
Example: Hiding with Overriding 2
class B extends A {
int k;
void show() {
System.out.println("k: " + k);
}
}
Example: Hiding with Overriding 3
When show() is invoked on an object of type B, the version of show()
defined in B is used:
class Override {
public static void main(String args[]) {
B subOb = new B(1, 2, 3);
subOb.show();
}
}
class B extends A {
int k;
B(int a, int b, int c) {
super(a, b);
k = c;
}
void show() {
super.show();
System.out.println("k: " + k);
}
}
The super-class version of show() is called within the sub-class’s version.
Overriding versus Overloading 1
Method overriding occurs only when the names and types of the two
methods (super-class and sub-class methods) are identical.
class A {
int i, j;
A(int a, int b) {
i = a; j = b;
}
void show() {
System.out.println("i and j: " + i + " " + j);
}
}
Overriding versus Overloading 2
The show() method in B takes a String parameter, while the show()
method in A takes no parameters:
class B extends A {
int k;
class Override {
public static void main(String args[]) {
B subOb = new B(1, 2, 3);
subOb.show("This is k: ");
subOb.show();
}
}
Dynamic Method Invocation
Overriding is a lot more than the namespace convention.
class A {
void callme() {
System.out.println("Inside A's callme method");
}
}
Example: Dynamic Invocation 2
Two sub-classes B and C:
class B extends A {
void callme() {
System.out.println("Inside B's callme method");
}
}
class C extends A {
void callme() {
System.out.println("Inside C's callme method");
}
}
class Dispatch {
public static void main(String args[]) {
A a = new A();
B b = new B();
C c = new C();
A r;
r = a; r.callme();
r = b; r.callme();
r = c; r.callme();
}
}
Polymorphism Again
One interface, many behaviors:
class Figure {
double dim1;
double dim2;
Figure(double a, double b) {
dim1 = a; dim2 = b;
}
double area() {
System.out.println("Area is undefined.");
return 0;
}
}
Example: Polymorphism 2
Rectangle is a sub-class of Figure:
Rectangle(double a, double b) {
super(a, b);
}
double area() {
System.out.println("Inside Area for Rectangle.");
return dim1 * dim2;
}
}
Example: Polymorphism 3
Triangle is a sub-class of Figure:
Triangle(double a, double b) {
super(a, b);
}
double area() {
System.out.println("Inside Area for Triangle.");
return dim1 * dim2 / 2;
}
}
Example: Polymorphism 4
Invoked through the Figure variable and overridden in their respective sub-
classes, the area() method returns the area of the invoking object:
class FindAreas {
public static void main(String args[]) {
Figure f = new Figure(10, 10);
Rectangle r = new Rectangle(9, 5);
Triangle t = new Triangle(10, 8);
Figure figref;
figref = r; System.out.println(figref.area());
figref = t; System.out.println(figref.area());
figref = f; System.out.println(figref.area());
}
}
Abstract Method
Inheritance allows a sub-class to override the methods of its super-class.
double area() {
System.out.println("Area is undefined.");
return 0;
}
abstract class A {
abstract void callMe();
}
abstract class A {
abstract void callme();
void callmetoo() {
System.out.println("This is a concrete method.");
}
}
class B extends A {
void callme() {
System.out.println("B's implementation.");
}
}
Abstract and Concrete Classes 2
Calling concrete and overridden abstract methods:
class AbstractDemo {
public static void main(String args[]) {
B b = new B();
b.callme();
b.callmetoo();
}
}
Example: Abstract Class 1
Figure is an abstract class; it contains an abstract area method:
Figure(double a, double b) {
dim1 = a; dim2 = b;
}
double area() {
System.out.println("Inside Area for Rectangle.");
return dim1 * dim2;
}
}
Example: Abstract Class 3
Triangle is concrete – it provides a concrete implementation for area:
double area() {
System.out.println("Inside Area for Triangle.");
return dim1 * dim2 / 2;
}
}
Example: Abstract Class 4
Invoked through the Figure variable and overridden in their respective sub-
classes, the area() method returns the area of the invoking object:
class AbstractAreas {
public static void main(String args[]) {
Rectangle r = new Rectangle(9, 5);
Triangle t = new Triangle(10, 8);
Figure figref;
figref = r; System.out.println(figref.area());
figref = t; System.out.println(figref.area());
}
}
Abstract Class References
It is illegal to create objects of the abstract class:
Figure figref;
class A {
final void meth() {
System.out.println("This is a final method.");
}
}
class B extends A {
void meth() {
System.out.println("Illegal!");
}
}
final and Early Binding
Two types of method invocation:
final class A { … }
class B extends A { … }
1) equals()
2) toString()
This way, classes can tailor the equality and the textual description of
objects to their own specific structure and needs.
Exercise: Polymorphism
1) Define a relationship among the following Building, HighBuilding
and Skyscraper classes.
3) Define a method that enters all the buildings in the street using the
method enter, one after another.
4) Fill the array with mixed objects from the classes Building,
HighBuilding and Skyscraper.
Make sure, that the output of your program visualizes the fact that
different method implementations are used depending on the type of the
actual object.
'
Course Outline
1) introduction 3) object-orientation 4) horizontal libraries
2) language a) objects a) string handling
a) syntax b) classes b) event handling
b) types c) inheritance c) object collections
c) variables d) polymorphism
5) vertical libraries
d) arrays e) access
a) graphical interface
e) operators f) interfaces
b) applets
f) control flow g) exception handling
c) input/output
h) multi-threading
d) networking
6) summary
Name Space Management
Classes written so far all belong to a single name space: a unique name has
to be chosen for each class to avoid name collision.
Java provides a mechanism for partitioning the class name space into more
manageable chunks. This mechanism is a package.
Package
A package is both a naming and a visibility control mechanism:
package myPackage;
class MyClass1 { … }
class MyClass2 { … }
means that all classes in this file belong to the myPackage package. The
package statement creates a name space where such classes are stored.
When the package statement is omitted, class names are put into the default
package which has no name.
Multiple Source Files
Other files may include the same package instruction:
package myPackage;
class MyClass1 { … }
class MyClass2 { … }
package myPackage;
class MyClass3{ … }
package myPackage;
class MyClass1 { … }
class MyClass2 { … }
package myPackage1.myPackage2.myPackage3;
1) Unix myPackage1/myPackage2/myPackage3
2) Windows myPackage1\myPackage2\myPackage3
3) Macintosh myPackage1:myPackage2:myPackage3
Two ways:
.;C:\myJava
package myPackage;
In order for a program to find myPackage, one of the following must be true:
class Balance {
String name;
double bal;
Balance(String n, double b) {
name = n; bal = b;
}
void show() {
if (bal<0) System.out.print("-->> ");
System.out.println(name + ": $" + bal);
}
}
Example: Package 2
class AccountBalance {
public static void main(String args[]) {
Balance current[] = new Balance[3];
java MyPack.AccountBalance
import myPackage1.myPackage2.myClass;
import myPackage1.myPackage2.*;
Access Control
Classes and packages are both means of encapsulating and containing the
name space and scope of classes, variables and methods:
class MyClass { … }
Access Control: Members
Four levels of access:
int variable;
int method(…) { … }
When a member does not have any access specification (default access), it
is visible to all classes within the same package.
To make a member visible outside the current package, but only to sub-
classes of the current class, declare this member protected.
Table: Access Control
private default protected public
same class yes yes yes yes
package p1;
package p1;
package p1;
class SamePackage {
SamePackage() {
Protection p = new Protection();
System.out.println("same package constructor");
System.out.println("n = " + p.n);
System.out.println("n_pro = " + p.n_pro);
System.out.println("n_pub = " + p.n_pub);
}
}
Example: Access 5
Protection2 is a sub-class of p1.Protection, but is located in a
different package – package p2.
package p2;
class OtherPackage {
OtherPackage() {
p1.Protection p = new p1.Protection();
System.out.println("other package constructor");
System.out.println("n_pub = " + p.n_pub);
}
}
Example: Access 7
A demonstration to use classes of the p1 package:
package p1;
package p2;
package myPackage;
import otherPackage1;otherPackage2.otherClass;
class myClass { … }
import java.lang.*;
This package includes the basic language functions. Without such functions,
Java is of no much use.
Name Conflict 1
Suppose a same-named class occurs in two different imported packages:
import otherPackage1.*;
import otherPackage2.*;
class myClass { … otherClass … }
package otherPackage1;
class otherClass { … }
package otherPackage2;
class otherClass { … }
Name Conflict 2
Compiler will remain silent, unless we try to use otherClass.
Then it will display an error message.
import otherPackage1.*;
import otherPackage2.*;
class myClass {
…
otherPackage1.otherClass
…
otherPackage2.otherClass
…
}
Short versus Full References
Short reference:
import java.util.*;
class MyClass extends Date { … }
Full reference:
Only the public components in imported package are accessible for non-
sub-classes in the importing code!
Example: Packages 1
A package MyPack with one public class Balance. The class has two
same-package variables: public constructor and a public show method.
package MyPack;
public class Balance {
String name;
double bal;
public Balance(String n, double b) {
name = n; bal = b;
}
public void show() {
if (bal<0) System.out.print("-->> ");
System.out.println(name + ": $" + bal);
}
}
Example: Packages 2
The importing code has access to the public class Balance of the
MyPack package and its two public members:
import MyPack.*;
class TestBalance {
public static void main(String args[]) {
Balance test = new Balance("J. J. Jaspers", 99.88);
test.show();
}
}
Java Source File
Finally, a Java source file consists of:
3) Define class Accessor2 outside the package. Again try to access all
methods and data members of the class AccessTest.
See what compiler messages you get.
Interface methods have no bodies – they end with the semicolon after the
parameter list. They are essentially abstract methods.
An interface may include variables, but they must be final, static and
initialized with a constant value.
If a class implements two interfaces that declare the same method, the
same method will be used by the clients of either interface.
The type signature of the implementing method must match exactly the type
signature specified in the interface definition.
Example: Interface
Declaration of the Callback interface:
interface Callback {
void callback(int param);
}
void nonIfaceMeth() {
System.out.println("Classes that implement “ +
“interfaces may also define ” +
“other members, too.");
}
}
Interface as a Type
Variable may be declared with interface as its type:
interface MyInterface { … }
…
MyInterface mi;
The variable of an interface type may reference an object of any class that
implements this interface.
interface MyInterface {
void myMethod(…) ;
…
}
class MyClass implements MyInterface { … }
…
MyInterface mi = new MyClass();
…
mi.myMethod();
The correct version of the method will be called based on the actual instance
of the interface being referred to.
Example: Call Through Interface 1
Declaration of the Callback interface:
interface Callback {
void callback(int param);
}
class TestIface {
public static void main(String args[]) {
Callback c = new Client();
c.callback(42);
}
}
Call Through Interface Variable 2
Call through an interface variable is one of the key features of interfaces:
Allows classes to be created later than the code that calls methods on them.
Example: Interface Call 1
Another implementation of the Callback interface:
class TestIface2 {
public static void main(String args[]) {
Callback c = new Client();
c.callback(42);
AnotherClient ob = new AnotherClient();
c = ob;
c.callback(42);
}
}
Compile-Time Method Binding
Normally, in order for a method to be called from one class to another, both
classes must be present at compile time.
This implies:
interface IntStack {
void push(int item);
int pop();
}
FixedStack(int size) {
stck = new int[size]; tos = -1;
}
Example: FixedStack 2
public void push(int item) {
if (tos==stck.length-1)
System.out.println("Stack is full.");
else stck[++tos] = item;
}
class IFTest {
public static void main(String args[]) {
FixedStack mystack1 = new FixedStack(5);
FixedStack mystack2 = new FixedStack(8);
Example: FixedStack 4
It pushes and them pops off some values from those stacks:
System.out.println("Stack in mystack1:");
for (int i=0; i<5; i++)
System.out.println(mystack1.pop());
System.out.println("Stack in mystack2:");
for (int i=0; i<8; i++)
System.out.println(mystack2.pop());
}
}
Example: DynStack 1
Another implementation of an integer stack.
DynStack(int size) {
stck = new int[size];
tos = -1;
}
Example: DynStack 2
If stack if full, push creates a new stack with double the size of the old stack:
class IFTest2 {
public static void main(String args[]) {
DynStack mystack1 = new DynStack(5);
DynStack mystack2 = new DynStack(8);
Example: DynStack 5
It then pushes some numbers onto those stacks, dynamically increasing
their size, then pops those numbers off:
System.out.println("Stack in mystack1:");
for (int i=0; i<12; i++)
System.out.println(mystack1.pop());
System.out.println("Stack in mystack2:");
for (int i=0; i<20; i++)
System.out.println(mystack2.pop());
}
}
Example: Two Stacks 1
Testing two stack implementations through an interface variable.
class IFTest3 {
public static void main(String args[]) {
IntStack mystack;
DynStack ds = new DynStack(5);
FixedStack fs = new FixedStack(8);
mystack = ds;
for (int i=0; i<12; i++) mystack.push(i);
mystack = fs;
for (int i=0; i<8; i++) mystack.push(i);
Example: Two Stacks 2
Then, those numbers are popped off:
mystack = ds;
System.out.println("Values in dynamic stack:");
for (int i=0; i<12; i++)
System.out.println(mystack.pop());
mystack = fs;
System.out.println("Values in fixed stack:");
for (int i=0; i<8; i++)
System.out.println(mystack.pop());
}
}
As no methods are included in the interface, the class does not implement
anything except importing the variables as constants.
Example: Interface Variables 1
An interface with constant values:
import java.util.Random;
interface SharedConstants {
int NO = 0;
int YES = 1;
int MAYBE = 2;
int LATER = 3;
int SOON = 4;
int NEVER = 5;
}
Example: Interface Variables 2
Question implements SharedConstants, including all its constants.
interface MyInterface1 {
void myMethod1(…) ;
}
interface MyInterface2 extends MyInterface1 {
void myMethod2(…) ;
}
interface A {
void meth1();
void meth2();
}
B extends A:
interface B extends A {
void meth3();
}
Example: Interface Inheritance 2
MyClass must implement all of A and B methods:
class IFExtend {
public static void main(String arg[]) {
MyClass ob = new MyClass();
ob.meth1();
ob.meth2();
ob.meth3();
}
}
Exercise: Interface
1) Define two interfaces:
a) an interface CardUse for card use with methods read to read the
state and reduceBy with a parameter amount to change the state of
the card. The user has to identify himself by a PIN for this operation;
b) an interface CardChange for the administration of the card by
authorized people, that need a method reset to reset the card
state, a method fill to fill the card with an amount of money and a
method changePIN to change the PIN for the card.
2) Define a third interface CardAll that includes all card operation (Use
inheritance).
In contrast, Java:
Fundamental errors that violate the rules of the Java language or the
constraints of the Java execution environment.
try { … }
catch(Exception1 ex1) { … }
catch(Exception2 ex2) { … }
…
finally { … }
where:
class Exc0 {
public static void main(String args[]) {
int d = 0;
int a = 42 / d;
}
}
When the Java run-time system detects the attempt to divide by zero, it
constructs a new exception object and throws this object.
This will cause the execution of Exc0 to stop – once an exception has been
thrown it must be caught by an exception handler and dealt with.
Default Exception Handler
As we have not provided any exception handler, the exception is caught by
the default handler provided by the Java run-time system.
java.lang.ArithmeticException: / by zero
at Exc0.main(Exc0.java:4)
Any exception not caught by the user program is ultimately processed by the
default handler.
Stack Trace Display
The stack trace displayed by the default error handler shows the sequence
of method invocations that led up to the error.
class Exc1 {
static void subroutine() {
int d = 0;
int a = 10 / d;
}
public static void main(String args[]) {
Exc1.subroutine();
}
}
Own Exception Handling
Default exception handling is basically useful for debugging.
try {
d = 0;
a = 42 / d;
System.out.println("This will not be printed.");
}
Try and Catch 2
control moves immediately to the catch block:
catch (ArithmeticException e) {
System.out.println("Division by zero.");
}
try { … }
catch (ArithmeticException e) { … }
System.out.println("After catch statement.");
Not with the next statement after a = 42/d; which caused the exception!
a = 42 / d;
System.out.println("This will not be printed.");
Catch and Continue 1
The purpose of catch should be to resolve the exception and then continue
as if the error had never happened.
import java.util.Random;
class HandleError {
public static void main(String args[]) {
int a=0, b=0, c=0;
Random r = new Random();
Catch and Continue 2
After exception-handling, the program continues with the next iteration:
try { … }
catch (ArithmeticException e) {
System.out.println(“Exception: “ + e);
}
class MultiCatch {
public static void main(String args[]) {
try {
int a = args.length;
System.out.println("a = " + a);
int b = 42 / a;
int c[] = { 1 };
c[42] = 99;
}
Example: Multiple Catch 2
Both exceptions can be caught by the following catch clauses:
catch(ArithmeticException e) {
System.out.println("Divide by 0: " + e);
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Array index oob: " + e);
}
System.out.println("After try/catch blocks.");
}
}
Order of Multiple Catch Clauses
Order is important:
class SuperSubCatch {
public static void main(String args[]) {
try {
int a = 0;
int b = 42 / a;
} catch(Exception e) {
System.out.println("Generic Exception catch.");
}
Example: Multiple Catch Order 2
This exception is more specific but occurs last:
catch(ArithmeticException e) {
System.out.println("This is never reached.");
}
}
}
class NestTry {
public static void main(String args[]) {
try {
int a = args.length;
int b = 42 / a;
System.out.println("a = " + a);
Example: Nested try 2
Inner try statement:
try {
if (a==1) a = a/(a-a);
Array index out of bound when two command-line arguments are present:
if (a==2) {
int c[] = { 1 };
c[42] = 99;
}
Example: Nested try 3
Catch statement for the inner try statement, catches the array index out of
bound exception:
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println(e);
}
Catch statement for the outer try statement, catches both division-by-zero
exceptions for the inner and outer try statements:
} catch(ArithmeticException e) {
System.out.println("Divide by 0: " + e);
}
}
}
Method Calls and Nested try 1
Nesting of try statements with method calls:
Still, the try blocks are considered nested within each other.
class MethNestTry {
Method Calls and Nested try 2
Method nesttry contains the try statement:
throw ThrowableInstance;
throw ThrowableInstance;
try { … } catch(Throwable e) { … e … }
Example: throw 1
class ThrowDemo {
class ThrowsDemo {
static void throwOne() {
System.out.println("Inside throwOne.");
throw new IllegalAccessException("demo");
}
public static void main(String args[]) {
throwOne();
}
}
class ThrowsDemo {
static void throwOne() throws IllegalAccessException {
System.out.println("Inside throwOne.");
throw new IllegalAccessException("demo");
}
public static void main(String args[]) {
try {
throwOne();
} catch (IllegalAccessException e) {
System.out.println("Caught " + e);
}
}
}
Motivating finally
When an exception is thrown:
For instance, if a method opens a file on entry and closes on exit; exception
handling should not bypass the proper closure of the file.
try { … }
catch(Exception1 ex1) { … } …
finally { … }
Any time a method is to return to a caller from inside the try/catch block via:
1) uncaught exception or
2) explicit return
class FinallyDemo {
MyException need not implement anything – its mere existence in the type
system allows to use its objects as exceptions.
Throwable Class 1
Exception itself is a sub-class of Throwable.
All user exceptions have the methods defined by the Throwable class:
MyException(int a) {
detail = a;
}
Throwable(Throwable causeExc)
Throwable(String msg, Throwable causeExc)
They both create an exception with causeExc being its underlying reason
and optional msg providing the textual description.
Chained Exceptions 2
Throwable class also includes two methods to handle chained exceptions:
Java provides a clean and powerful way to handle errors and unusual
boundary conditions through its:
1) try
2) catch
3) finally
4) throw and
5) throws statements.
1) process-based multi-tasking
2) thread-based multi-tasking
1) the transmission rate of data over a network is much slower than the rate
at which the computer can process it
2) local file system resources can be read and written at a much slower rate
than can be processed by the CPU
3) of course, user input is much slower than the computer
Single-Threading
In a single-threaded environment, the program has to wait for each of these
tasks to finish before it can proceed to the next.
1) ready to run
2) running
3) a running thread can be suspended
4) a suspended thread can be resumed
5) a thread can be blocked when waiting for a resource
6) a thread can be terminated
When two equal-priority threads are competing for CPU time, which one is
chosen depends on the operating system.
Threads: Synchronization
Multi-threading introduces asynchronous behavior to a program. How to
ensure synchronous behavior when we need it?
For instance, how to prevent two threads from simultaneously writing and
reading the same object?
1) is invoked automatically
2) is the first to start and the last to finish
3) is the thread from which other “child” threads will be spawned
method of Thread.
Example: Main Thread 1
class CurrentThreadDemo {
public static void main(String args[]) {
The main thread is obtained, displayed, its name changed and re-displayed:
Thread t = Thread.currentThread();
System.out.println("Current thread: " + t);
t.setName("My Thread");
System.out.println("After name change: " + t);
Example: Main Thread 2
A loop performs five iterations pausing for a second between the iterations.
It is performed within the try/catch block – the sleep method may throw
InterruptedException if some other thread wanted to interrupt:
try {
for (int n = 5; n > 0; n--) {
System.out.println(n);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted");
}
}
}
Example: Thread Methods
Thread methods used by the example:
1) create a class that implements the run method (inside this method, we
define the code that constitutes the new thread):
void start()
Example: New Thread 1
A class NewThread that implements Runnable:
NewThread() {
t = new Thread(this, "Demo Thread");
System.out.println("Child thread: " + t);
t.start();
}
Example: New Thread 2
This is the entry point for the newly created thread – a five-iterations loop
with a half-second pause between the iterations all within try/catch:
new NewThread();
try {
for (int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
New Thread: Extend Thread
The second way to create a new thread:
NewThread() {
super("Demo Thread");
System.out.println("Child thread: " + this);
start();
}
Example: New Thread 2
NewThread overrides the Thread’s run method:
new NewThread();
try {
for (int i = 5; i > 0; i--) {
System.out.println("Main Thread: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
New Thread: Which Approach?
The Thread class defines several methods that can be overriden.
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start();
}
Example: Multiple Threads 2
Here is the implementation of the run method:
class MultiThreadDemo {
public static void main(String args[]) {
new NewThread("One");
new NewThread("Two");
new NewThread("Three");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
Using isAlive and join Methods
How can one thread know when another thread has ended?
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start();
}
Example: isAlive and join 2
Here is the new thread’s run method:
System.out.println(ob1.t.isAlive());
System.out.println(ob2.t.isAlive());
System.out.println(ob3.t.isAlive());
Example: isAlive and join 4
Waiting until all three threads have finished:
try {
System.out.println("Waiting to finish.");
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
Example: isAlive and join 5
Testing again if the new threads are still alive:
System.out.println(ob1.t.isAlive());
System.out.println(ob2.t.isAlive());
System.out.println(ob3.t.isAlive());
In practice, the amount of CPU time that a thread gets depends on several
factors besides its priority.
Setting and Checking Priorities
Setting thread’s priority:
1) MIN_PRIORITY (1)
2) MAX_PRIORITY (10)
3) NORM_PRIORITY (5)
public Clicker(int p) {
t = new Thread(this);
t.setPriority(p);
}
Example: Priorities 2
When running, click is incremented. When stopped, running is false:
The main thread is set at the highest priority, the new threads at two above
and two below the normal priority:
Thread.currentThread().
setPriority(Thread.MAX_PRIORITY);
clicker hi = new clicker(Thread.NORM_PRIORITY + 2);
clicker lo = new clicker(Thread.NORM_PRIORITY - 2);
Example: Priorities 4
The threads are started and allowed to run for 10 seconds:
lo.start();
hi.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
Example: Priorities 5
After 10 seconds, both threads are stopped and click variables printed:
lo.stop();
hi.stop();
try {
hi.t.join();
lo.t.join();
} catch (InterruptedException e) {
System.out.println("InterruptedException");
}
This is to ensure that the value of running is examined at each iteration of:
while (running) {
click++;
}
Otherwise, Java is free to optimize the loop in such a way that a local copy
of running is created. The use of volatile prevents this optimization.
Synchronization
When several threads need access to a shared resource, they need some
way to ensure that the resource will be used by only one thread at a time.
While a thread is inside a monitor, all threads that try to call this or any other
synchronized method on this object have to wait.
class Callme {
void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println("]");
}
}
Example: No Synchronization 2
Caller constructor obtains references to the Callme object and String,
stores them in the target and msg variables, then creates a new thread:
class Synch {
public static void main(String args[]) {
Callme target = new Callme();
Caller ob1 = new Caller(target, "Hello");
Caller ob2 = new Caller(target, "Synchronized");
Caller ob3 = new Caller(target, "World");
Example: No Synchronization 5
Waiting for all three threads to finish:
try {
ob1.t.join();
ob2.t.join();
ob3.t.join();
} catch(InterruptedException e) {
System.out.println("Interrupted");
}
}
}
No Synchronization
Output from the earlier program:
[Hello[Synchronized[World]
]
]
By pausing for one second, the call method allows execution to switch to
another thread. A mix-up of the outputs from of the three message strings.
In this program, nothing exists to stop all three threads from calling the same
method on the same object at the same time.
Synchronized Method
To fix the earlier program, we must serialize the access to call:
class Callme {
synchronized void call(String msg) {
…
}
}
This prevents other threads from entering call while another thread is using
it. The output result of the program is now as follows:
[Hello]
[Synchronized]
[World]
Synchronized Statement
How to synchronize access to instances of a class that was not designed for
multithreading and we have no access to its source code?
Put calls to the methods of this class inside the synchronized block:
synchronized(object) {
…
}
This ensures that a call to a method that is a member of the object occurs
only after the current thread has successfully entered the object’s monitor.
Example: Synchronized 1
Now the call method is not modified by synchronized:
class Callme {
void call(String msg) {
System.out.print("[" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
System.out.println("]");
}
}
Example: Synchronized 2
class Caller implements Runnable {
String msg;
Callme target;
Thread t;
class Q {
int n;
class PC {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}
Why Incorrect?
Here is the output:
Put: 1
Got: 1
Got: 1
Put: 2
Put: 3
Get: 3
…
Nothing stops the producer from overrunning the consumer, nor the
consumer from consuming the same data twice.
Example: Corrected Queue 1
The correct producer-consumer system uses wait and notify to
synchronize the behavior of the producer and consumer.
class Q {
int n;
boolean valueSet = false;
Example: Corrected Queue 2
Inside get, wait is called to suspend the execution of Consumer until
Producer notifies that some data is ready:
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
Example: Corrected Queue 6
Producer creates a thread that keeps producing entries for the queue:
class PCFixed {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}
Deadlock
Multi-threading and synchronization create the danger of deadlock.
Suppose that:
1) one thread enters the monitor on object X
2) another thread enters the monitor on object Y
3) the first thread tries to call a synchronized method on object Y
4) the second thread tries to call a synchronized method on object X
class A {
synchronized void foo(B b) {
String name = Thread.currentThread().getName();
System.out.println(name + " entered A.foo");
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("A Interrupted");
}
System.out.println(name + " trying B.last()");
b.last();
}
Example: Deadlock 2
Class A also contains the synchronized method last:
class B {
synchronized void bar(A a) {
String name = Thread.currentThread().getName();
System.out.println(name + " entered B.bar");
try {
Thread.sleep(1000);
} catch(Exception e) {
System.out.println("B Interrupted");
}
System.out.println(name + " trying A.last()");
a.last();
}
Example: Deadlock 4
Class B also contains the synchronized method last:
A a = new A();
B b = new B();
Example: Deadlock 6
The constructor creates and starts a new thread, and creates a lock on the a
object in the main thread (running foo on a) with b passed as a parameter:
Deadlock() {
Thread.currentThread().setName("MainThread");
Thread t = new Thread(this, "RacingThread");
t.start();
a.foo(b);
System.out.println("Back in main thread");
}
Example: Deadlock 7
The run method creates a lock on the b object in the new thread (running
bar on b) with a passed as a parameter:
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start();
}
Example: Suspending/Resuming 2
The run method contains the synchronized statement that checks
suspendFlag. If true, the wait method is called.
void mysuspend() {
suspendFlag = true;
}
class SuspendResume {
The two threads are kept running, then suspended, then resumed from the
main thread:
Example: Suspending/Resuming 6
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming thread One");
ob2.mysuspend();
System.out.println("Suspending thread Two");
Thread.sleep(1000);
ob2.myresume();
System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
Example: Suspending/Resuming 7
The main thread waits for the two child threads to finish, then finishes itself:
try {
System.out.println("Waiting to finish.");
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
The Last Word on Multi-Threading
Multi-threading is a powerful tool to writing efficient programs.
When you have two subsystems within a program that can execute
concurrently, make them individual threads.
However, creating too many threads can actually degrade the performance
of your program because of the cost of context switching.
Exercise: Multi-Threading 1
1) Create a new main class called MultiThread
2) Create a new class called MemoryThread . This class should
implement the interface Runnable so that it can be run as a thread.
This Thread will monitor the memory usage on the system.
a) Add void start(), stop() and run() methods.
b) The run() method should print to the screen every 5 seconds the
amount of memory presently being used. This can be done using
these two lines of code:
Runtime r = Runtime.getRuntime();
long memoryUsed = r.totalMemory()- r.freeMemory();
This is not a restriction. It means each time you need an altered version of an
existing string, a new string object is created that contains the modification.
Example:
char chars[] = {‘a’,’b’,’c’};
String s = new String(chars);
String Constructors 2
3) to create a string as a subrange of a character array
String(char chars[], int startindex, int numchars)
Example:
char chars[] = {‘a’,’b’,’c’,’d’,’e’,’f’};
String s = new String(chars,2,3);
The following fragment prints “3”, since there are three characters in the
string s.
Java provides several string operations within the syntax of the language.
There are explicit methods to perform all these functions, but Java does them
automatically for the convenience of the programmer and to add clarity.
String Literals
Using String literals is an easier way of creating Strings Objects.
Example:
char chars[] = {‘a’,’b’,’c’};
String s1 = new String(chars);
Example:
General form:
char charAt(int where)
where is the index of the character you want to obtain. The value of where
must be nonnegative and specify alocation within the string.
Example:
char ch;
ch = “abc”.charAt(1);
Assigns a value of “b” to ch.
getChars()
Used to extract more than one character at a time.
General form:
void getChars(int sourceStart, int sourceEnd, char[]
target, int targetStart)
General form:
byte[] getBytes()
Usage:
Most useful when you are exporting a String value into an environment that
does not support 16-bit Unicode characters.
For example, most internet protocols and text file formats use 8-bit ASCII for
all text interchange.
toCharArray()
To convert all the characters in a String object into character array.
It returns an array of characters for the entire string.
General form:
char[] toCharArray()
General form:
boolean equals(Object str)
str is the String object being compared with the invoking String object.
It returns true if the string contain the same character in the same order, and
false otherwise.
General form:
boolean equalsIgnoreCase(Object str)
str is the String object being compared with the invoking String object.
It returns true if the string contain the same character in the same order,
and false otherwise.
General form:
boolean regionMatches(int startindex, String str2,
int str2StartIndex, int numChars)
The index at which the comparison will start within str2 is specified by
str2StartIndex.
The length of the substring being comapred is passed in numChars.
General form:
boolean startsWith(String str)
boolean endsWith(String str)
str is the String being tested. If the string matches, true is returned,
otherwise false is returned.
startsWith() and endsWith() 2
Example:
“Foobar”.endsWith(“bar”);
and
“Foobar”.startsWith(“Foo”);
are both true.
startsWith() and endsWith() 3
A second form of startsWith(), let you specify a starting point:
General form:
boolean startWith(String str, int startIndex)
Where startIndex specifies the index into the invoking string at which
point the search will begin.
Example:
“Foobar”.startsWith(“bar”, 3);
returns true.
equals() Versus ==
It is important to understand that the two metyhod performs different
functions.
A string is less than the another if it comes before the other in the dictionary
order.
A string is greater than the another if it comes after the other in the dictionary
order.
str is the string that is being compared with the invoking String. The result
of the comparison is returned and is interpreted as shown here:
These two methods are overloaded in several different ways. In all cases, the
methods return the index at which the character or substring was found, or
-1 on failure.
Searching String 2
To seach for the first occurrence of a character, use
To search for the first and the last occurence of a substring, use
int indexOf(String str)
int lastIndexOf(String str)
Here str specifies the substring.
Searching String 3
You can specify a starting point for the serach using these forms:
For indexOf(), the search runs from startIndex to the end of the string.
For lastIndexOf(), the search runs from startIndex to zero.
Example: Searching String 1
class indexOfDemo {
public static void main(String args[]) {
String s = "Now is the time for all good men " +
"to come to the aid of their country.";
System.out.println(s);
System.out.println("indexOf(t) = " +
s.indexOf('t'));
System.out.println("lastIndexOf(t) = " +
s.lastIndexOf('t'));
System.out.println("indexOf(the) = " +
s.indexOf("the"));
System.out.println("lastIndexOf(the) = " +
s.lastIndexOf("the"));
Example: Searching String 2
System.out.println("indexOf(t, 10) = " +
s.indexOf('t', 10));
System.out.println("lastIndexOf(t, 60) = " +
s.lastIndexOf('t', 60));
System.out.println("indexOf(the, 10) = " +
s.indexOf("the", 10));
System.out.println("lastIndexOf(the, 60) = " +
s.lastIndexOf("the", 60));
}
}
Modifying a String
String object are immutable.
Whenever you want to modify a String, you must either copy it into a
StringBuffer or use the following String methods,, which will construct a new
copy of the string with your modification complete.
They are:
1) subString()
2) concat()
3) replace()
4) trim()
startIndex specifies the index at which the substring will begin. This form
returns a copy of the substring that begins at startIndex and runs to the end
of the invoking string.
subString() 2
The second form allows you to specify both the beginning and ending index
of the substring.
This method creates a new object that contains the invoking string with the
contents of str appended to the end.
Example:
String s = “Hello”.replace(‘l’,’w’);
General form:
String trim();
Example:
String s = “ Hello world “.trim();
IOException{
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
String str;
System.out.println("Enter 'stop' to quit.");
System.out.println("Enter State: ");
do {
str = br.readLine();
Example: trim() 2
str = str.trim(); // remove whitespace
if(str.equals("Illinois"))
System.out.println("Capital is pringfield.");
else if(str.equals("Missouri"))
System.out.println("Capital is Jefferson
City.");
else if(str.equals("California"))
System.out.println("Capital is Sacramento.");
else if(str.equals("Washington"))
System.out.println("Capital is Olympia.");
} while(!str.equals("stop"));
}
}
Data Conversion Using valueOf()
Converts data from its internal format into human-readable form.
It is a static method that is overloaded within String for all of Java’s built-in
types, so that each of the type can be converted properly into a String.
General forms:
static String valueOf(double num)
static String valueOf(long num)
static String valueOf(Object obj)
static String valueOf(char chars[])
Case of Characters
The method toLowerCase() converts all the characters in a string from
uppercase to lowercase.
General form:
String toLowercase()
String toUppercase()
Example: Case of Characters
class ChangeCase {
public static void main(String args[]) {
String s = "This is a test.";
System.out.println("Original: " + s);
String upper = s.toUpperCase();
String lower = s.toLowerCase();
System.out.println("Uppercase: " + upper);
System.out.println("Lowercase: " + lower);
}
}
StringBuffer
StringBuffer is a peer class of string that provides much of the
functionality of Strings.
General form:
int length()
Int capacity()
Example: Length() and capacity()
class StringBufferDemo {
public static void main(String args[]) {
StringBuffer sb = new StringBuffer("Hello");
General form:
Usage:
Useful if you know in advance that you ill be appending a large number of
small strings to a StringBuffer.
setLength()
To set the length of the buffer within a StringBuffer object.
General form:
void setlengthint len)
Here, len specifies the lenght of the buffer.
Usage:
When you increase the length of the buffer, null characters are added to the
end of the existing buffer. If you call setLength() with a value less than the
current value returned by length(), then the characters stored beyond the
new length will be lost.
charAt() and setCharAt()
To obtain the value of a single character, use CharAt().
To set the value of a character within StringBuffer, use setCharAt().
General form:
char charAt(int where)
void setCharAt(int where, char ch)
For charAt(), where specifies the index of the characters being obtained.
For setCharAt(), where specifies the index of the characters being set,
and ch specifies the new value of that character.
where must be non negative and must not specify a location beyond the end
of the buffer.
Example:charAt() and setCharAt()
class setCharAtDemo {
public static void main(String args[]) {
StringBuffer sb = new StringBuffer("Hello");
System.out.println("buffer before = " + sb);
System.out.println("charAt(1) before = " +
sb.charAt(1));
sb.setCharAt(1, 'i');
sb.setLength(2);
System.out.println("buffer after = " + sb);
System.out.println("charAt(1) after = " +
sb.charAt(1));
}
}
getChars()
To copy a substring of a StringBuffer into an array.
General form:
void getChars(int srcBegin, int srcEnd, char[] dst,
int dstBegin)
Where:
srcBegin - start copying at this offset.
srcEnd - stop copying at this offset.
dst - the array to copy the data into.
dstBegin - offset into dst.
append()
Concatenates the string representation of any other type of data to the end of
the invoking StringBuffer object.
General form:
StringBuffer append(Object obj)
StringBuffer append(String str)
StringBuffer append(int num)
").append(a).append("!").toString();
System.out.println(s);
}
}
insert()
Inserts one string into another. It is overloaded to accept values of all the
simple types, plus String and Objects.
General form:
StringBuffer insert(int index, String str)
StringBuffer insert(int index, char ch)
StringBuffer insert(int index, Object obj)
Here, index specifies the index at which point the String will be inserted
into the invoking StringBuffer object.
Example: insert()
class insertDemo {
public static void main(String args[]) {
StringBuffer sb = new StringBuffer("I Java!");
General form:
StringBuffer replace(int startIndex, String endIndex,
String str)
test.");
sb.replace(5, 7, "was");
System.out.println("After replace: " + sb);
}
}
substring()
Returns a portion of a StringBuffer.
General form:
String substring(int startIndex)
String substring(int startIndex, int endIndex)
The first form returns the substring that starts at startIndex and runs to
the end of the invoking StringBuffer object.
The second form returns the substring that starts at startIndex and runs
through endIndex-1.
These methods work just llike those defined for String that were
described earlier.
Exercise: String Handling
1.) Write a program that computes your initials from your full name and
displays them.
3.) Write a program to read English text to end-of-data, and print a count of
word lengths, i.e. the total number of words of length 1 which occurred,
the number of length 2, and so on.
Type in question 3 as input to test your program.
1) Visual Basic
a) Each component responds to a fixed set of events
2) C
a) A giant loop with a massive switch statement
3) Java
a) Event delegation model – events are transmitted from event
sources to event listeners
b) You can designate any object to be an event listener
Event Handling Components 1
Event handling involves three components:
1) listener object is an instance of a class that implements a special
interface called a listener interface.
2) event source is an object that can register listener objects and send
them event objects
3) event source sends out event objects to all registered listeners
when that event occurs.
eventSourceObject.addEventListener(eventListenerObject);
For example
ActionListener listener = …;
JButton button = new JButton(“OK”);
button.addActionListener(listener);
For Example:
class MyListener implements ActionListener {
...
public void actionPerformed(ActionEvent event)
{
// reaction to button click goes here
...
}
}
Event Handling Process 3
Whenever the user clicks the button,
new
JButton
new
addActionListener
MyListener
actionPerformed
Event and Listener Objects
Different event sources can produce different kinds of events
Component
Container
JComponent Window
JFrame
JButton
Example: JButton Event 1
class ButtonPanel extends JPanel {
public ButtonPanel( ) {
JButton yellowButton = new JButton(“Yellow");
JButton blueButton = new JButton(“Blue");
JButton redButton = new JButton(“Red");
add(yellowButton);
add(blueButton);
add(redButton);
}
}
Constructors – button with a label string, an icon, or both a label string and
an icon
JButton blueButton = new JButton(“Blue");
JButton blueButton = new JButton(new ImageIcon(“blue-
ball.gif”));
Example: JButton Event 2
Example: JButton Event 3
Event Hierarchy 1
All events in Java descend from the EventObject class in the java.util
package
Key Mouse
Event Event
MouseWheel
Event
Example: AWT Event Objects
Commonly used AWT event types
1) ActionEvent
2) AdjustmentEvent
3) FocusEvent
4) ItemEvent
5) KeyEvent
6) MouseEvent
7) MouseWheelEvent
8) WindowEvent
Example: AWT Listener Interfaces
The following interfaces listen to these events
1) ActionListener
2) AdjustmentListener
3) FocusListener
4) ItemListener
5) KeyListener
6) MouseListener
7) MouseMotionListener
8) MouseWheelListener
9) WindowListener
10) WindowFocusListener
11) WindowStateListener
Adapter Classes
Adapter Class exists as convenience for creating a listener object.
Extend this class to create a listener for a particular listener interface and
override the methods for the events of interest.
It defines null methods for all of the methods in the listener interface, so
you can only have to define methods for events you care about.
<<implements>>
Listener
Interface
Implementation:
Exercise: Event Handling
1) What listener would you implement to be notified when a particular
component has appeared on screen? What method tells you this
information?
2) What listener would you implement to be notified when the user has
finished editing a text field by pressing Enter?
3) What listener would you implement to be notified as each character is
typed into a text field? Note that you should not implement a general-
purpose key listener, but a listener specific to text.
4) What listener would you implement to be notified when a spinner’s value
has changed? How would you get the spinner’s new value?
5) The default behavior for the focus subsystem is to consume the focus
traversal keys, such as Tab and Shift Tab. Say you want to prevent this
from happening in one of your application’s components. How would you
accomplish this?
4+7 5
Course Outline
1) introduction 3) object-orientation 4) horizontal libraries
2) language a) objects a) string handling
a) syntax b) classes b) event handling
b) types c) inheritance c) object collections
c) variables d) polymorphism
5) vertical libraries
d) arrays e) access
a) graphical interface
e) operators f) interfaces
b) applets
f) control flow g) exception handling
c) input/output
h) multi-threading
d) networking
6) summary
Overview 1
1) Introduction - tells you what collections are, and how they will make your
job easier and your programs better.
2) Interfaces - describes the core collection interfaces, which are the heart
and soul of the Java Collections Framework. You will learn:
a) general guidelines for effective use of these interfaces, including
when to use which interface
b) idioms for each interface that will help you get the most out of the
interfaces.
Overview 2
3) Implementations - describes the JDK's general-purpose collection
implementations and tells you when to use which implementation.
Usage:
1) to store and retrieve data
2) to manipulate data
3) to transmit data from one method to another
Collections typically represent data items that form a natural group like:
1) a poker hand (a collection of cards)
2) a mail folder (a collection of letters)
3) a telephone directory (a collection of name-to-phone-number mappings)
Collection Framework 1
A collections framework is a unified architecture for representing and
manipulating collections.
3) Algorithms
a) methods that perform useful computations like searching and
sorting, on objects that implement collection interfaces.
b) they are polymorphic because the same method can be used on
many different implementations of the appropriate collections
interface.
c) In essence, they are reusable functionality.
Collection Framework 3
Benefits 1
Collection Framework offers the following benefits:
Purpose:
1)To allow collections to be manipulated independently of the details of
their representation.
Note:
1) They are the heart and soul of the collections framework.
2) When you understand how to use these interfaces, you know most of
what there is to know about the framework.
Core Collection Interfaces 2
The core collections interfaces are shown below:
Core Collection Interfaces 3
There are four basic core collection interfaces:
1) Collection
2) Set
3) List
4) Map
Collection
The Collection interface is the root of the collection hierarchy.
Usage:
To pass around collections of objects where maximum generality is
desired.
Behaviors:
1) Basic Operations
2) Bulk Operations
3) Array Operations
Collection Methods 1
public interface Collection {
// Basic Operations
int size();
boolean isEmpty();
boolean contains(Object element);
boolean add(Object element); // Optional
boolean remove(Object element); // Optional
Iterator iterator();
// Bulk Operations
boolean containsAll(Collection c);
boolean addAll(Collection c); // Optional
boolean removeAll(Collection c); // Optional
boolean retainAll(Collection c); // Optional
void clear(); // Optional
Collection Methods 2
// Array Operations
Object[] toArray();
Object[] toArray(Object a[]);
}
Example:
1) Set of Cars - {BMW, Ford, Jeep, Chevrolet, Nissan, Toyota, VW}
Two Set objects are equal if they contain the same elements.
Set Methods 1
The Set interface is shown below:
public interface Set {
// Basic Operations
int size();
boolean isEmpty();
boolean contains(Object element);
boolean add(Object element); // Optional
boolean remove(Object element); // Optional
Iterator iterator();
// Bulk Operations
boolean containsAll(Collection c);
boolean addAll(Collection c); // Optional
boolean removeAll(Collection c); // Optional
Set Methods 2
boolean retainAll(Collection c); // Optional
void clear(); // Optional
// Array Operations
Object[] toArray();
Object[] toArray(Object a[]);
}
Collection operations:
1) remove operation removes the first occurrence of the specified
element
2) add and addAll operations always appends new elements to the end
of the list.
3) Two List objects are equal if they contain the same elements in the
same order.
List 2
1) New List operations
a) Positional access
b) Search
c) Iteration (ordered, backward)
d) Range-view operations
Iterator allows the caller to remove elements from the underlying collection
during the iteration with well-defined semantics
Location: java.util.Iterator
Example: Iterator
static void filter(Collection c)
{
for (Iterator it = c.iterator() ; it.hasNext(); )
if (!cond(it.next()))
it.remove();
}
4) Two Map objects are equal if they represent the same key-value
mappings
Example: Map 1
import java.util.*;
public class Freq {
private static final Integer ONE = new Integer(1);
public static void main(String args[]){
Map m = new HashMap();
for (int i=0; i<args.length; i++) {
Integer freq = (Integer)m.get(args[i]);
m.put(args[i], (freq==null ?
ONE : new Integer(freq.intValue() + 1)));
}
System.out.println(m.size() + " distinct words
detected:");
System.out.println(m);
} }
Example: Map 2
for (Iterator i = m.keySet().iterator() ;
i.hasNext() ; )
System.out.println(i.next());
Implementations
Resizeable Balanced
Hash Table Linked List
Array Tree
All take the form of static methods whose first argument is the collection
on which the operation is to be performed.
1)Sorting
a) reorders a List so that its elements are ascending order
according to some ordering relation.
b) The important things to know about this algorithm are that it is:
• Fast: This algorithm is guaranteed to run in n log(n) time,
and runs substantially faster on nearly sorted lists.
• Stable: That is to say, it doesn't reorder equal elements.
2) Shuffling
a) does the opposite of what sort does - it destroys any trace of order
that may have been present in a List.
Algorithms 3
3) Routine Data Manipulation
a) The Collections class provides three algorithms for doing
routine data manipulation on List objects: Reverse, Fill and
Copy
4) Searching
a) The binarySearch algorithm searches for a specified element in
a sorted List using the binary search algorithm.
6 *4 * $ %
% . % # .% ;
</# .5 $ % + $ $
+
<& .. + - = 6 / $$ = %
<' + "'& + * .
< * > '& . ? " >. $ ! 0! .
<> . > $/ $$ + " . $
+ # * $$ * $$
Overview of Swing API 7
( % 65 % # $ # "
* ! " . " '& % >A ,
( 0 # 65 , !#
B /# . ,B
( '& 65 , % B /# .'&,1
C ; B/# .B # % $ 7
* $ # $ ,
Overview of Swing API 8
& % /# .!' (D
'+ #
( = <$ * E $ >A , ,
$ % ,
* & % $$ ' ( $
' ( 7* , # # /# . 7* 0, # .
/# .5 $ # 1 2
' (+ F
/# .F F
First Swing Application 1
( 0 % $ $ . !
) /# ., ( + % %
/# .,
import javax.swing.*;
public class HelloWorldSwing {
public static void main(String[] args) {
JFrame frame = new JFrame("HelloWorldSwing");
final JLabel label = new JLabel("Hello World");
frame.getContentPane().add(label);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_C
LOSE);
frame.pack();
frame.setVisible(true);
}
}
First Swing Application 2
( + * "/# .
$ . ;
< $ $ $ =.
</ $ $ *
( % $ /# .$ = . ;
import javax.swing.*;
)# * ! /# .$ . $ # ' (
$ =. + /# . $ ' (
% ! . ' ( * ,
import java.awt.*;
import java.awt.event.*;
First Swing Application 3
8* "$ . # /# .:E
$ * /# . ,
Definition
A top-level Swing container provides the support that Swing
components need to perform their painting and event handling.
( $ * ;
1) JFrame $ . # #
2) JDialog $ "# #D # # G
$ # #<
3) JApplet $ $$ G $ " #
+ # # #
First Swing Application 4
) $ # % ;
( # % +
$ % ,
final JLabel label = new JLabel("Hello World");
frame.getContentPane().add(label);
( # ## =
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
First Swing Application 5
6 $ * setDefaultCloseOperation
%. % % # =
+ ,
( EXIT_ON_CLOSE " $ %
" ! %
* , % * & % ,
( $ * !" * #
# # * ,
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
);
Basic Features
% # . $$ +
% % # .;
1) SwingApplication.java
2) CelsiusConverter.java
3) LunarPhases.java
Example: SwingApplication 1
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SwingApplication {
private static String labelPrefix = "Number of
button clicks: ";
private int numClicks = 0;
public Component createComponents() {
final JLabel label = new JLabel(labelPrefix +
"0 ");
JButton button = new JButton("I'm a Swing
button!");
button.setMnemonic(KeyEvent.VK_I);
Example: SwingApplication 2
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e) {
numClicks++;
label.setText(labelPrefix + numClicks);
}
});
label.setLabelFor(button);
JPanel pane = new JPanel();
Example: SwingApplication 3
pane.setBorder(BorderFactory.createEmptyBorder(
30, //top
30, //left
10, //bottom
30) //right
);
pane.setLayout(new GridLayout(0, 1));
pane.add(button);
pane.add(label);
return pane;
}
Example: SwingApplication 4
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(
UIManager.getCrossPlatformLookAndFeelClassName(
));
} catch (Exception e) {}
JFrame frame = new JFrame("SwingApplication");
SwingApplication app = new SwingApplication();
Component contents = app.createComponents();
frame.getContentPane().add(contents,
BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_C
LOSE);
frame.pack(); frame.setVisible(true);}}
Example: SwingApplication 5
( $ . % # .% % # .;
< * = %
<5>8H % = %
< # = % !
Example: Look and Feel
( $$ # " # /# .'$$ $ %
= % ;
E $ % = % ,
Example: Look and Feel
( % # .%. # * # % :E
/# . $ ,
Buttons and Labels
) G 9 + ;
<' .)( - -+
<' . # .F
Example: CelsiusConverter 1
( $ . # % % # .;
<' .)( - -+
<' . # .F
Example: CelsiusConverter 3
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CelsiusConverter implements
ActionListener {
JFrame converterFrame;
JPanel converterPanel;
JTextField tempCelsius;
JLabel celsiusLabel, fahrenheitLabel;
JButton convertTemp;
public CelsiusConverter() {
converterFrame = new JFrame("Convert Celsius to
Fahrenheit");
Example: CelsiusConverter 4
converterPanel = new JPanel();
converterPanel.setLayout(new GridLayout(2, 2));
addWidgets();
converterFrame.getContentPane().add(
converterPanel, BorderLayout.CENTER);
converterFrame.setDefaultCloseOperation(JFrame.
EXIT_ON_CLOSE);
converterFrame.pack();
converterFrame.setVisible(true);
}
Example: CelsiusConverter 5
private void addWidgets() {
tempCelsius = new JTextField(2);
celsiusLabel = new JLabel("Celsius",
SwingConstants.LEFT);
convertTemp = new JButton("Convert...");
fahrenheitLabel = new JLabel("Fahrenheit",
SwingConstants.LEFT);
convertTemp.addActionListener(this);
converterPanel.add(tempCelsius);
converterPanel.add(celsiusLabel);
converterPanel.add(convertTemp);
converterPanel.add(fahrenheitLabel);
Example: CelsiusConverter 6
celsiusLabel.setBorder(BorderFactory.
createEmptyBorder(5,5,5,5));
fahrenheitLabel.setBorder(BorderFactory.
createEmptyBorder(5,5,5,5));
}
<5 $ F
<5 + F0
<- . $ .
Example: LunarPhrases
Compound Border
F +$ ! & $ "& ! *
$ + ,
( $ + % + D
+ # < $"+ D
0 $ <!
( % & + % #,
selectPanel.setBorder(BorderFactory.createCompoundB
order(BorderFactory.createTitledBorder("Select
Phase"),BorderFactory.createEmptyBorder(5,5,5,5)));
Combo Boxes 1
<' + +0 + ,
<' + +0 + + + !+ +"
% +
<' + + +0 = = +
# , = ! + +0
$ " % ,
Combo Boxes 2
<' + +0 + ,
<' + +0 + + + !+ +"
% +
<' + + +0 = = +
# , = ! + +0
$ " % ,
< + + +0
<# $ !
+<# + % .! #
$ ,
Combo Boxes 2
( $$ + + 0;
, # " %/ .
, " %/ .
80 $ ;
phaseChoices.addActionListener(this);
...
public void actionPerformed(ActionEvent event) {
if
("comboBoxChanged".equals(event.getActionCommand
())) {
// update the icon to display the new
phase
phaseIconLabel.setIcon(images[phaseChoices.getSe
lectedIndex()]);
}
}
Multiple Images 1
< $ * $ . !# # # .
. + ,
<-& . . ,
<( %. +* # :E %%* %
% $ . ,
<( + ,
/ # " :E = %
% @
<F " %
% " .
9 $ % + ,
Using Layout Managers 1
( * $ % $$ %* " "
. ;
<F -"
<F 0- "
<6 #- "
<: F .- " !
<: -"
Using Layout Managers 2
<F" % !* " " .
<& +7 6 #- " +" %
< '$$ ! > .! 6 +7
F -" +" %
<' ! " " * = + "
. # " & $
$ ,
Using Layout Managers 3
%" G = % " . $
$ !" . %
% +"
. -" % $ ,
( . . +
FlowLayout.LEADING,
FlowLayout.CENTER, or
FlowLayout.TRAILING
GridLayout
= + % $ ? 9 $ "
? + % #
Example: GridLayout
pane.setLayout(new GridLayout(0,2));
<' % # .
+ 9
< # . $ *
.
<( 9 :$ * :$ .
#" $ %" + %
$0 + # , %" G $ %". $ !
* % 9 ,
GrigBagLayout
< $ % 0+ " .
< . $ +"$ . # . % !
# . $ $
<( # . G "
. J "!. * %
% # ,
Example: GrigBagLayout 1
JButton button;
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
3) The big exception to the rule is that if the top-level container has a
menu bar, then by convention the menu bar goes in a special place
outside of the content pane.
Containment Hierarchy 3
Here is the code that adds the button and label to the panel, and the panel
to the content pane
import java.awt.Graphics;
import javax.swing.JApplet;
}
Displaying Welcome Message
//Welcome Applet
import java.awt.Graphics;
import javax.swing.JApplet;