[Top bar]
[Bottom bar]
[Photo of the Author]
by Jose M. Fernández <fgcia(at)correoweb.com>
Translated to English by:
Javier Cano <jcano(at)iti.upv.es>
Content:
|
Programming with Java, part II
[
画像: ]
Abstract:
This series of articles have as a model the classical books of
structured programming. After a short introduction to Java
language characteristics in the first article of the series, we
now continue with the study of data types, variables, control
statements, etc. This will lead us to the most important topic
which is classes. The concept of classes is at the root of this
programming language. Into account that classes are the basis
of this programming language.
_________________ _________________ _________________
Lexical issues
Formally speaking, a Java program is formed by a set of
comments, identifiers, literals, separators, blank spaces and
key words. The compiler receives code written in a unique
format, expanding the number of bits from 8 of ASCII to 16 and,
consequently, also widening the keymap table to fit with those
characters of the no latin languages. Blank spaces, tabs and
carriage returns are erased by the compiler as they do not
belong to the symbol set. This provides Java programs with free
writing style.
Java comments can be in one of the next three styles:
- //comments
Characters from // until end of line are ignored.
- /* comment */
All characters between /* and */ are ignored. These comments
can have an extension of several lines.
- /** comment **/
Same as /* */ comments, but these should only be used before
the declarations because the tool javadoc uses them to
automatically create the documentation.
Identifiers are the names given to the variables, classes
and methods to identify them to the Compiler. It is possible to
use any string of letters (upper and lower case), numbers and
the underline and dollar symbols. They can not begin with a
number.
Java uses some special characters as separators. The most
frequently used is the ; separator, but we will also find:
Symbol
Description
()
It holds parameter lists on the definition and call to
the methods. It is also used to change the expressions
precedence, or to contain expressions in a control
sentence. and in type conversion.
{}
To contain the values of the automatically
initialized vectors. To define a code block, to use with
classes, methods and local scope
[]
To define matrix types. To reference
values in a matrix
;
Sentence separator.
,
To separate consecutive identifiers in the
variable declaration. To separate sentences in a FOR
sentence.
.
To separate packet, sub packet and classes
names. To separate a variable or method from a referenced
variable.
The keywords are identifiers used by the Java language and
cannot be used in any other way from that defined by Java. The
next table shows all the Java keywords:
abstract
double
int
super
boolean
else
interface
switch
break
extends
long
synchronized
byte
false
native
this
byvalue
final
new
threadsafe
case
finally
null
throw
catch
float
package
transient
char
for
private
true
class
goto
protected
try
const
if
public
void
continue
implements
return
while
default
import
short
do
instanceof
static
Data types, Variables, Operators.
At this point I will insist on saying that Java is a hard typed
language, each variable has a type and each type is tightly
defined. All assignment type compatibility is tested, both
explicitly or through parameter interchange in the calls to
methods. The compiler checks all the expressions and parameters
to ensure type compatibility.
In the previous article we mentioned that Java was
completely object oriented, nevertheless, due to efficiency
considerations, Java defines eight "simple" data types that are
not objects. Besides, for portability reasons, all data types
have a very defined range.
Simple data types can be distributed in four groups:
TYPE
NAME
SIZE
RANGE
Integer
long
64
-9.223.372.036.854.775.808
a
9.223.372.036.854.775.807
int
32
-2.147.483.648
a
2.147.483.647
short
16
-32.768 a 37.767
byte
8
-128 a 127
Floating point
float
32
3.4 e-038 a 3.4 e+038
double
64
1.7 e-308 a 1.7 e+308
Character
char
16
Unicode
Boolean
boolean
true o false
Variables:
A variable is defined by an identifier and a type.
Alternatively, we can declare and initialize the variable at
the same time. Every variable has a scope and a lifetime.
Besides, they must be declared before they can be used. They
can be declared at any place in the program, even at the same
moment of being used for the first time.
Generally, a variable is declared in this way:
identifier type [=value] [,identifier [=value]......];
where "type" can be a basic Java type or a class, even an
interface. If we initialize the variable, its expression must
be of the same type or a compatible type with that specified at
the variable declaration.
Examples:
int a = 4, b, c=7;
char c;
myclass class;
As a rule, the variable defined inside a scope it is not
accessible by the code outside (we define scope as the code
portion between braces {}). A variable will not hold its value
once exited from its scope.
Most of the programming languages define two scope
categories, global and local. But this does not fit well with
the Java object oriented model. On this model, the two main
scopes are those defined by a class and a method.
Type conversion:
Java allows, although theory denies it, to assign a value of a
specific type to a variable of another type. If the types are
compatible, an automated conversion is carried out and if not,
it is always possible to perform an explicit type conversion
between incompatible types. In order to achieve an automatic
conversion of types, it is required that:
- the two data types will be compatible.
- Destination type should be bigger than source type.
For example, an int type is big enough to store a byte type, so
it doesn't need an explicit conversion. Number types are not
char or boolean compatible, and these last are neither
compatible with the rest of them. If we wanted to assign an int
value to a byte, we should make use of an explicit conversion
with the next format:
where type indicates the type conversion target. Example:
int a;
char b;
a=(int) b;
We must take care with the automated type conversion, as this
conversion can carry out a leak of information. For example:
At the conversion of a floating point type to an integer
type, it loses the fraction component:
int a;
double d= 125.43;
a=(int) d;
the variable has the value 125.
byte b;
int i=257;
b=(byte) i;
b has the value 1, that results from dividing 257 by
256 where 256 is the range of the byte type.
byte b;
double d= 340.123;
b=(byte) d;
where b will have a value of 84;
All these conversions are carried out with the compiler and the
interpreter , which do not come up with any compile errors.
Operators:
There is a wide set of operators that can be divided into four
groups: arithmetic, bit level, relationals and logic. As a
general rule, they will work exactly the same as in other
languages, but there are some little differences that will be
discussed here.
Arithmetic Operators:
Operator
Description
+
Addition
-
Subtraction
*
Multiplication
/
Division
%
Modulo (division remaining)
++
Increment
+=
Addition and assignment
-=
Subtraction and assignment
*=
Multiplication and assignment
/=
Division and assignment
%=
Modulo and assignment
--
Decrement
The modulo operator can be applied, both to integer and
floating point values. For example:
int a=38;
double d=41.95;
int c=a%10;<
double e=d%10;
The c variable has a 8. The e variable has a 1.95;
The operators with assignment are useful at constructions
such as:
a = a + 4; equivalent to a+=4;
a = a % 2; equivalent to a%=2;
Normally, we can say that sentences like:
var=var op expression; can be replaced with var op=
expression;
Bit level operators:
There are some defined bit level operators that can be applied
to integer, long, int, short, char, byte types, modifying their
operand bits.
Operator
Description
~
Unary NOT at bit level
&
AND at bit level
|
OR at bit level
/\
Exclusive OR exclusive at bit level
>>
Right shift
>>>>
Right shift filled with zeroes
<<
Left shift
&=
AND at bit level and assignation
|=
OR at bit level and assignation
/\=
exclusive OR at bit level and
assignation
>>=
Right shift and assignation
>>>>=
Right shift filled with zeroes and
assignation
<<=
Left shift and assignation
Relational operators:
They determine the relation between two operands, specifically
testing if one is equal, greater or lower than the other. The
result is a boolean value.
Operator
Description
= =
Equal to
!=
Different from
>
Greater than
<
Lower than
>=
Equal or greater than
<=
Equal or lower than
Unlike other languages(C/C++), the boolean values are True and
False, that is, they are not numeric values..
Boolean logic operators:
They only work with boolean operators and also produce another
boolean operator.
Operator
Description
&
logic AND
|
logic OR
/\
logic XOR(exclusive OR)
||
shortcut OR
&&
shortcut AND
!
unary logic NOT
&=
AND assignment
|=
OR assignment
/\=
XOR assignment
= =
Equal to
!=
Not equal to
?:
Ternary If-then-else ternary
The OR shortcut operator has as a result: true, when the first
operator is true, whichever the second operator value. Equally,
the AND shortcut operator is false when the first operator is
false, whichever the other operator.
The general format of the ternary operator is:
Expession1 ? expession2 : expression3
If Expression1 is true, expresion2 will be executed; if it
is false, expression3 will be executed.
Operators precedence:
Higher
( )
[ ]
.
++
--
~
!
*
/
%
+
-
>>
>>>>
<<
>
>=
<
<=
= =
!=
&
'
|
&&
||
?:
=
Op=
Lower
Flow-Control sentences
They can be divided into three groups: Selection, Iteration and
Jump.
Group
Sentence
Description
Selection
if
if ( condition )
sentence1;
else
sentence2;
various if's
If (condition )
sentence;
else if (condition)
sentence;
else if (condition)
sentence;
.
.
else
sentence;
switch
switch (expression){
case value1:
sentence;
break;
case value2:
sentence;
break;
.
...
default :
sentence;
}
Iteration
while
while (condition) {
sentence;
}
do while
do {
sentences;
} while (condition)
for
for (initialization, condition, iteration) {
sentences;
}
Jump
break
To exit from a switch.
To exit from a loop
continue
Exits from the current loop iteration
but continues in the same loop
return
Return explicitly from a method
Classes, Methods, Inheritance
Java is a language that was designed from scratch, as we
remarked in the previous article, and this is the reason for
the language being a close, clear and useful implementation of
an object oriented programming language. Consequently, all Java
programs are object oriented. You must realize that you will
not find any object oriented programming teaching in this
series of articles. For that purpose you can find a lot of
great literature, from the basics up to the most skillful
programming. Because OOP (object oriented programming) is so
fundamental to Java, you should understand it before beginning
to program in this language. We are forced to use and handle
some basic elements of this paradigm, although we always will
follow the Java terminology and we will try to define the
elements that make Java a complete object oriented language in
the shortest and clearest way.
CLASSES :
It is the Java kernel. It defines the shape and nature of an
object, and it represents the basis of object oriented
programming. A new data type comes defined by a class, and this
new type can be used to create objects of that type.
A class is a model (pattern) for an object, and an object is
an instance of a class. Java does not support global functions
or variables, so all program actions (methods) have to be
defined into a class.
A class is defined using the reserved word "class". A common
class definition could be:
Class class_name {
Type instance1_of_variable;
Type instance2_of_variable;
.
.
...
type instance_variable;
type method_name(parameter_list){
//body of the method
}
.
.
..
type name_of_the_method(parameter_list){
//body of the method
}
}
The variables or data defined into a class are called variables
of instances. The methods contain the code, and they define how
the data of a class can be used.
Two steps are required in order to get the objects of a
class:
- To declare a variable of the type of the class. This
variable does not define an object, it is a variable which we
can use to reference an object.
- To dynamically assign memory to the object and get a
reference of it.
This second step it is done by means of the new operator. Its
general aspect is:
variable = new name_of_the_class();
Where "variable" is a variable of the class that we want to
create and name_of_the_class is the name of the class which is
being instanciated. The creation of an object could be
graphically represented as:
METHODS:
The general format of a method is:
type name_of_the_method (parameter_list) {
//method_body
}
"type" is the returned type by the method; it can be any valid
type, included class types, or it can even not return any value
(void).
The parameter list is a pair sequence of type-identifier,
separated by a colon. The parameters are variables that receive
the value of the arguments given to the method. If the method
has no parameters, then the list will be empty.
Methods returning a value different from "void" use:
Where value is the returned value.
Java provides methods with plenty of flexibility and power,
so from here, up to the end of the article, we will review each
of the most important aspects of methods.
However, before going on, let's review all the previous
concepts with a simple example.
Let's create a class to calculate the capacity of a
rectangular box (like a pool):
Code
Comments
class capacity {
double length;
double width;
double height;
void CalcVolume () {
double volume ;
volume = length*width*height;
System.out.println("Volume: " +
volume);
}
}
As you can see, we have defined a class named
"capacity" which holds three instance variables: length,
width and height. It is also defined a method that
calculates the recipient volume. We will call
capacity.java to the source file. When you compile it, a
capacity.class class will be created.
This class on its own does not carry any action, like an
applet, neither has the main() method to be executed from the
command line. We have created a template that enables us to
create objects (instances) of this class. To perform this
target, we will create a class that can be executed from the
command line.
Code
Comments
class example {
public static void main(String Arg[]){
capacity p1=new capacity();
capacity p2=new capacity();
p1.length = 16;
p1.width=3;
p1.height=2;
//
p2.length = 25;
p2.width=6;
p2.height=3;
//
p1.CalcVolume();
//
p2.CalcVolume();
}
}
Two variables of the capacity type are defined, p1, p2.
With the new operator we create two objects of the
capacity type, which can be referenced through the p1,
p2 variables.
Afterwards, we assign values to each one of the
variables of the created objects
We call the method CalcVolume() of the referenced
object in p1, and as a result a:
"Volume: 96", will be shown on the screen.
The same to the object referenced in p2. A:
"Volume: 450", will be shown on the screen.
When p1.CalcVolume() is executed, the Java interpreter
transfers the control to the code defined inside CalcVolume().
Once all control sentences have been executed it returns to the
calling routine and the execution continues on the next line to
the call.
Methods with parameters. Value return.
The majority of the methods are used with parameters that
allow one to generalize them. Besides, methods can also return
values, so we can build methods that can work with a wide range
of data that can be used in different situations.
We will improve our example:
Code
Comments
class capacity {
double CalcVolume (double l,
double a,
double p) {
double volume=l*a*p ;
return volume;
}
}
The CalcVolume method has been
modified to receive three parameters. It is also defined
to return a double type. This action is performed by the
return volume instruction.
class example {
public static void main(String Arg[]){
capacity p1=new capacity();
capacity p2=new capacity();
double vol;
vol=p1.CalcVolume(10,3,2);
System.out.println("Volume: " + vol);
//
vol=p2.CalcVolume(25,5,2);
System.out.println("Volume: " + vol);
}
}
The call to the method is done
sending the desired parameters. It returns the value of
the method in the vol variable, which must be the same
type that the method.
A main aspect of classes are constructors. These items define
what happens when an object of a class is created. Most of them
explicitily define its own constructors into the class
definition. If not defined at this point, Java uses a default
constructor (as in our example).
A constructor included in a class has exactly the same name
as the class. Its syntax is similar to that of a method. It is
automatically executed after creating the object, before the
new operator finishes.
Constructors do not return any type, as implicitly they
return the type of the class. The constructor carries on with
the initialization of the all the object state. By this way,
the code that creates an instance of the object has a ready
object to make use of it. As default, instance variables are
initialized by constructors. As it happens with methods,
constructors can have parameters to make them more useful.
Let's modify our example to contemplate all this new
aspects.
Code
Comments
Class capacity {
double length;
double width;
double height;
//
capacity(double l,
double a,
double p){
length=l;
width=a;
height=p;
}
//
void CalcVolume () {
double volume ;
volume=large*wide*high;
return volume;
}
}
A constructor is added to the class,
that has the aspect of a method with the same name that
the class, but without any type. This constructor
initializes the instances of the variables declared with
the received arguments.
class example {
public static void main(String Arg[]) {
capacity p1=new capacity(10,5,2);
capacity p2=new capacity(25,6,2);
double vol;
vol=p1.CalcVolume();
System.out.println("Volume: " + vol);
//
vol=p2.CalcVolume();
System.out.println("Volume: " + vol);
}
}
The new operator creates the
instances of the class, passing the needed parameters to
the constructor of that class.
When no reference to an object exists, it is assumed that this
object is not going to be used anymore, so the memory allocated
to it gets freed. There is no explicit need to destroy the
objects because this process is carried out in an automated way
through the program execution.
Nevertheless, the method "finalize()" is used to add a
finisher to a class. This method is executed when the
interpreter destroys the object. In this method we will include
the actions to get executed before destroying the object.
Method Overload.
Polymorphism (multiple methods for one interface) is one of
the basic PILLARS in OOP. Java implements polymorphism by means
of the method overload.
Different methods with the same name can be defined in a
class, but they must have a different parameter list or at
least different returned types. When an overloaded method is
called the Java interpreter uses the type and/or the arguments
passed with the call, to distinguish the version of the method
to be used.
Each version of the overloaded method can perform different
tasks, although this makes polymorphism completely impossible,
so method overload should preferably imply some relation. Same
way methods get overloaded, constructors can also be
overloaded.
Argument passing.
Generally, programming languages allow two different ways to
pass the arguments:
- By value: it is a copy of the argument value on the
parameter-variable routine.
- By reference: it is passed the reference (the memory
address) of the value, so if the value is modified by the
routine, the variable at the calling process gets also
modified.
Java supports two means of passing parameters to the methods.
If the argument has a simple type, it is passed by value, but
when the argument is an object it is passed by reference.
Access Control.
Another basic PILLAR in OOP is ENCAPSULATION. It means
linking data with the code that uses it. Moreover,
ENCAPSULATION provides access control, that is to say, a part
of the program has the ability to access the members of a
class.
Access specifications in Java are 'public', 'private' and
'protected'.
When a method or a instance-variable is defined as 'public',
it is accessible from any part of the program. If defined as
'private', it is only accessible by other methods of its own
class. By default all methods or instance-variables (members)
are 'public' (to its own packet¿?).
The 'protector' specifier is used when working with
HERENCIAS(inheritances¿?), which is the next topic.
INHERITANCE.
The three elements that define OOP are polymorphism,
encapsulation, and last of all inheritance. A general class
(superclass) can be defined through this. This generic class,
with a set of common characteristics, can be inherited by other
more specific classes, each adding some other particular
characteristic.
To achieve a class B inheriting the properties of an A
superclass, we will put in the B definition:
Class B extends A {
// class definition
}
Class B includes all members of A superclass, being this last
class an AUTONOMOUS class with the ability to be used freely.
Also, class B can be the superclass of any other class.
Java does not allow multiple inheritance from different
superclasses to one subclass.
If there are members defined as 'private' in the superclass,
they can not be accessed by the inherited classes. When a
subclass needs to reference an immediate superclass, the
reserved word 'super' can be used. In that way we can call the
builder/constructor or members of the superclass that have been
hidden by the subclass.
When a method of a subclass has the same name and type as
the method of the superclass, it is said that the method is
overwritten. This property establishes the base of one of the
more powerful aspects of Java, named "Dynamic selection
method". This means that the decision of which method should be
used on each call, is performed at execution time in place to
depend on the referenced variable type.
In the next article we will see all the power of
inheritance, with abstract classes, interfaces, etc.
References
- JAVA reference manual. Patrick Naughton
Herbert Schildt. Mcgraw-Hill.
- Programming with JAVA. Tim Ritchey.
Prentice Hall.
- Java Tutorial. Spanish manual in HTML
format obtained from the address www.fie.us.es/info/internet/JAVA.
Agustín Froufe.
- The Java Tutorial. English manual in HTML
format obtained from the address www.javasoft.com. Sun.
- JDK own installation tutorials.
- Java client-server.Cédric Nicolas,
Chistophe Avare y Frederic Najman. Gestión 2000.
2002年11月03日, generated by lfparser version 2.34