Jose M. Fernández |
Summary: 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. To center the classes topic, the first part will be as ESQUEMATICA¿? as possible, due to the similarity to the rest of the programming languages.
Java comments can be in one of the next three styles:
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. |
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 |
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 |
Generally, a variable is declared in this way:
identifier type [=value] [,identifier [=value]......]; |
Examples:
int a = 4, b, c=7; char c; myclass class; |
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) value |
int a; char b; a=(int) b; |
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; |
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 |
int a=38; double d=41.95; int c=a%10;< double e=d%10; |
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;
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 |
Operator | Description |
= = | Equal to |
!= | Different from |
> | Greater than |
< | Lower than |
>= | Equal or greater than |
<= | Equal or lower than |
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 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:
( ) | [ ] | . | |
++ | -- | ~ | ! |
* | / | % | |
+ | - | ||
>> | >>>> | << | |
> | >= | < | <= |
= = | != | ||
& | |||
' | |||
| | |||
&& | |||
|| | |||
?: | |||
= | Op= |
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 |
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 } } |
Two steps are required in order to get the objects of a class:
To dynamically assign memory to the object and get a reference of it.
variable = new name_of_the_class(); |
type name_of_the_method (parameter_list) { //method_body } |
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:
return valor; |
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. |
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. |
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 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. |
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:
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.
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 } |
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.
Páginas web mantenidas por Miguel Ángel Sepúlveda © Jose M. Fernandez 1998 LinuxFocus 1998 |