Tour of JDK •
Uninst.isu file
- contains information that is used when removing the JDK
•
src.jar file
- archive that contains the class library source code (a collection of files with .java
•
bin directory -Tools java.exe, javac.exe, appletviewer.exe, jar.exe
•
jre directory - Java Runtime Environment (JRE) files
•
lib directory
- library files that support the compiler (and other tools) and user-interface development
•
docs directory
- Java Documentation
Can have Java Demonstration Programs Java Tools javac java jdb javap appletviewer javadoc javah
Compiler Interpreter Debugger Dis-assembler Applet viewer Documentation generator C header file generator
Debugger - but it also provides special capabilities to stop program execution at selected breakpoints and to display the values of class variables Dis-assembler : takes the bytecode files and displays the classes, fields (variables), and methods that have been compiled into the bytecodes C header file tool, javah, is used to generate C-language header and source files from a Java bytecode file. The files generated by javah are used to develop native methodsJava classes that are written in languages other than Java.
1
Using Classes from Other Packages -
CLASSPATH is a system environment variable containing a list of directories where Java packages can be found.
-
CLASSPATH tells the JDK programs where to find Java classes.
The Applet Viewer javadoc The Java documentation generator, javadoc, is the tool that created the excellent Java API documentation The documentation generator is executed using either the name of a Java source code file, a full class name, or a package name. If it is executed with a class name or package name, it will automatically load the source code associated with the class or with all the classes in the package. If it is executed with a source code file, it will generate documentation for all classes and interfaces defined in the file. Options: classpath, d and verbose The d option is used to specify the directory to which the generated HTML files are to be stored Java & C++ -
Syntax from C++ No Internet version of C++
Java Applications and Applets Security & Portability Stages in a typical Java Environment 1
Editing the file - .java extension
2
Compiling – Byte Codes
3
class loading by Class Loader – loads all classes necessary for execution.
2
4
Byte Code Verifier – adheres to the format.
5
Interpreter
JVM Byte Codes Features of Java 1 2
Simple Object Oriented – Reusability – Inheritance – Polymorphism – Data Abstraction – Encapsulation. Robust – Strictly typed language – Compile error – memory mismanagement – good exception handling. Multi – Threading Architecture Neutral – Portability – Motto write once; run anywhere, any time, forever. Distributed - Java is designed for the distributed environment of the Internet, because it handles TCP/IP protocols. Dynamic - Java programs carry with them substantial amounts of run-time type information that is used to verify and resolve accesses to objects at run time. We can dynamically link code at runtime.
3 4 5 6 7
Garbage Collection -
Done by a System Level Thread Least Priority Thread One cannot predict when the garbage collection of any particular object will be done. By using the finalise() method, there is no guarantee that the object will be immediately collected, on the other hand using the finalise() method only marks the object ready for garbage collection.
public class Test { public static void main (String arg []) { System.out.println (“ Hello, Welcome to DOTS”); } } Points to be noted: 1
All source codes should be done within classes. There can be either one class or more than one class in any source code file. 3
2
The opening brace {and the closing brace} define the body of the class or the method. 3 If the braces do not occur in matching pairs, the compiler indicates an error. 4 Semi-colons at the end of the line is mandatory and omitting the same at the end of a statement is a syntax error. A syntax error is caused when the compiler cannot recognise the statement. The compiler normally issues an error message to help the programmer to locate and fix the incorrect statements. Syntax errors are violation of the language rules. 5 One can call the class whatever you want (within the limits of identifier, which we will see in the next chapter), but the method, which is executed first in an application, is always called the main (). 6 When you run your java application the method main () will typically cause methods belonging to the other classes to be executed, but the simplest possible java application consist of one class containing the main () method. 7 There can be only one main () in any source code file. 8 The syntax of the main () is fixed and is public static void main (String arg[]) 9 Also note the braces. There will be one set of braces for each and every class and one for the method. The class name should always be start with a capital Alphabet. This is not mandatory but is java coding standard. Now lets see what each of the words in the file is meant: 1 2 3 4 5
6
7
public – This keyword indicates that the class and method is globally accessible. The other access modifiers are default (nothing given), private and protected, which we will see later on. static – The keyword static ensures that it is accessible even though no objects of the class exists. void – This indicates that the method has no return type. It is mandatory for every method to have a return type. (String args []) – Every method has a (), thorough which we can pass any parameter required for the method and in this main () we pass the String array having the name args. The array is defined by []. System – This is the name of the standard class that contains variables and methods for supporting simple keyboard input and character outputs to the display. It is contained in a package java.lang so it is always accessible just by using the simple class name, System. out – The object out represents the standard output stream – your display screen and is a data member of the class System. The member out is a special kind of member of the System class. Like the main () in our program, it is also static. This means that out exists even though there is no object of type System. The out member is referenced by using the class name, System, separated from the member name out by a full stop. println () – This is the println () method that belongs to the object out and that outputs anything that is within the parameters of the method. Over here we are printing out the text string in the println method. 4
OBJECTS DATA METHODS ENCAPSULATION – MODIFIERS INHERITANCE – SINGLE AND NOT MULTIPLE POLY(MANY) MORPHISM (FORMS) WHAT IS A CLASS COMMENTS SEMI-COLON BLOCK WHITESPACE (String) SOURCE FILE LAYOUT – PACKAGE – IMPORT – CLASS EXTENDS AND IMPLEMENTS API DOCUMENTATION The class hierarchy. A description of the class and its general purpose A list of member variables A list of constructors A list of methods A detailed list of variables, with descriptions of the purpose and use of each variable. A detailed list of constructors with descriptions A detailed list of methods with descriptions.
Identifiers -
May begin with a letter May begin with a Dollar sign ($) May begin with a underscore (_) 5
Keywords Keywords are words having special meaning to the Java Technology Compiler. They identify a data type name or program construct name. The following are important notes about keywords a) The literals true, false and null are lowercase and not uppercase as in C++ language. Strictly speaking these are not keywords but literals, but the difference should be known. b) There is no sizeof operator; the size and representation of all types is fixed and is not implementation dependent. c) goto and const are keywords that are not used in Java Programming Language. The keywords are: abstract boolean break byte case catch char class continue default
do double else extends final finally float for future if
implements import instanceof int interface long native new null package
private protected public return short static super switch synchronized this
throw throws transient true try void volatile while
What are variables?? A variable is a named piece of memory that you use to store information in your java programs – a piece of data of some description. In short variables are locations in memory in which values are stored. Each one has a name, a type, and a value. If you define a variable to store integers, for example you cannot use it to store a value that is of decimal fraction or a string value Before you can use a variable, you have to declare it. After it is declared, you can then assign values to it and use it. The declaration does the following;
6
a) Tells the compiler what the variable name is, so that it can referenced in future b) Tells the compiler the type of data the variable will or can hold. Java is very particular about the data type and if you specify any variable can hold integer, then that variable cannot hold any other data type (i.e. String, Double, Float etc) and compiler check for the same. c) The place of declaration decides the scope of variables, whether the variable is local variable or class variable or instance variable. a) Declaration Before you can use any variable anywhere in the program, you will have to declare it. b) Initialisation One will have to intialise a variable inside a method mandatorily, for class and instance variables, they take a default value. Variables are of 3 kinds namely, Local Variable, Class Variables or Instance Variables. Local Variables: Inside a method – destroyed when exited – to be initialized – cannot be used outside its scope Instance Variables: Instance variables are created when objects are instantiated and therefore they are associated with the object. They take different value for each objects. Class Variables: Class variables are variables that can be used for the whole class and all methods inside that class can use those variables. The Important point to be noted here is that there is only one memory location for the class variables. Default value of a class variable: Data Type
Default Value
boolean char byte short int long float double String
false \u0000 (that is nothing) 0 0 0 0L 0.0f 0.0d null
7
8
Data Types - The data types specify the size and type of values that can be stored. Each primitive data type has a name, specifies how much memory is required to store a data item of that data type, and identifies a legal range of values from which a data item of that data type can be obtained. Again the Primitive data types can be classified into the following 4 major categories a) b) c) d)
Textual Data Type Integral Data Type Logical Data Type Floating Data Type
1 Textual Data Type: Individual Characters and can hold only single characters - The character should be put inside quotes (‘ ‘) while defining the same. Characters are stored in 16-it Unicode characters and the range is from 0 to 255 and there is no negative char. It is important to note that char in C/C++ and in Java are different because in C/C++, char is an integer type with 8 bits wide. Java uses Unicode to represent characters. Unicode defines a fully international character set that can represent all the characters found in all human languages. Since java is designed to allow applets to be written for worldwide use, it makes sense that it would use Unicode to represent characters. The following table lists the special codes that can represent nonprintable characters, as well as characters from the Unicode character set. Character escape codes. Escape \n \t
Meaning New line Tab
2 Integral Data Type The Integral Data Type can be represented in 3 forms namely; a) b) c)
Decimal – Where the decimal value is two Octal – Where the leading zero indicates an octal value (Eg. 077) Hexadecimal – Where the leading OX indicates a hexadecimal value (Eg. OX22)
The default Integral type is int and for Long it has to be explicitly followed by the letter L. There are 4 types of variables that you can use to store data and all of these are signed that mean you can use both negative and positive values. The four integer types differ in 9
the range of values they can store, so the choice of types for a variable depends on the range of data values you are likely to need. The four integer types are: Type
Size
byte short int long
8 bits 16 bits 32 bits 64 bits
Range -128 to 127 -32,768 to 32,767 -2,147,483,648 to 2,147,483,647 -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
byte and short The smallest integer type is byte. This is a signed 8-bit and is especially useful when you are working with a stream of data from a network or file. short is a signed 16-bit data type int – 32 Bit IMP: It is very important to note here that integer expressions using byte and short are AUTOMATICALLY PROMOTED to int before the calculation is done. This has a specific reason and will be explained later on. long The type long is a 64-bit and is useful for those occasions where an int type is not large enough to hold the desired values 3 Logical Data Type In Java, the only logical type is boolean which takes only two states, true or false. In java, unlike C and C++ boolean is neither a number nor it can be treated as one. All tests of boolean should test for true or false. Also note that boolean states are in small caps and not like other languages where true should mandatorily be declared as TRUE and vice versa. It is also important to note that boolean values cannot be converted or casted with other data types also. The boolean data type is used by the control statements like if and for etc. 4 Floating Point Data Type Floating-point numbers are also known as real numbers are used when evaluating expressions that require fractional precision. There are two kinds of floating point types, float and double which represent single and double precision numbers in the width and range as under:
10
Type float double
Size 32 bit 64 bit
Range 3.4e-038 to 3.4e+038 1.7e-308 to 1.7e+308
The default of Floating Point is Double. The Floating point literals include either a decimal point or one of the following. a) E or e (exponential value) b) F or f (float) c) D or d (double) Example: 3.12 2.78F 6.02E3
A simple double A simple float size value A large floating point exponential value.
Example: class Test { public static void main (String arg[]) { byte a = 10; short b = 20; short c = a + b System.out.println (c); } } The output would be as under: Error: Explicit casting is required. This example gives application to the automatic promotion rule that byte and short are automatically converted into int and the result type should be stored in an int. Java Coding Conventions Classes
- Class names should start with the first letter of each word capitalized
Interfaces – They should also be capitalised by class names
11
Methods – Method names should start with the first letter in lower case and within each method name, capital letters separate each word. Variables – All variables should with a lowercase first letter like that used for method and the words will be separated by capital letters. Limit the use of underscore(_) and Dollar ($) because they have special meaning to inner classes. Java Operators Java provides a fully featured set of operators, most of which are taken fairly directly from C and C++. However Java’s operators differ in some important aspects from their counterparts in these other languages and you need to understand clearly how java’s operators function. The Java Operators can be classified into 8 Groups as under: a) b) c) d) e) f) g) h)
Unary Operators Arithmetic Operators Shift Operators Comparison Operators Bitwise Operators Short-Circuit Operators Ternary Operators Assignment Operators
Unary Operators The most common of the unary operators are i. ii. iii. iv. v.
Increment and Decrement Operators; ++ -Unary plus and minus Operators; + The bitwise inversion operators; ~ The boolean complement operators; ! The Cast operator; ()
Increment and Decrement Operators These operators modify the value of an expression by adding or subtracting 1. So for example, if an int variable x contains 10, then ++x results in 11 and --x give you 9. This is the case because the increment and decrement is done on x and the value is stored in x only To understand how the position of these operators’ ++x and x++ affect their operation, you must understand the different between the values stored by these operations and the result value they give. For example, you could say y = x++; then the value assigned to y will be the original value of x and if you say y = ++x, then the value assigned to y will be 1 more than the original value of x. It is important to note here that in both these cases the value of x will be increment by 1. 12
The following table shows the value of x and y, before and after particular assignment using these operators: Initial value of x
Expression
Final Value of y
Final value of x
10 10 10 10
y = x++ y = ++x y = --x y = x--
10 11 9 10
11 11 9 9
The Unary x and – operators The unary + and – operators are distinct from the more common binary + and – operators which are usually referred to as + and – (add and subtract). The unary + has no effect beyond emphasising the positive nature of a numeric literal. Unary – negates an expression. So one might make a block of assignment just like this: x = -3; y = +3; z = -(y+6); The Bitwise Inversion Operator ~ The ~ operator performs bitwise inversion on integral types. For each primitive type, Java uses a virtual machine representation that is platform independent. This means that bit pattern used to represent a particular value in a particular variable type is always the same. This feature make bit manipulation operators even more useful, since they do not introduce platform dependencies. The ~ operator works by converting all the 1 bits in a binary value to 0s and all the 0 bits to 1s. For example, applying this operator to a byte containing 00011101 would result in the value 11100010. The same simple logic applies, no matter how many bits there are in the value being operated on. The Boolean Complement Operator ! This operator inverts the value of a boolean expression so !true gives false and !false would give true. This operator is usually used in the body of if() and else() to be swapped. The Cast Operator
13
Casting is used for explicit conversion of the type of an expression. This is only possible for plausible target types. The compiler and runtime system check for conformance with typing rules and incase they do not match, then casting might be required. Casts can be applied to change the type of a primitive values, for example forcing a double value into a int value like this: int c = 10; double b = 15.50; int d = (int) (c x b); Arithmetic Operators The next highest in precedence, after the unary operators are the arithmetic operators. The Arithmetic Operators are divided into two further sub groups, the first group having the *, / and % operators. The second group have the lower precedence + and – operators. Multiplication and Division Operators The above operators can be used on all primitive numeric types and char. Integer division can generate an ArithmeticException from a division by zero. The multiplication and division works as it works in simple math examples which we learnt in school. The important point to note here is that, whether you multiply or divide two integers, the result will be calculated using the integer arithmetic in either int or long representation and u will have to store the same in the wider of the types to ensure that precision is maintained. Modulo Operator % The modulo Operator gives a value which is related to the remainder of a division. It is generally applied to two integers, although it can be applied to floating point numbers also. For example when you say int a = 7 int b = 3 int c = a % b the result would be 1. The Addition and Subtraction Operators The + and – operators perform addition and subtraction and they apply to operands of any numeric type, but uniquely, the + operator is also permitted when either of the operand is a String object.
14
When either of the operands of a + expression is a String object, the meaning of the operator is changed from numeric addition to concatenation of text. In order to achieve this, both operators must be handled as a text. If both operators are in fact String objects, this simple, however if one of the operands is not a String object, then the non string operand is converted to a String object before the concatenation is taken place. How operands are converted into String Objects?? It is very useful in practice to know a little about how + converts operands into String objects. For object types, conversion to a String object is performed simply by invoking the toString () of that object. The toString () is defined in the java.lang.Object class which is the root of the class hierarchy and therefore all objects have a toString (). Conversion of an operand of primitive type to a String is typically achieved by this, indirectly using the conversion utility method in the wrapper classes. For example, an int value is converted by a static method Integer.toString (). So to summarise: For a + expression with two operands of primitive numeric type, the result a) Is of a primitive numeric type b) Is at least int, because of normal promotions c) If of a type at least as wide as the wider type of the two operands. d) Has a value calculated by promoting the operands to the result type, then performing the addition calculations using that type. This might result in overflow or loss of precision. Shift Operators Java provides three shift operators. Two of these << and >> are taken directly from C++, but the third >>> is new. Shifting is on the face of it a simple operation. It involves taking the binary representation of a number and moving the bit pattern left or right. The shift operators may be applied to arguments of integral types only. The operator >> performs a signed right shift. The result of this shift is that the first operand is divided by two raised to the number of times specified by the second operand. For example 128 >> 1 means 128 >> 2 raised to 1 = 64
15
256 >> 2 means 128 >> 2 raised to 2 (4) = 16 The >> operator results in the sign bit being copied during the shift, hence if the original value is negative the result would be negative and vice versa. The >>> is a logical and unsigned right shift operator which works on the bit pattern rather than the arithmetic meaning of a value. The << is a left shift operator and the result of this shift is that the first operand is multiplied by two raised to the number specified in the second operand. For example 128 << 1 which returns 128 * 2 raised to 1 (2) = 256 16 << 2 which returns 16 * 2 raised to 2 (4) = 64. The Comparison Operators The comparison operators all return a boolean value. There are three types of comparison: a) Ordinal
- Which tests the relative value of the numeric operands
b) Object Type - Which tests if the runtime type of an object is of a particular type or subclass of that particular type c) Equality to values of
- Which test if two values are the same and may be applied non-numeric types also.
Operator < > <= >=
Meaning Less than Greater than Less than or equal to Greater than or equal to
Example x<3 x>3 x <= 3 x >= 3
instanceof Operator This is the operator, which tests the class of an object at runtime. The left-hand argument can be any object reference expression, usually a variable, while the right hand operand must be a class, interface or array type. You cannot use a java.lang.Class object or its string name as the right hand operands. The instanceof operator returns true if the class of a left hand argument is the same or is some subclass of the class specified by the right hand operand. The right hand 16
operand may equally well be an interface. In such a case, the test determines if the object at the left hand argument implements the specified interface. Note: If the left hand argument is a null type, the instanceof test simply returns false – it does not cause an exception. Equality comparison operators: == and != The operators == and != test for equality and inequality, respectively returning a boolean value. For primitive type, the concept of equality is quite straightforward and is subject to promotion rules so that for example a float value of 10.0 is considered equal to a byte value of 10. For variables of object type, the “value” is taken as the reference to the object; typically this is the memory address. You should not use these operators to compare the contents of objects, such as strings because they will return true if two reference refer to the same object, rather than if the two objects have an equivalent meaning. To achieve a in-depth comparison, so that two different String objects containing the text “Hello” are considered equal, you must see the equals() rather than the == method. Bitwise Operators The Bitwise Operators &, ^ and | provide AND, Exclusive-OR (XOR) and OR Operations respectively. They are applicable to internal types. The bitwise operations calculate each bit of their results by comparing the corresponding bits of the two operands on the basis of these 3 rules: a) For AND Operations, 1 and 1 produces 1 and any other combination produces 0 b) For XOR Operations, 1 XOR 0 produces 1 as does 0 XOR 1 and any other combination produces 0 c) For OR Operation 0 OR 0 produces 0 and any other combination produces 1 The names AND, XOR and OR are intended to be mnemonic for these operations. You get 1 result from an AND operation if both the first operand and second operand are 1. An XOR gives 1 result if one or the other operand, but not both (the exclusivity part) is 1. In the OR Operation, you get 1 result if either the first operand or the second operand (or both) is 1 Bitwise on Boolean Operations The &, ^ and | operators behave in fundamental the same way when applied to arguments of boolean rather than integral types. However instead of calculating the 17
result on a bit by bit basis the boolean values are treated as single bits, with true corresponding to a 1 bit and false to a 0 bit. The general rules discussed in the previous section may be modified like this when appliced to boolean values a) For AND Operations, true AND true produces true and any other combination produces false. b) For XOR Operations, true XOR false produces true or false XOR true produces true and any other combination produces false. For OR Operation, false OR false produces false and for any other combination produces true. Operator ~ <<= >>= >>>= x&=y x|=y x^=y
Meaning Bitwise complement Left shift assignment (x = x << y) Right shift assignment (x = x >> y) Zero fill right shift assignment (x = x >>> y) AND assignment (x = x & y) OR assignment (x = x | y) XOR assignment (x = x ^ y)
Short Circuit Logical Operators The short circuit logical operators && and || provides logical AND and OR operations on boolean types. Note that there is no XOR operation provided. Superficially this is similar to the & and | operators with the limitation of only being applicable to boolean values and not integral types. However the && and || operators have a valuable additional feature: the ability to shortcircuit a calculation if the result is definitely known. This feature makes these operators central to a popular null-reference-handling idiom in java programming. The main difference between the & and && and the | and || operators is that the right hand side operand might not be evaluated at all. This behaviour is based on two mathematical rules that define conditions under which the result of a boolean AND or OR operations is entirely determined by one operand without regard for the value of the other: a) For a AND operation, if one operand is false, the result is false, without regard to the other operand. b) For an OR operation, if one operand is true, the result is true, without regard to the other operand. 18
Given these rules, if the left hand operand of a boolean AND operation is false, the result is definitely false whatever the right hand operand may be. It is therefore unnecessary to evaluate the right hand operand. Similarly, if the left hand operand of a boolean OR operation is true, the result is true and the right hand operand need not be evaluated. For Example if ((s != null) && (s.length() > 20)) { System.out.println(s); } Now here if the String reference is null, then calling the s.length() method would raise a NullPointerException. If we use the short-circuit && then that situation would not arise, because if (s != null) returns false, then the whole test expression is guaranteed to be false. Where the first operand is false then in && the second operand is not evaluated at all and the s.length () is not evaluated at all. The Ternary Operator: The ternary operator provides a way to code simple situations (if/else) into a single expression. The syntax for a ternary operator is (boolean condition) ? true : false. Here the boolean condition is evaluated and if the result is true then the value of the expression after the ? is evaluated (here true) otherwise it is the value after the colon will be evaluated ( here false). The sub expressions (true and false) on either side of the colon must have the same type. Example: int a = 10; int b = 20; inc c = (a>b)?40:50. This will give the value of c as 50, since (a>b) returns false and hence the right hand side of the colon will be evaluated. Assignment Operators The assignment operators set the value of a variable or expression to a new value. Simple assignment uses =. Besides simple assignments, compound “calculate and assign” is provided by operators such as += and *=. These operators does the
19
calculation and then assigns. The point to be noted here with the right hand operand must be a type that is assignment compatible with the left hand operand. Assignment operators. Expression x += y x -= y x *= y x /= y
Meaning x=x+y x=x-y x=x*y x=x/y
Evaluation Order or Operator Precedence.
Operator . [] ()
++ -- ! ~ instanceof
new (type)expression
*/% +<< >> >>> < > <= >= == != & ^ | && || ?: = += -= *= /= %= ^= &= |= <<= >>= >>>=
Notes Parentheses (()) are used to group expressions; dot (.) is used for access to methods and variables within objects and classes (discussed tomorrow); square brackets ([]) are used for arrays (this is discussed later on in the week) The instanceof operator returns true or false based on whether the object is an instance of the named class or any of that class's subclasses (discussed tomorrow) The new operator is used for creating new instances of classes; () in this case is for casting a value to another type (you'll learn about both of these tomorrow) Multiplication, division, modulus Addition, subtraction Bitwise left and right shift Relational comparison tests Equality AND XOR OR Logical AND Logical OR Shorthand for if...then...else Various assignments More assignments
20
You can always change the order in which expressions are evaluated by using parentheses around the expressions you want to evaluate first. You can nest parentheses to make sure expressions evaluate in the order you want them to (the innermost parenthetic expression is evaluated first). The following expression results in a value of 5, because the 6 + 4 expression is evaluated first, and then the result of that expression (10) is divided by 2: y = (6 + 4) / 2 Java Flow Control & Arrays The for Loop A common requirement in programming is to perform a loop so that a single variable is incremented over a range of values between two limits. This is frequently provided for by a loop that uses the keyword for. The primary purpose of a for loop is to execute a block of statements a given number of time. The for loop syntax is for (initialisation ; loop condition ; increment expression) { body of the loop; } The control for the for loop appears in parentheses followed by the keyword for. It has three parts separated by semi-colons. 1. The first part, initialisation is executed before the execution of the loop starts. This is typically used to initialise a counter for the number of loop iterations, for example i = 0. With a loop controlled by a counter, you can count up or doing using a integer or a floating point variable. It is only used to set up a starting conditions. 2. The second part is the loop condition, which means the execution of the loop continues as long as the condition you have specified in this is true. That means the loop conditions should be a boolean conditions which will either return a true or false. This loop conditions is checked at the beginning of each loop iteration and when it is false the execution stops and the program continues with the statement after the loop. A simple example of loop conditions is i < 10, which would mean that the loop would execute as long as the variable has a value less than 10 and the moment it increases the value of 10, the loop conditions will retune false the loop stops. 3. The third part the increment expression, is executed immediately after the body of the loop, just before the test is performed again. Commonly this is used to increment the loop counted. This could be i++, which will increment the loop counter by one. Of course you might want to increment the loop counter in steps 21
other than one and in that case you can write i +=2, in which case the loop counter gets increment by 2. Example for (int i = 0 ; i<5 ; i++) { System.out.println(“The value is now “ + i); } System.out.println(Out of the loop now); The above code prints The value is now 0 till The value is now 5 and then Out of the loop now. The execution is done in the following way a) First of all the loop is initialised to 0, then it check whether the boolean condition is true and in this case it is true since 0 is less then 5, then it goes into the body and the statement” The value is now 0 is printed.. b) Then it goes to the Iteration statement and this increments the value of the loop counter to 1 c) Then it again check the boolean condition and this continues till the boolean condition is false and once it is false, it comes out of the loop. d) Then the statements after the loop are executed. Note: The for () loop allows the use of comma operators in a special way. For example for (int i = 0, int j = 0 ; j <10 ; i++, j++) { } The above code initialise int i and int j to 0, the checks the boolean condition or conditions and then increments both the variables. The while Loop The while loop executes as long as the given logical expression in the parentheses is true and stop when the conditions becomes false. The syntax for the while loop is; while (boolean condition) { Statement; }
22
It is important to note here that the condition is checked at the beginning of the loop and hence if the condition is false initially, then the loop will not execute at all. Note here that in java the conditions can only be a boolean condition, while in C and C++ it can be a variety of types. The statement or statements will be executed again and again until the boolean condition becomes false. If the condition will never become false, then it will be a infinite loop. The do – while Loop The do – while loop is similar to the while loop and the only difference is that the boolean condition is after the body of the loop, which means that even if the condition is false, the loop will be executed atleast one. In programming, this loop is very important where we want a particular statement to execute atleast once. The syntax for the do loop is; do { statement; } while (boolean condition) Each iteration of the loop first executes the body and then evaluates the conditional expression. If this expression is true, then it will executed the body again and then check for the condition and this goes on till the condition becomes false. IMP: In general programming all of the above loops are used together and remember that all the above loops can be nested also. Java’s Selection Statement Java supports if – else and switch as its selection statements and we will discuss both of them in this section if Statement The if statement is used to route programs execution to different paths depending on a particular condition and the syntax for the same is; if (condition) { Statement; }
23
else { Statement; } As in the earlier cases, the condition checking the flow of control is a boolean condition and if the condition is true, then the if part body will be executed or the else part of the body will be executed. Example int a ; int b ; if (a>b) { int c = a; } else { int c = b; } In the above example we want the value of int c to be the higher value amount a and b and this we do not know and hence we will use the if loop and if (a>b) then the value of int c will be the value of a and if int b is higher then the value of int c will be the value of int b as stated in the else part of the body. Nested ifs A nested if is an if statement that is the target of another if or else. Nested ifs are very common in programming and when you nest a if, the important point to remember is that an else statement always refer to the nearest if statement that is within the same block as the else. It is very important that you use block of codes, when using the nested ifs or otherwise you will find a result other than what you were expecting. if-else-if ladder The if-else-if ladder syntax looks like this if (condition) { Statement; 24
} else if (condition) { Statement; } else if (condition) { Statement; } else { Statement; } The if condition in the first if will be considered and like the normal if-else will not go to the else part, but it will check the else if condition and like this it goes down the ladder. After the last else if is encountered and then also the condition is not true then the else statement at the end of the ladder will be executed. Remember, if the last else statement is not there and if all the else if condition returns false then nothing will be executed. switch Statement If you need to make a choice between multiple alternative execution paths and the choice can be based on an int value, then you should use the switch () construct. It is better than the if-else-if construct. The syntax is as under: switch (expression) { case value1: { Statement; } case value2: { Statement; } case value3: { 25
Statement; } break; default: { Statement; } It is very important to note here that the expression must be of type byte, short, int or char and each of the values in the cases (eg. case value1 ....) must be type compatible with the expression and each case should be a unique (eg. it should not be a constant or a variable). Duplicate case values are also not allowed. The switch starts off with a expression and the value is compared with each of the literal values in the case statements and if a match is found then the body of that case value is executed and if none of the case values are matched the default block is always executed. The default is optional here and if no matching case if found and there is no default then nothing will be executed. One can use the break statement inside a switch to terminate a statement sequence. When a break statement is encountered, the execution branches to the first line of code that follows the entire switch statement. The switch statement differs from the other loops in that the switch can only test for equality, where as the other loops test for boolean condition. That is the switch looks only for a match between the value of the expression and one in its case and has nothing to do with the boolean conditions. Jump Statements The java’s jump statements help in transferring control to another part of the program. Java has three jump statements that are break, continue and return. Using break statements Break can be used for 3 reasons a) breaking out of the switch statements b) breaking out of a loop c) Labeled break to enable transfer to a particular point in the code. Using Break to exit out of a loop
26
We can use break to force immediate termination of a loop and thereby bypassing the conditional expression and any remaining code in the body of the loop. When break statement is encountered inside a loop, the loop is terminated and the program control resumes at the next statement following the loop. Let’s see a example class Test { public static void main(String args[]) { for (int i=0 ; i<100 ; i++) { if (i==10) { break;} } System.out.println(“The value of loop is “ + i); } System.out.println(“ The loop is complete”); } } The above program is to print the numbers from one to hundred, but we are having a if condition which states that if i is equal to 10, then it should break out of the loop and then it will print the statement that loop is complete. The above program generates numbers till “The value of i is 9” and then will exit out of the loop and then the next statement that “The loop is complete” will be printed out. The following points are also important regarding the break statement: a) The break statement is used to exit out of infinite loops. b) When used inside nested loops, the break statement will come out of the innermost loop and the execution of the outer loops will continue. Using Labeled Break Java also makes a labeled break available to you, by which you can exit out of any block with the respective block name. It is not necessary that it have to be a loop or switch. The labeled break enables you to break out to the statement following an enclosing block that has a label regardless of how many levels there are. You might have nested blocks and you can exit out of any nested block or blocks by using the respective block name (label) and the only important point here is that you will have to name the block with the name. For Example Block 1 { 27
Block 2 { Block 3 { break Block 2 (here i can break out of any block, either 3,2 or 1) } } The break statement inside block 3, tells to break out of block 2 and hence the point of execution will be switched here and any statement after the break will not be executed. } Continue Statement Sometimes it is useful to force an early iteration of a loop. That is, you might want to continue running the loop, but stop processing the remainder of the code in its body for this particular iteration. For Example. If we want to sum the values of integers from 1 to some limit except that we do not want to include integers that are multiples of 3. We can do this using an if and continues statement. for(int i =1 ; i <= limit ; i++) { if (i % 3 == 0 ) { continue; sum+=1; } } The continue statement is executed in this example when i is an exact multiple of 3, causing the rest of the current loop iteration to be skipped. The program execution continues with the next iteration if there is one and if not with the statement following the end of the loop body. The continue statement can appear anywhere within a block of loop statements. The labeled continue statement Where you have nested loops, there is a special form of the continue statement that enables you to stop executing the inner loop – not just the current iteration of the inner loop – and continues at the beginning of the next iteration of the outer loop that immediately enclosed the current loop. The important point to note here is that to use the continue statement, you need to identify the loop statement for the enclosing outer and inner loop with a statement label. A statement label is simply an identifier that is used to reference a particular statement. When you need to reference a particular statement, you write the statement label at the beginning of the statement in question and separated from the statement by a colon. 28
class Test { public static void main (String args[]) { outer: for (int i = 0 ; i < 10 ; i++) { for (int j = 0 ; j < 10 ; j++) { if (j > i) { System.out.println(); continue outer; } System.out.print( “ “ + (i * j) ); } } System.out.println(); } } Here the continue statement executes the j loop when i is greater than j and continues with the next iteration of i. Arrays Array is a group of similar kind of data types that is reference by a common name. Suppose if we want a group of integers from 1 to 100 to be reference by a common name, we create an array of them. Each variable in an array is called array element. It is important to note that the array numbering stars from 0 and not 1. Array is an object and not a primitive, even if it is made up of primitives. Like objects, array required initialisation and declaration only creates a reference to the array. To explain in depth, to create a array is to 3 steps a) Declaration b) Creation c) Initialisation Declaration One is not obliged to create the array itself when you declare the array variable. The array variable is distinct from the array itself. This is how one declares a array. int a [] String s []
-
This is a array of integers with the variable a This is a array of strings with the variable s 29
Creation Once you declare an array of any data type, you should create the same with the help of the new keyword and the same is done like this a = new int [10]; s = new String [5]; The above example shows that the array with the variable a will store integers up to 10 values and the second example creates that the s (String variable) will store Strings up to 5 values. Remember: The array length starts from 0 The creation of array only reserves the space in memory for 10 integers and 5 strings, but nothing is inside it. Initialisation Once we have the memory reserved, we can put values into each of the individual spaces like this: a[0] = 10; This puts 10 as the first value of the array a[1] = 20; This puts 20 as the second value of the array and so on. Similarly we can put strings into the 5 spaces as under; s[0] = “Dots” and so on. Direct Declaration and Creation The above 1 and 2 steps can be do simultaneous like this int a [] = new int [10]; It is important to note that the [] box can be put before or after the array variable. This is also correct. int [] a = new int[10]; Direct Initialisation
30
Since the above process is cumbersome, we can initialise an array with your own values when you declare it and at the same time determine how many elements it will have. This is done as below: int a [] = { 1,25,30,55} This creates an array with variable name as a and with values as put into the {} and with 4 elements. Accessing Array Values You can refer to an element of an array by using the array variable followed by the element’s index value enclosed between square brackets. For Example. Existing Array: int a [] = { 1,25,30,55} If we have to access the 2nd element of the array, we will do it like this int a[1], here we use 1 because, as said earlier, the array indexing begins with 1. Important: Any attempt to access array indexes beyond the length of the array causes runtime error. For example: If we try to access the 5th element, it will give a runtime error, because there is no 5th element in the array. Array Bounds In the java programming language, all array subscripts begin at zero. The number of elements in an array is stored as part of the array object, as the length attribute. This value is used to perform bounds checking of all runtime accesses. If an out-bounds access occurs, then a runtime error occurs. Use the length attribute to iterate on an array as follows: int list[] = new list [10]; for (int I = 0 ; I < list.length ; I++) { System.out.println[i]; ) Using the length attribute makes the program maintenance easier Array resizing Once created, an array cannot be resized. However you can use the same reference variable to refer to an entirely new array. Since an array cannot be resized, this is the biggest limitation of arrays. 31
int d[] = new int [6]; d = new int [10]; In this case, the first array is effectively lost unless another reference to it is retained elsewhere. Array Copying The java language provides a special method in the System class arraycopy () to copy arrays. The syntax for copying array is: System.arraycopy ( original array, 0 (index to start with), new array, 0 (index of new array from where copying has to start), original array.length (or number of references to be copied); The above method can be proved with the help of this example. // original array.
int a[] = {1,2,3,4,5,6};
// new larger array. int d[] = {10,9,8,7,6,5,4,3,2,1}; System.arraycopy{a,0,d,0,a.length); After this, the array d will have the following content: 1,2,3,4,5,6,4,3,2,1} Note: The method System.arraycopy() copies, references, not objects, when dealing with array of objects. The objects themselves do not change. Multi-Dimensional Arrays We have only worked with one-dimensional arrays up to now, that is arrays that use a single index. Why would you ever need the complications of using more indexes to access the elements of an array? Suppose that you have a fanatical interest in the weather and you are intent on recording the temperature each day at 10 separate geographical locations throughout the year 1999. Once you have sorted out the logistics of actually collecting this information, you can use an array of 10 elements corresponding to the number of locations, where each of these elements is an array of 365 elements to store the temperate values. You would declare this array with the statement float temperature [] [] = new float [10] [365]; 32
There are 10 arrays each having 365 elements. In referring to an element, the first square brackets enclose the index for a particular array, and second pair of square brackets enclose the index value for an element within that array. So to refer to the temperate for day 100 for the sixth location, you would use temperature [5] [99]. In java, multidimensional arrays are actually array of arrays. To declare a multidimensional array a variable, specify each additional index using another set of square brackets. For example, the following declares a two-dimensional array variable called D. int D [] [] = new int [2] [4] The above array creates and allocated a 2 by 4 array. Internally this acts like a matrix in which the first square bracket is for the number of rows and the second bracket is for the number of columns. Remember: Note that you can have an array with 0 columns but not with 0 rows. For example int D[] [] = new int [2] [0]
-
Ok
int D[] [] = new int [0] [2]
-
Not Ok.
Objects & Classes In essence a class definition is very simple and it contains just two kinds of things: a) Variables: These are variables that store data items that typically differentiate one object from another. These are known as data members of a class. The variables in a class definition can be any of the basic data types or they can be references to objects of any class type, including the one that you are defining. b) Methods: These define the operations you can perform for the class – so they determine what you can do to or with objects of the class. Methods typically operate on the variable of a class, though not necessarily as we have seen in the examples we have seen until now. Variables An object of a class is also referred to as an instance of that class. When you create an object, the object will contain all the variables that were included in the class definition.
33
However, the variables in a class definition are not all the same – these are of two kinds. One kind of variable in a class is associated with each object uniquely – each instance of the class will have its own copy of these variables with its own value assigned. This differentiates one object from another – giving an object its individuality. These are known as instance variables. However please note that this do not change the original variable defined in the class. The other kind of class variable is associated with the class and is shared by all objects of the class. There is only one copy of this kind of variable and if any object changes the value of this variable the original value is changed. These are known as class variables because they belong to the whole class and not to any specific object. These variable are also referred to as static variables. The New keyword If we have to create an object for a particular class, the same can be done with the help of a new keyword. For example class Test { int a; int b; double c; } The above class is just a template for any object creation and a new object is created with the help of the following syntax: Test a = new Test(); Here a is just a handle for the Test and is an instance of Test. When you create an object of class Test, it will have its own copy of the instance variables defined by the class. Thus every Test object will have its own copies of int a, int b and double c. Over here it is important to note that a is a variable that refer to an object. The following examples create new instances of the classes String, Random, and Motorcycle, and store those new instances in variables of the appropriate types: String str = new String (); Random r = new Random(); Motorcycle m2 = new Motorcycle();
34
The parentheses are important; don't leave them off. The parentheses can be empty (as in these examples), in which case the most simple, basic object is created; or the parentheses can contain arguments that determine the initial values of instance variables or other initial qualities of that object: Date dt = new Date (90, 4, 1, 4, 30); Point pt = new Point (0,0); The number and type of arguments you can use inside the parentheses with new are defined by the class itself using a special method called a constructor (you'll learn more about constructors later today). If you try and create a new instance of a class with the wrong number or type of arguments (or if you give it no arguments and it needs some), then you'll get an error when you try to compile your Java program. Memory allocation and layout When variables of any primitive type - that is boolean, int, etc - are declared, the memory space is allocated as part of the operation. The declaration of a variable using a non-primitive type – that is an object does not allocate space for the object. It is the new keyword that implies allocation and initialisation of storage. Getting Values To get to the value of an instance variable, you use an expression in what's called dot notation. With dot notation, the reference to an instance or class variable has two parts: the object on the left side of the dot and the variable on the right side of the dot. New Term Dot notation is an expression used to get at instance variables and methods inside a given object. For example, if you have an object assigned to the variable myObject, and that object has a variable called var, you refer to that variable's value like this: myObject.var; This form for accessing variables is an expression (it returns a value), and both sides of the dot can also be expressions. This means that you can nest instance variable access. If that var instance variable itself holds an object and that object has its own instance variable called state, you could refer to it like this: myObject.var.state;
35
Dot expressions are evaluated left to right, so you start with myObject's variable var, which points to another object with the variable state. You end up with the value of that state variable after the entire expression is done evaluating. Changing Values Assigning a value to that variable is equally easy-just tack an assignment operator on the right side of the expression: myObject.var.state = true; Determining the Class of an Object Want to find out the class of an object? Here's the way to do it for an object assigned to the variable obj: String name = obj.getClass().getName(); What does this do? The getClass() method is defined in the Object class, and as such is available for all objects. The result of that method is a Class object (where Class is itself a class), which has a method called getName(). getName() returns a string representing the name of the class. Another test that might be useful to you is the instanceof operator. instanceof has two operands: an object on the left and the name of a class on the right. The expression returns true or false based on whether the object is an instance of the named class or any of that class's subclasses: "foo" instanceof String // true Point pt = new Point(10, 10); pt instanceof String // false The instanceof operator can also be used for interfaces; if an object implements an interface, the instanceof operator with that interface name on the right side returns true. We will study about the instanceof operator in details. Constructor As already stated the new keyword dynamically allocated memory for an object. We can create an object of a class with the new keyword and the class name is followed by parentheses specifies the constructor for the class. Constructors define that occurs when an object of a class is created. Most of the real world classes define their own constructors and incase there is no explicit constructor defined in a class, java provided its own constructor.
36
A constructor always has the same name as the class in which it is defined, has no return type specified, and must not include a return statement. You can always specify a constructor with any parameters as the arguments and anything in the body, which will be guaranteed to be initialised when we use the new keyword. A default constructor has nothing in its body and has no arguments in it. The constructor is an unusual type of method because it has no return value. This is distinctly different from a void return value, in which the method returns nothing but you still have the option to make it return something else. Constructors return nothing and you don’t have an option. If there were a return value, and if you could select your own, the compiler would somehow need to know what to do with that return value. Example using constructor: class Test { int a,b,c; Test() { System.out.println(“This is inside the constructor”); a = 10; b = 5; c = 5; } int met1() { return int d = a x b x c; } public static void main (String arg[]) { Test t = new Test(); Test s = new Test(); int z = t.met1();
37
int y = s.met1(); System.out.println(z); System.out.println(y); } } Result: The result will be This is inside the constructor This is inside the constructor 250 250 As you will see both the object variables z and y were initialised with the constructor Test, when they were created. Since the constructor gives all the object the same dimensions, the volumes with both the object are 250. With the new keyword a constructor is called, if available and if not a default constructor is called. The default constructor initializes all instance variables to zero. But it is important to note that once you define your own constructor, the default constructor will not be called. Invoking Overloaded Constructors If you have a class with several constructors, you might want to duplicate the effect of one inside a different one. This can be achieved using the keyword this as a method calls. For example: public class Employee { private String name; private int salary; public Employee (String n, int s) { name = n; salary = s; } public Employee(String n) { this(n,o); } 38
public Employee() { this (“unknown”); } } In the above example, the second constructor that has one String argument, the call this(n,0) passes control to the version of the constructor that takes one String argument and one int argument. In the third constructor, which has no arguments, the call this (“unknown”), passes control to the version of constructor that takes one String argument. IMP: Any call to this, if present, must be the first statement in any constructor. Assignment of object reference variables Object reference variable act different than the primitive data type reference variables. When we say int a = 10; int b = a; here infact another object is created when a is referenced to b, because they are of primitive data type and we have already seen, memory space is allocated as a part of the operation itself. However. if we say Test a = new Test(); Test b = a; here b is being assigned a reference to a copy of the object referred to by a. One might be tempted to think that a and b refer to different object, but this is wrong. Instead after this fragment executes, a and b refer to the same object. Here the assignment of a to b did not allocate any memory or copy any part of the original object, it just made b also refer to the same object as done by a. Thus any changes made on the object through b will affect the object to which a is also referring since they are the same object. Although a and b are referring to the same object, they are not linked in any way. At a later date, a might be made to refer to another object and at that time b will still be referring to the same object. Imp: When you assign one object reference variable to another object reference variable, you are not creating a copy of the object, you are only making a copy of the reference. 39
Introducing Methods Methods that you define for a class provide the actions that can be carried out using the variables specified in the class definition. Method is a self-contained block of code that has a name and has some property that it is reusable – the same method can be executed from as many different points in a program as you require. A method is executed by calling the method using its name, as will see and a method may or may not return a value, but the return type is mandatory before the method name. The general form of a method is: <modifier> (<argument list>) throws <exception (if any)> { block of code; } 1) The modifier segment can carry out a number of different modifiers including public, protected, default (no modifier) and private. This determines the accessibility of the method. We will at a later stage go into each of the different modifiers 2) The return type is mandatory for any method. We have seen in the main () that we write void which tell the compiler that the method will not return anything. If the method returns anything it must be specified before the modifiers name and if not so the compiler will give a compile time error. Java is very particular about what the method returns. If we write that the method returns int and incase it returns any other data type, the compiler again will complain. Use the return command within a method to pass back a value. 3) The name is the name of the method, by which it will be referenced later on in the source codes. 4) The argument list allows argument values to be passed into a method. Elements of the list are separated by a comma, while each element consist of a type and an identifier. 5) The throws (exception) clause cause a runtime error (exception) to be reported to the calling method so as to handle it in a suitable manner Similar to the variables, there are also two methods known as instance methods and class or static methods. One can execute class methods without any object of the class also, whereas for instance methods, an object of the class should be there. Since the class methods are declared using the static keyword, they are also called as static methods.
40
Since class methods are executed when there are no objects in existence, they cannot refer to instance variables. This is quite sensible – if you think about it - trying to operate with variables that might not exist would be bound to cause trouble. Java will not allow you to try and will give a compile time error. The best example of a class / static method is the main method and you declare the same with the keyword static. This is because the main() is the method from where the execution starts in an application and before an application can start no objects will exist and hence the main() will have to be declared as static. Accessing Variables and methods. In many circumstance, you would want to refer to a constant or a variable or a method of a particular class in another class. There are two rules for it a) A static member of a class can be accessed using the class name, followed by a period, followed by the member name. With a class method, you also need to supply the parentheses enclosing any arguments to the method after the method name. The period here is called the dot operator. So if you want to calculate the square root of PI you could access the class method sqrt() and class variable PI that is defined in the Math class as follows: double a = Math.sqrt (Math.PI); b) Instance variables and method can only be called using an object reference, as by definition they relate to a particular object. The syntax is exactly the same as we have outlined for static members. You put the name of the variable referencing the object followed by a period, followed by the member name. For example: class Test { int a,b,c; public static void main (String arg[]) { Test t = new Test(); t.a = 10; t.b = 5; t.c = 5; int z = t.met1(); 41
System.out.println(z); } int met1() { return int d = a x b x c; } } The above can be described in the following steps: a) We have 3 class variables which are declared and have variable names of a, b and c. b) We also have a method called met1, which will multiply the class variable a , b and c. c) We create a object referenced by the object handle t. d) We assign values for a, b and c for the object created reference by the name t. e) Then we call the method met1() referenced by the object handle t. f) The int returned by the met1() is stored in z. g) The value of z is displayed. To ensure that different values can be given to the class variable referenced by the object handle, we create another method inside the same class Test and see the result. The revised code looks as under: class Test { int a,b,c; public static void main (String arg[]) { Test t = new Test(); t.a = 10; t.b = 5; 42
t.c = 5; int z = t.met1(); System.out.println(z); Test s = new Test(); s.a = 8; s.b = 9; s.c = 6; int x = s.met1(); System.out.println(x); int met1() { return int d = a x b x c; } } Result: We see from the above example that different result are displayed for z and x, which proves the point the different objects take different values for the class variables. Method that takes arguments We will have to differentiate between the terms arguments and parameter. The parameter list that appears between the parentheses following the method name, specifies the type of each value that can be passed as an argument to the method and the variable name that is to be used in the body of the method to refer to the value passed. The following is the difference between the parameter and argument: a) A parameter has a name and appears in the parameter list in the definition of a method. b) A argument is a value that is passed to a method when it is executed and the value of the argument is referenced by the parameter name during the execution of the method.
43
class Test { public static void main (String arg[]) { Test t = new Test(); int z = t.met1(10,5); System.out.println(z); } int met1(int a, int b) { return int c = a x b; } } In the above example we have a method met1(). The method has two parameters int a and int b, that are used to refer to the arguments 10 and 5 respectively within the body of the method. When you call a method from another method (like main()), the values of the arguments passed are the initial values assigned to the corresponding parameters. You can use any expression you like for an argument when you call a method, so long as the value it produces is of the same type as the corresponding parameter in the definition of the method. How argument values are passed !! This is one of the most important and the most confusing part of java fundamentals. In java, all arguments values that belong to one of the basic types are transferred to a method using what is called the pass-by-value mechanism. All this means is that for each argument value that you pass to a method, a copy is made and it is the copy that is passed and referenced through the parameter name and not the original value. This implies that if you use a variable of any of the basic types as an argument, the method cannot modify the value of the main variable in the calling program. For example; class Test { public static void main (String arg[]) { 44
int i = 10; Test t = new Test(); int z = t.met1(i); System.out.println(z); System.out.println(i); } int met1(int a) { ++a; return a; } } In the above example, what is passed as an argument to the met1() is a copy (value) of i and not the actual i and hence what is returned is 11, caught by int z, while the value of i remains contact at 10. The this keyword Every instance method has a variable with the name, this which refers to the current object for which the method is being called. This is used implicitly when your method refers to an instance variable of the class. In the body of a method definition, you may want to refer to the current object-the object in which the method is contained in the first place-to refer to that object's instance variables or to pass the current object as an argument to another method. To refer to the current object in these cases, you can use the this keyword. this can be used anywhere the current object might appear-in dot notation to refer to the object's instance variables, as an argument to a method, as the return value for the current method, and so on. Here's an example: t = this.x; // the x instance variable for this object this.myMethod (this); // call the myMethod method, defined in // this class, and pass it the current // object return this; // return the current object In many cases you may be able to omit the this keyword entirely. You can refer to both instance variables and method calls defined in the current class simply by name; the this is implicit in those references. So the first two examples could be written like this: 45
t=x // the x instance variable for this object myMethod(this) // call the myMethod method, defined in this // class Note Omitting the this keyword for instance variables depends on whether there are no variables of the same name declared in the local scope. See the next section for more details on variable scope. Keep in mind that because this is a reference to the current instance of a class, you should only use it inside the body of an instance method definition. Class methods-that is, methods declared with the static keyword-cannot use this. Initialisation Blocks A initialisation block is a block of code between braces that is executed before an object of the class is created. This is normally used with the static keyword and this block is executed once when the class is loaded and can only initialise static data members of the class. All the other methods are initialised after the static initialisation block. If you want your variables to be started with a particular values, then you can put the same in the static initialisation block and can then use the variables in the other methods. Passing objects to a method. Until now we have seen that only simple types are parameters to methods. However it is very common and correct to pass objects to methods. One of the most common use of object parameters involves constructors. Frequently you will want to construct a new object so that it is initially the same as some existing object. To do this, you must define a constructor that takes an object of its class as a parameter. Passing objects to the parameter is known as call-by-reference. In this method, a reference to an argument (and not the value of the argument) is passed to the parameter. Inside the method, this reference is used to access the actual argument specified in the call. This means that changes made to the parameter will affect the argument used to call. Example of call by reference: class Test { int a,b Test (int i, int j) 46
{ a = i; b = j; } void met1( Test o) { o.a *= 2; o.b /= 2; } class Byref { public static void main (String arg[]) { Test z = new Test(15,20) System.out.print(“Value before call “ + z.a+ “ “ + z.b)” z.met1(z); System.out.print(“Value after call “ + z.a+ “ “ + z.b)” } } As you will see the values keep on changing if you pass objects as parameters. Another Example of this is. The PassByReference class 1: class PassByReference { 2: int onetoZero(int arg[]) { 3: int count = 0; 4: 5: for (int i = 0; i < arg.length; i++) { 6: if (arg[i] == 1) { 7: count++; 8: arg[i] = 0; 9: } 10: } 11: return count; 12: } 13: public static void main (String arg[]) { 14 int arr[] = { 1, 3, 4, 5, 1, 1, 7 }; 15: PassByReference test = new PassByReference(); 16: int numOnes; 47
17: 18: 19: 20: 21: 22: 23: 24 25: 26: 27: 28: 29: 30: 31: 32:}
System.out.print("Values of the array: [ "); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println("]"); numOnes = test.onetoZero(arr); System.out.println("Number of Ones = " + numOnes); System.out.print("New values of the array: [ "); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println("]"); }
Values of the array: [ 1 3 4 5 1 1 7 ] Number of Ones = 3 New values of the array: [ 0 3 4 5 0 0 7 ] Analysis Note the method definition for the onetoZero() method in lines 2 to 12, which takes a single array as an argument. The onetoZero() method does two things: It counts the number of 1s in the array and returns that value. If it finds a 1, it substitutes a 0 in its place in the array. The main() method in the PassByReference class tests the use of the onetoZero() method. Let's go over the main() method line by line so that you can see what is going on and why the output shows what it does. Lines 14 through 16 set up the initial variables for this example. The first one is an array of integers; the second one is an instance of the class PassByReference, which is stored in the variable test. The third is a simple integer to hold the number of ones in the array. Lines 18 through 22 print out the initial values of the array; you can see the output of these lines in the first line of the output. Line 24 is where the real work takes place; this is where you call the onetoZero() method, defined in the object test, and pass it the array stored in arr. This method returns the number of ones in the array, which you'll then assign to the variable numOnes. 48
Got it so far? Line 25 prints out the number of 1s (that is, the value you got back from the onetoZero() method). It returns 3, as you would expect. The last bunch of lines prints out the array values. Because a reference to the array object is passed to the method, changing the array inside that method changes that original copy of the array. Printing out the values in lines 27 through 30 proves this-that last line of output shows that all the 1s in the array have been changed to 0s. Creating Methods with the Same Name, Different Arguments Yesterday you learned how to create methods with a single name and a single signature. Methods in Java can also be overloaded-that is, you can create methods that have the same name, but different signatures and different definitions. Method overloading allows instances of your class to have a simpler interface to other objects (no need for entirely different methods with different names that do essentially the same thing) and to behave differently based on the input to that method. For example, an overloaded draw() method could be used to draw just about anything, whether it were a circle or a point or an image. The same method name, with different arguments, could be used for all cases. When you call a method in an object, Java matches up the method name and the number and type of arguments to choose which method definition to execute. New Term Method overloading is creating multiple methods with the same name but with different signatures and definitions. Java uses the number and type of arguments to choose which method definition to execute. To create an overloaded method, all you need to do is create several different method definitions in your class, all with the same name, but with different parameter lists (either in number or type of arguments). Java allows method overloading as long as each parameter list is unique for the same method name. Note that Java differentiates overloaded methods based on the number and type of parameters to that method, not on the method's return type. That is, if you try to create two methods with the same name and same parameter list, but different return types, you'll get a compiler error. Also, the variable names you choose for each parameter to the method are irrelevant-all that matters is the number and the type. Is-a and Has-a Relationship In programming language, one often creates a model of something (for example, an employee) and then need a more specialized version of that original model. For example, you might want a model for a manager, which only has more features but is still an employee. The Is-a relationship in java is done with the help of extends keyword which creates a new class from an existing class, by sub-classing it. 49
For Example: class Employee { String name; int salary; Date hiredate; } class Manager extends Employee { String department; } In the above example, when we sub-class the class Manager, the Manager class will have all the variable and methods that an Employee has. All these variables and methods are inherited from the definition of the parent class. The class Manager then adds additional functionality to itself by defining its own variables and methods. The has-a relationship comes when a particular variable or method is inside a particular class. For example in the above class Employee, we can safely say class Employee has a name. instanceof Operator When we pass objects around using references to their parents, many a times we need to know whether the object belongs to a particular parent or no. Using the instanceof Operator one can do this. The instanceof Operator tests the class of an object at runtime. The left-hand argument can be any object reference expression, usually a variable or an array element while the right-hand operand must be a class, a interface or an array type. You cannot use java.lang.Class object or its string name as the right hand argument. The instanceof operator returns true if the class of the left hand argument is the same as or is some subclass of the class specified by the right hand operand. If the left hand argument is a null value, the instanceof test simply returns false – it does not cause an exception. For Example: class Employee class Manager extends Employee class Contractor extends Employee.
50
In one receives a object using a reference to type Employee, it might turn out to be a Manager or an Employee. Manager m = new Manager(); Contractor c = new Contractor(); (m instanceof Employee) returns true, while (c instance of Manager) returns false, because Manager and Contractor is not related at all. finalize() method We have already learnt about the concept of Garbage Collection, which is done by a system level thread, which will collect an object, which is of no use. But sometimes an object will need to perform some action when it is destroyed. In many cases a particular java object may be holding some non-java resource such as a window character font etc and we must make it sure that these resources are freed before an object is destroyed. To handle such cases, java has a mechanism called finalization. By using finalization, one can define specific actions that will occur, before the garbage collector reclaims the object. To add a finalize to a class, one needs to just define the finalize method. The Java environment calls that method whenever it is about recycle an object of that class. Inside the finalize () method you specify those actions which must be performed before the object is destroyed. The general form of a finalize () is: protected void finalize() { finalization code; } Here the keyword protected is a specifier that prevents access to finalize () by code defined outside its class. It is important to note here that the method is not called when an object goes out-of-scope. The finalize () method is a member of the Object class. Since all classes inherit from the Object class, your classes also contain the default finalize () method. This gives you an opportunity to execute your special cleanup code on each object before the memory is reclaimed. Stack class
51
Stack class is one of the class, which stores data using first-in-last-out ordering. The Stack class represents a last-in-first-out (LIFO) stack of objects. It extends class Vector with five operations that allow a vector to be treated as a stack.
Method Summary boolean empty() Tests if this stack is empty. Object peek() Looks at the object at the top of this stack without removing it from the stack. Object pop() Removes the object at the top of this stack and returns that object as the value of this function. Object push(Object item) Pushes an item onto the top of this stack. int search(Object o) Returns the 1-based position where an object is on this stack. The following Example shows how to use the methods of the class Stack. class Stack1 { static int tos; int s[] = {10,15,20}; public static void main(String arg[]) { Stack1 a = new Stack1(); a.push(8); a.pop(); } Stack1() { tos=1; }
52
void push (int i) { if (tos==9) { System.out.println("The Stack is full"); } else { s[++tos] = i; System.out.println("The value pushed is " + i); } } int pop() { System.out.println("The value popped out is"+ s[tos]); return s[tos]; } } Another Example: public class Stack { Vector theStack; public Object push(Object o) { theStack.addElement(item); return o; } public Object pop() { Object o; int len = theStack.size(); o = peek(); theStack.removeElementAt(len - 1); return o; } public Object peek() { 53
Object o; int len = theStack.size(); if (len == 0) throw new EmptyStackException(); return theStack.elementAt(len - 1); } public boolean empty() { if (theStack.size() == 0) return true; else return false; } public int search(Object o) { int i = theStack.lastIndexOf(o); if (i >= 0) return theStack.size() - i; return -1; } } Access Modifiers We have already studied about encapsulation, which links data with the code that manipulates it. Encapsulation also provides another important feature and that is Access Control. It is through encapsulation that you can control what parts of the code (that is variables and methods) can be accessed by members of other classes which call upon code from your class. Public Access Modifier When a member of a class is having a public access modifier then that member can be accessed by any other code in your program. Remember our original program whether we had used public access modifier in our main (). This is done so to enable the code outside the program – that is the Java run-time system to call it. Private Access Modifier There are many situations when we want some data members or methods which access those data members to be accessed by that class and not to be accessed by 54
any other class either by way of inheritance or by way of creation of objects. This can be done by prefixing the members of the class with the keyword private. The variables / methods prefixed with the private access modifier can be used only within that particular class. Other classes, which extend this class, also cannot access these variables. This keyword provides the maximum security. For Example class Test { public static void main (String arg[]) { int i = 10 private int j = 10 } } class Test1 extends Test { public static void main (String arg []) { System.out.println (j); // it is not possible to access j since it is private. } } Understanding Static static variable As we have discussed earlier variables, which are, declared as static have got only one copy and any change made to them change the original also. When objects of its class are declared, no copy of a static variable is made. Instead all instances of the class share the same static variable, When we want a variable that is common to all the objects and accessed without using a particular object that is the member belongs to the class as a whole rather than the objects created from the class, we use the static variables. If we need to do some computation in order to initialise our static variable, we can declare a static block with gets executed exactly once, when the class is first loaded. Remember, the static block gets initialised before any other method. Between the static initialisation of a variable and static block, the static variable gets initialised ( with a declaration cum initialisation statement) and then the static initialisation block gets executed and then the other methods including the main ().
55
static methods This also has the same funda as that of the static variable. The static methods can be directly called without the creation of an object and then using the method. For nonstatic methods, one has to create an object and then use those methods, but static methods have this exception. If one has to use the static variables or method outside the class, we just need to add the classname before the variable / method and the same will be executed. For example, all the methods in java.lang.Math class are static because they get no data from within their class except for a few static final constants. So there is no need to instantiate them. This is because the static variables and static methods are common for the whole class The static methods however have several restrictions as: a) b) c) d) e)
They can only call other static methods. They must only access static data They cannot refer to this or super in any way. static methods cannot be overridden to be non-static. Non-static methods can access static methods, but not vice-versa
How Constructors are called? When there is multi level hierarchy, in what order are constructors called. The constructors are called in the order of derivation from superclass to subclass. It is important to note here that this order is followed irrespective of whether super () is used or not. If super () is not used, then the default or parameterless constructor is used. super keyword The super keyword refers to the superclass of the class in which the keyword is used. The super keyword has two general forms: a) The super keyword is also used to invoke the parent class’s constructor from the child class’s constructor. For this one should use the super keyword in the first line of the child class’s constructor. IMP: If one uses the super with no argument in the child’s class’s constructor, then this will call the default parent class constructor and if such a constructor is not available in the parent class, then a compile error results. For Example:
56
class Employee { String name; pubic Employee (String s) { name = s; } } class Manager extends Employee { String department; public Manager (String s, string d) { super(); // this will cause a compile error, because there is no default constructor in Employee. super(s) department = d; } } When a subclass calls super (), it is calling the constructor of its immediate superclass. Thus super () always refers to the superclass immediately above the calling class. This is true even in a multileveled hierarchy. b) The second use of super is to refer to the member variables or methods of the superclass that is hidden by the subclass. This is also like this, except that it always refers to the superclass of the subclass in which it is used. The syntax for the same is: super.member. (Here the member can either be a variable or a method) It is used more in those cases when the variable name of a subclass hides the members by the same name of the superclass. For Example: class First { int i; } class Second extends First { 57
int i; Second (int a, int b)// constructor { super.i = a; i = b; } void method() { System.out.println( “ This is superclass i “ +super.i); System.out.println( “ This is superclass i “ +i); } class Super { public static void main (String arg []) { Second s = new Second(10,25); s.method() } } This example shows how to use the super keyword in the second context. Method Overriding If a method is defined in a subclass that has the same name and return type exactly as that of the superclass (or parent class), then the new method is said to override the old one. When an overridden method is called from within a subclass, then it will always refer to the version of that method defined by the subclass. Note: Remember that methods with the same name, but with different argument lists that are in the same class are simply overloaded and not overridden. For Example: The Source Code file name should be Tes.java class One { void show() { int i = 10; int j = 20; System.out.println(" The value of i and j are " + i+""+j); 58
} } class Two extends One { void show() { int a = 50; int b = 60; System.out.println(" The value of a and b are " + a+""+b); } } class Tes { public static void main(String arg[]) { Two t = new Two(); t.show(); } } This will print out the show () of the object, which is created. If one has to use the show () of the superclass then we can use the same as super.show (), which will use the show () of the super class. Virtual Method invocation We have learnt earlier that it is possible to cast objects of a super class to a subclass and to automatically allow a subclass object to a superclass. After doing this if we call a method with the handle after the normal conversion is done, then we get the behaviour associated with the runtime type of the variable (that is, the type of the object referred to by the variable) and not the behaviour associated with the compile time type of the variable. This is also known as dynamic method dispatch. The Virtual Method invocation is a mechanism by which a call to an overridden function is resolved at run time rather than compile time. How does this happen. a) A superclass variable can access a subclass object. Java uses this fact to resolve calls to overridden methods at runtime. b) When a overridden method is called through a superclass reference, java determines which version of that method to execute based upon the type of the 59
object being referred to at the time when the call occurs. Thus this determination is done at runtime. c) In other words, it is the type of the object being referred to and not the type of the reference variable. Rules about overriding methods The following rules are mandatory and apply to overridden methods: a) The return type of overriding method must be identical to the method it overrides. This would mean that even if the arguments are the same, but return type is different, then it amounts to overloading and overriding. b) An Overriding method cannot be less accessible that the method it overrides. This would mean that if a method has a particular access modifier then the overriding method couldn’t have a modifier, which makes it less accessible. c) An overriding method cannot throw different types of exception that the method it overrides. This will be explained later on. Why Overriding? Overriding of methods allows java to support polymorphism, which allows a general class to specify methods that will be common to all of its subclasses, while allowing each of the sub classes to define the specific implementation of some or all of those methods. Abstract class There are many situation when you want to define a super class that declares the structure of a given abstraction without providing a complete implementation of every method. That is one creates a superclass that only defines a completely general form that will be shares by all of its subclasses leaving it to each of the subclass to fill in the details. For Example, we have a class called Figure which has a method called area () which does nothing, but lets the subclasses like Circle, Triangle, Square to override it and give specific implementation to the same. In this case you should call the area () as abstract. The other example can be a Drawing class. The class contains methods for variety of drawing facilities, but these must be implemented in a platform independent way. You cannot access the video hardware of a machine and still be platform independent. The intention is that the drawing class defines which method should exist, but special platform independent subclasses actually implement the behaviour. The syntax of an abstract method is 60
abstract method (); It is important to note here that this method does not have a body also. The points to be remembers here are: a) Any class, which has one or more abstract method, should be declared as abstract. To declare a class as abstract, simply use the abstract keyword in front of the class. b) There can be no objects of the abstract class. That is a abstract class cannot be directly instantiated with the new keyword. This is so because the class is not complete. c) Also you cannot have a abstract constructor or abstract static method. This is because static and abstract are opposite. d) Any subclass of a abstract class must override all the abstract methods, or the subclass must also be declared as abstract. That means any subclass must override all of the abstract methods. e) A abstract class can have a non-abstract method also. f) A abstract class can have member variables also, which can be used by the subclass after it overrides the abstract methods. final Keyword The final keyword can be used for a class, variable or a method. a) When a class is pre-fixed with a final keyword, then that class cannot be extended further. For example, the java.lang.String is a final class. This is done for security reasons, because it ensures that if a method has a reference to a string, it is definitely a string of class String and not a string of a class that is a modified subclass of String that might have been maliciously changed. b) When a variable is pre-fixed with the final keyword, then it cannot take any other variable than the variable with which it was initialised. That would mean that it will act like a constant. c) When a method is pre-fixed with the final keyword, then it cannot be overridden to provide any additional functionalities. This is also done for security reasons. You should make a method final if the method has a implementation that should not be changed and is critical to the consistent state of the object. The methods declared final are sometimes used for optimization. The compiler can generate 61
code that causes direct call to the method rather than the usual virtual method invocation that involves a runtime lookup. It is a common coding convention to choose all uppercase identifier for final variables. Variables declared as final do not occupy memory on a per instance basis. Thus the final variable is essentially a constant. Thus final keyword is often used to prevent overriding and also to prevent inheritance. Inner Classes Until now we have seen classes defined so far separate from each other. In previous releases, Java supported only top-level classes, which must be members of packages. In the 1.1 release, the Java 1.1 programmer can now define inner classes as members of other classes, locally within a block of statements, or (anonymously) within an expression. Here are some of the properties that make inner classes useful: o The inner class's name is not usable outside its scope, except perhaps in a qualified name. This helps in structuring the classes within a package. o The code of an inner class can use simple names from enclosing scopes, including both class and instance members of enclosing classes, and local variables of enclosing blocks. It is possible to define a class within another class and such classes are known as nested classes. The scope of the nested class is within the boundary of the outer class. The nested class can access all the variables, including private (since the inner class is within the boundary of the outer class), but the outer class does not have access to the members of the nested class. For Example: class Outer { int x; private int y; class Inner { int a; private int b; } }
62
Over here, the class Inner can access variables x and even y of the Outer class, but the Outer class cannot access the variables a and b of class Inner. Another important point to note here is that – to create objects of the Inner class you will need the context of the Outer class, since it is a nested class. That means until an object of Outer class is created, a object of Inner class cannot be created. Also one should note that when we create an object of the Outer class, no objects of the Inner class are necessarily created – unless of course they are created by the Outer class’s constructor. An object of the Inner class is created in the following format: Outer o = new Outer (); Outer.Inner a = o.new Inner (); Forms of Inner Classes a) Simple Inner Class b) Static Inner Class c) Inner Class inside a method. We have seen the simple inner class and now we got to the static inner class. static Inner Class If we have to make objects of a nested class independent of objects of the enclosing class, one should declare the nested class as static. For Example class Outer { int a; static class Inner { } } Now if we have to create an instance of the nested class, the syntax would be Outer.Inner= new Outer.Inner ();
63
This is significantly different from what we did for the non-static inner class. Now we must used the nested class name qualified by the enclosing class name as the type for creating the object. Note that a static inner class can have static members, whereas a non-static nested class cannot and the points to remember here are: a) Members of a static nested class can access static members of the top-level class. b) A non-static inner class cannot have static members. c) A non-static inner class can access any members of the top level class, regardless of their access attributes. d) A non-static nested class can access static members of any static nested class within the same top level class Inner class inside a method. We can also have a inner class inside a method also. The point to remember here are: a) The inner class inside a method can access all the variables of the outer class. b) The inner class can access only the final variables inside the method, and cannot access the non-final variables inside the method in which it is defined. Object Class Class Object is the root of the class hierarchy. Every class has Object as a superclass. All objects, including arrays, implement the methods of this class. The main methods of the class Object are: The methods wait (including the overloaded versions), notify and notifyAll will be covered at the time of threads. Package A package is a collection of class and is often used to keep the class name compartmentalized. The package has both a naming and visibility control mechanism. You can define classes inside a package that is not accessible to others outside the package. Essentially a package is a named collection of classes. To use a package, just use package command as the first statement in the source file. Any classes declared within that file will belong to the specified package. If you omit the
64
package statement, the class names are put into the default package with no name. The syntax for the package statement is: package abc // abc is the name of the package If you want the classes in a package to be accessible outside the package, you must declare the class using the public keyword. The class definitions that aren’t preceded by the public keyword are only accessible from methods in classes that belong to the same package. More than one file can include the same package statement. The package statement simply specifies to which package the classes defined in a file belong. The package mechanism is for two main purposes: a) Reduce the problems with name conflicts. b) control the visibility of classes, interfaces and the methods and data defined within them. One can also have a hierarchy of packages. To do so, simply separate each package name from the one above it by the use of the period. For Example: package abc.xyz.nmq Java uses file systems directories to store packages. For example, a class file for the above class you declare will be a part of the abc package and in a directory called as abc. Remember java is case-sensitive. If we have a class file named as Test.java in a package named abc, then we can also compile the same as javac abc.Test.java // it will compile correctly. Accessing a package How do you access a package when you are compiling a program that uses the package depends on where you have put it. There are a couple of options here. The first but not the best is to leave the .class file for the classes in the package in the directory with the package name. Let’s look at that before we go into to the second option. With the .class file in the original package directly, either the path to your package must appear in the string set for the CLASSPATH environment variable or you must use the classpath option on the command line when you invoke the compiler or the interpreter. This overrides the CLASSPATH environment variable if it happens to be set. Note that it 65
is up to you to make sure that the classes in your package are in the right directory. Java will not prevent you from saving a file in a directory that is quite different from that appearing the package statement. Of the two options here, using the –classpath option on the command line is preferable because it sets the class paths transiently each time and can’t interfere with anything you do subsequently. This has the advantage that it only applies for the current compilation or execution so you can easily set it to suit each run. The command to compile Test.java defining the class path would be: javac –classpath ,; c:\MySource\Test.java If you do not set the class path in one of the above two ways or do it incorrectly, then java will not be able to find the classes in any new package you might create. The Important java packages are: a) java.applet
-
Classes for implementing Graphics.
b) java.awt
-
Classes for text, windows and GUIs.
c) java.io
-
Classes for all kinds of input and output
d) java.net
-
Classes for networking.
e) java.math
-
Classes for calculations.
Protected and Default Access Modifiers We had learnt about private and public access modifier and now we will see the other two access modifiers now. Package adds a complete new dimension to access control. Package is a container for classes and other subordinate packages. Java has 4 levels of access control, which we should study and they are: a) subclass in the same package b) non sub-class in the same package c) subclass in different package d) non sub-class in different package. Default Modifier
66
A Default Access Modifier means, when we do not specify anything to the class, method or variable it is said to have default access modifier. The default access modifier means it is available to any class inside the package, irrespective of whether it is sub class or not and is not available to any sub class outside the package also. Protected Modifier A Protected Access Modifier is actually a misnomer and is often confusing. By general understanding of the term is seems to be more restrictive that private, but is not actually so. When we declare a member of a class as protected, we cannot declare the class as protected, then it is available to all members inside the package and also to classes, which is a subclass in a different package. The access modifier from the most restrictive to the least restrictive is private
--> default -->
protected --> public
Importing packages All of java classes are stored in packages and one would not find a single class just hanging in open air. Since classes within packages must be fully qualified with their package name or names, it would be tedious to type in the long dot-separated package name for every class you want to us. For this java has a special statement called import statement, which will certain class or the entire packages into visibility. The import statement tells the compiler where to find the particular classes.3 Once imported, a class can be referred to directly, using only its name. The import statement is a convenience to the programmer and is not technically needed to write a complete java program. In a normal java source code, the import statement occurs immediately after the package statement. The general form of a import statement is: import package1.package2.*; This would mean that all the classes in package1.package2 would be imported. But remember it would also take for the basic source java file to compile, as all the classes will have to be imported. If one know a file which is to be specifically imported then it should be written as: import package1.package2.Test; All the standard java classes are included in a basic package called java. The basic language functions are stored in a package inside the java package called java.lang. Normally one will have to import every package or class that you want to use, but since
67
java is useless without much of the functionalities in java.lang, the compiler for all programs implicitly imports it. Interfaces We have discussed about the concept of inheritance and have understood that java has simple inheritance only. There are many cases when a particular method will be used by a lot of classes and this can be done by a interface. An interface is also like a normal class, but it has only final variable (constants) and abstract methods. That would mean that it is similar to abstract classes, but since the interface is by abstract and all the methods are abstract (remember abstract classes can also have non-abstract methods) there is no need to write abstract before the interface. Similarly, all the data members declared in an interface are by default constants, there is no need to explicitly insert a final, static or final modifier before them. But we need to prefix the class name with interface instead of class. For example, the general syntax of a interface is: interface Test { met1(); } implements clause A class declares all of the interfaces it is implementing using the implements clause. The implements clause consists of the keyword implements followed by the list of interfaces separated by commas and it must be put after the extends clause (if any). This would mean that a class can implement more than one interface. An interface gives the illusion of bending the java technology single inheritance rule, while a class can extend only a single class, it can implement as many interfaces as needed. Interfaces are useful for: a) Declaring methods that one or more classes are expected to implement. b) Determining an object’s programming interface without revealing the actual body of the class. c) Capturing the similarities between unrelated classes without forcing a class relationship.
68
Variables in Interfaces One can also use interfaces to import shared constants into multiple classes by simply declaring an interface that contains variables, which are initialised to the desired values. When you then implement the interface all those variable names will be in scope as constants. Interfaces can be extended One interface can inherit another with the help of the usual extends keyword. When a class implements an interface that inherits another interface, it must provide implementation for all methods defined within the interface inheritance chain. Partial Implementation It is very much possible that a class will implement an interface, but does not want to override all the abstract method, but will override some abstract methods and leave the further implementation to its own subclasses. In this case we should declare the class as abstract, because there are some abstract method in the class.
69