At the end of this chapter, you will be able to understand and use
Java is a pure object-oriented language and hence all programming is enclosed in classes. Object-oriented programming involves writing programs that use classes. We create objects of different classes to solve the problem at hand and make objects communicate with each other through the member functions.
In this chapter, we will learn how to solve problems by using classes and objects. We will also cover topics such as data hiding, abstraction, access privileges enjoyed by members of the class, and concepts of constructor and destructor. Variations in methods such as methods definition, recursion and factory methods are also discussed. Classes within a class, called inner classes, are introduced. This operator and static member functions and their relevance and usage are explained. Java's garbage collector and finalizer methods are also discussed.
Look around your classroom. There are students all round. First of all, why have they been grouped together by your principal? Firstly because they all share common interests, for example they would like to learn the language Java or they would like to complete their PG or UG studies. In computer parlance, we can say that all students have the same functionality. That is why they could be grouped together.
But notice that each student has his own individual attributes. Attributes mean own member data like height, weight, marks, attendance, etc. Also notice that there are about 60 students in your class, each with his or her own attributes but common functionalities. We can call 60 instances of object of Students class. Well so much background for analogy. Figure 18.1 shows attributes and methods of class student.
Figure 18.1 Class methods and attributes
Class: A collection of objects. We can also define as an array of instances objects. But class can have member functions and member data. Here, unlike array, a class can have different data types as its elements.
Object: An object is an entity. That is, it can be felt and seen. Examples are students, pens, tables, chairs, etc. Therefore, an object is an independent entity that has its own member data and member functions.
While methods of a class are common to all instances of the object, each instance of an object has its own set of attributes. Hence, member data is also called instance variables, i.e. they are different for each instance of an object.
Data Hiding/Data Abstraction. It is customary to declare all member data as private only. But the data declared as private is hidden and cannot be accessed by anyone. This feature is called data hiding or data abstraction. But how can we get them? You can access this only through public member methods.
Encapsulation. An object-oriented programming like Java is a data primacy language i.e. data is important and functions are not important. As per memory mapping, data is stored in data area, such as stack and free space, and functions are stored in code area and there is a need to maintain strict control over the accessing of data by functions. Java achieves this control by using the encapsulation feature. Encapsulation is binding member data and calling function together with security classification, so that no unauthorized access to data takes place. Java depends heavily on access specifiers to maintain data integrity. The security access specifiers are public, private, protected and default specifier package.
Use keyword class followed by brace brackets. In side brace brackets we can include member data and member methods, as shown below. We will create a class for Student called Student3. The attributes are name, rollNo, total marks and grade. The grades are awarded based on total marks: A, if total marks are >80; B, if total marks are >60; C, if total marks are <60; and D, if total marks are <40.
Example 18.1: How to Declare a Class Called Student
1. package com.oops.chap19;
2. import java.io.*;
3. class Student1{
4. // member data or attributes
5. String name=””; // name of the student
6. int rollNo;
7. double totalMarks;
8. String grade=””;
9. }
10. class StudentDemo {
11. public static void main(String[] args) {
12. // create an object of class Student3
13. Student1 std = new Student1();
14. std.name=”Gautam”;
15. std.rollNo=6274;
16. std.totalMarks=98.78;
17. //compute grade
18. if( std.totalMarks >=80.0) std.grade=”A”;
19. else if (std.totalMarks>= 60.0) std.grade=”B”;
20. else if (std.totalMarks>= 50.0) std.grade=”C”;
21. else std.grade=”D”;
22. System.out.println(“Students Details are………”);
23. System.out.println(“Roll Number:” + std.rollNo);
24. System.out.println(“Name:” + std.name);
25. System.out.println(“Total Marks:” + std.totalMarks);
26. System.out.println(”Grade:“ + std.grade);
27. }
28. }// end of StudentDemo
Output: Students Details are………
Roll Number:6274 Name:Gautam Total Marks:98.78 Grade:A
When you need to construct a house, you go to a specialist called architect or mason so that they make the house ready for occupation and usage. So is the case with class. When a class is declared and an object is created, the constructor for the class is called. Its job is to create the object, allocate memory for the data members and initialize them with initial values if supplied by the user. If no initial values are supplied by the user, then it initializes with default values. Similarly, if the user does not declare a constructor, default constructor is always created. Constructor will have the same name as that of the class but no return value. Constructor is always treated as public by default. Whenever an object is created, the constructor is automatically called.
Student Std = new Student(); // default constructor is called.
Constructors are called parameterized when we pass initial values at the time of creation of the object: Student Gautam = new Student (“ Gautam”, 6274,74.00,”A”); we will demonstrate the concepts of constructors through an example of Polar class in Example 18.2:
Example 18.2: PassObjConst.java A Program for Showing Overloaded Methods
1. package com.oops.chap19;
2. import java.io.*;
3. //import java.math.*;
4. class Polar2{
5. // all member data is declared as private
6. private double r; // magnitude
7. private double t; // angle theeta
8. private double a; // real
9. private double b; // imaginary
10. public void Setr( double rd){ r=rd;}
11. public void Sett( double td){ t=td;}
12. public void Seta( double ad){ a=ad;}
13. public void Setb( double bd){ b=bd;}
14. //constructors
15. //Default Constructor
16. Polar2() {
17. System.out.println(“Polar2 Default constructor….”);
18. Setr(0.0);Sett(0.0);Seta(0.0);Setb(0.0);}
19. //parameterized constructor
20. Polar2(double ad, double bd){
21. System.out.println(“parameterized(a & b) constructor.”);
22. Setr(0.0);Sett(0.0);Seta(ad);Setb(bd);}
23. Polar2(double ad, double bd , double rd, double td){
24. System.out.println(“parameterized( a,b,r,t) constructor.”)
25. Setr(rd);Sett(td);Seta(ad);Setb(bd);}
26. // public accessory functions
27. public void ConvertToPolar(){double x=0.0;
28. r=(a*a + b*b)*0.5; x=Math.atan(b/a);//x in radians
29. t=Math.toDegrees(x);
30. } // to convert to polar form
31. public void DisplayPolar(){
32. System.out.println(“Inside DisplayPolar .”);
33. /*directly use r and t because accessed inside method */
34. System.out.println(«magnitude<r>:» +r + «Angle<t>» + t);}
35. }// end of class Polar1
36. class Polar2Demo {
37. public static void main(String[] args) {
38. // create an object of class Polar1-Default constructor
39. Polar2 pol2 = new Polar2();
40. pol2.DisplayPolar();
41. Polar2 pol2a = new Polar2(3.0,4.0); // 3 + J4
42. pol2a.ConvertToPolar();
43. pol2a.DisplayPolar();
44. Polar2 pol2b = new Polar2(3.0,4.0,12.5,53.13); //3+J4 & r,Φ
45. pol2b.DisplayPolar();
}
}// end of Polar2Demo
Output Inside Polar2 Default constructor………….
Inside DisplayPolar .
magnitude <r> :0.0Angle<t>0.0
Inside Polar2 parameterized(a & b) constructor………….
Inside Polar2 parameterized( a,b,r,t) constructor………….
Inside DisplayPolar.
magnitude <r> :12.5Angle<t>53.13
Inside DisplayPolar .
magnitude <r> :12.5Angle<t>53.13010235415598
Overloading of constructors means the same name but different signatures (number and type of parameters). In the above example, we have overloaded the constructors as shown below:
Line No. 16: | Polar() { ………………………….) Nil arguments. This type of constructor is called NIL arguments constructor and also as default constructor. |
Line No. 20: | Polar2(double ad, double bd){…………………………………….} 2 arguments |
Line No. 23: | Polar2(double ad,double bd ,double rd,double td){…} 4 args |
We have overloaded the constructors. Each overloaded constructor has a different number of arguments. Overloading means the same name but different signatures (number and type of parameters). When a message is sent, signatures are compared and best-fit methods get loaded. This happens at run time. We have to pass arguments to constructors. Hence, these are called parameterized constructors.
In the Class we have declared in Example 18.1, the attributes had no access specifiers and hence they had default access specifiers, i.e. they are public to all the members of package and private to outside package. However, policy of any good OOPS language is to declare the attributes as private and provide public methods to access these attributes. The next example shows that we have declared all the attributes as private and provided public methods like GetData(), DisplayData() and ComputeData().
Once the object to a class is created, we can access the member functions and public member data of a class using the dot (.) operator.
In Java, class member functions are called Methods. A method is nothing but a code written to achieve a result. The syntax is:
public void main () calls the function FindMax() by supplying the arguments and receives the result through return type.
ans = FindMax ( a, b ) ; // a,b, and ans are all integer data types
Arguments: Number and type of parameters are called arguments. Parameters are also called formal parameters.
Signature: Name and arguments together are called the signature of the method. A method will have a return type which is outside the signature. The variables declared inside a method are called local variables and are never available anywhere outside the method. A method can be executed by sending a message to the object. Message comprises – a reference to the object, a dot (.), method name and actual parameters (arguments). In the next example, we will show usage of access specifiers and also methods that return parameters. Whenever IO Stream commands are used, there is a likelihood of errors and exceptions occurring. Hence, try and catch block.
Instance Methods: Methods are defined inside a class and can be accessed by object or instances of object. Hence, these methods are also called instance methods.
Access/Mutator Methods. Normally the member data is declared private and public accessory methods are declared inside a class to access them. There are a set of these public methods which are called Get() and Set() methods whose job is just to set the private data and read(Get) the private data. The Get() methods are called accessor methods and the Set() methods are called mutator methods. These are extensively used in deciding the behaviour pattern of the objects.
Example 18.3: How to Declare a Class Called Student with Data with Access Specifiers and Function Accepts a Value as Parameter and Returns a Value
1. package com.oops.chap19;
2. import java.io.*;
3. class Student3{
4. // member data or attributes
5. private String name=””; // name of the student
6. private int rollNo;
7. private double totalMarks;
8. private String grade=””;
9. //public metods
10. public void GetData() {
11. try{
12. BufferedReader input = new BufferedReader (new InputStreamReader(System.in));
13. System.out.println(“Enter Students name :”);
14. name = input.readLine();
15. System.out.println(“Enter Students roll number :”);
16. rollNo= Integer.parseInt(input.readLine());
17. System.out.println(“Enter total marks :”);
18. totalMarks= Double.parseDouble(input.readLine());
19. }catch ( Exception e){}
20. }//endof GetData()
21. public void DisplayData() {
22. System.out.println(“Students Details are………”);
23. System.out.println(“Roll Number:” + rollNo);
24. System.out.println(“Name:” + name);
25. System.out.println(“Total Marks:” + totalMarks);
26. System.out.println(“Grade:” + ComputeGrade(totalMarks));
27. }
28. public String ComputeGrade(double totalMarks) {
29. String grade=””;
30. if( totalMarks >=80.0) grade=”A”;
31. else if (totalMarks>= 60.0) grade=”B”;
32. else if (totalMarks>= 50.0) grade=”C”;
33. else grade=”D”;
34. return grade;
35. }
36. }// end of Student3
37. class Student3Demo {
38. public static void main(String[] args) {
39. // create an object of class Student3
40. Student3 Gautam = new Student3();
41. Gautam.GetData();
42. Gautam.DisplayData();
43. }
44. }// end of Student3Demo
Output: Students Details are………
Roll Number:50595
Name:Ramesh
Total Marks:98.0
Grade:A
In our next example, we will show all the concepts we have discussed so far through a class declaration called Polar. In this program, you will learn the concept of class and object and public accessory functions. The class we will consider is vector in Cartesian form denoted by real number a and an imaginary component b. In Polar coordinates, the same can be represented by vector whose magnitude is r given by the formula r = √ (a2 + b2) and the direction is given by θ = tan – (b/a). Our program will accept the real value a and imaginary component b through a public accessory function called GetData() and convert it to Polar form with magnitude r and angle θ through a public accessory function called ConvertToPolar() and display the result through a function called DisplayPolar(). A word or two about the way we will declare and define functions. In the next example, we will show how we can use math function. Java defines a Math class. Some of the important and widely used methods are shown in Table 18.1.
Table 18.1 Math class of Java – some widely used methods
Method | Description |
---|---|
static double sin(double arg) //cos & tan also available |
Returns sine cosine and tan of argument in radian |
static double atan(double arg) //asin() and acos available |
Returns angle whose tan() is argument |
static double sinh(double arg) //cosh & tanh also available |
Returns hyperbolic sine of angle given by argument. |
static double pow (double y, double x) | Returns y^x |
static double sqrt(double x) | Returns square root of x |
static double exp(double x) | Returns e^x |
static double log(double x) | Returns natural log of x |
static double log10(double x) | Returns log base 10 of x |
static double abs( double x) | |
static double ceil( double x) | Returns smallest whole number >= x |
static double floor( double x) | Returns largest whole number <= x |
static double rint( double x) | Returns integer nearest to x. |
Example 18.4: Polar1Demo.java A Program to Accept Data for Cartesian Vector a + j b and Display the Result in Polar Form r Angle Theta
1. package com.oops.chap19;
2. import java.io.*;
3. class Polar1{
4. // all member data is declared as private
5. private double r; // magnitude
6. private double t; // angle theeta
7. private double a; // real
8. private double b; // imaginary
9. // public accessory functions
10. public void GetData(){
11. try{
12. BufferedReader input = new BufferedReader (new InputStreamReader(System.in));
13. System.out.println(“Enter Cartesian <real number a>:”);
14. a = Double.parseDouble(input.readLine());
15. System.out.println(“Enter Imaginary <b> :”);
16. b= Double.parseDouble(input.readLine());
17. System.out.println(“Enter magnitude <r> :”);
18. r=t=0.0; // in side a member method.r & t can be accessed d
19. }catch( Exception e){}
20. }
21. public void ConvertToPolar(){
22. double x=0.0;
23. r=Math.sqrt(a*a + b*b);
24. x=Math.atan(b/a); // x is in radians, b/a in radians
25. t= (7.0/22.0)*180.0*x; // PI radians equals 180 degrees
26. t=Math.toDegrees(x); //conver to degrees
27. } // to convert to polar form
28. public void DisplayPolar(){
29. System.out.println(“Inside the classes member function .”);
30. /*We can directly use r and t because it is inside the
31. member function of the class thus equal to public*/
32. System.out.println(«magnitude<r>:» + r + «Angle<t>» + t);
33. } // to display in polar and cartesian forms
34. }// end of class Polar1
35. class Polar1Demo {
36. public static void main(String[] args) {
37. // create an object of class Polar1
38. Polar1 pol1 = new Polar1();
39. pol1.GetData();
40. pol1.ConvertToPolar();
41. pol1.DisplayPolar();
42. }
43. }// end of Polar1Demo
Output: Enter Cartesian form Vector Details <real number a>: 3
Enter Imaginary <b> : 4
Enter magnitude <r> :
Inside the classes member function .
magnitude <r> :12.5Angle<t>53.13010235415598
Line Nos. 5 to 8: | declare the attributes as private and type double. |
Line Nos. 10 to 20: | defines a method for GetData() that obtains data from keyboard using Biffered Reader at Line No. 12. It also uses try and catch blocks at Line Nos. 11 and 19. |
Line Nos. 23, 24 and 26: | use Math class methods like sqrt, atan and toDegrees |
Notice that when we refer to private data a,b,r,t inside a method like ConverPolar() and the method is invoked by the object, then these private variables can be accessed directly like we have done at Line No. 31 and we do not need public accessory methods.
System.out.println("magnitude<r>:" + r + "Angle<t>" + t);
Mode of data transfer between calling method and called method is carried out by copying variables listed as arguments into called method stack area, and subsequently, returning the value by called function to calling function by copying the result into stack area of the main method. This is called call by value. Note that as copying of the variables, both for forward transfer and return transactions are involved, it is efficient only if values to be transferred are small in number and of basic data type. Accordingly, Java uses call by value for transferring all primitive data types.
As only copies are forwarded to method, the changes made to these variables by called method are local changes and are not reflected back to calling method.
Example 18.5: PassByValDemo.java – Passing Arguments by Call by Value
//PassByValDemo.java
1. package com.oops.chap19;
2. import java.io.*;
3. class CallByVal{
4. public void SwapData(int x, int y) {
5. System.out.println(“Inside SwapDataBefore Swap………”);
6. System.out.println(“x:” + x + “y:”+y);
7. int temp=x;x=y;y=temp;
8. System.out.println(“Inside SwapData, After Swap”);
9. System.out.println(“x:” + x + “y:”+y); }
10. }// end of class callBy Val
11. class PassByValDemo {
12. public static void main(String[] args) {
13. int x=10;int y=100;
14. CallByVal val = new CallByVal();
15. val.SwapData(x,y);
16. System.out.println(“Inside main :return from SwapData, “);
17. System.out.println(“x:” + x + “y:”+y);}
18. }
Output: Inside SwapDataBefore Swap……… x:10y:100
Inside SwapData, After Swap ………. x:100y:10
Inside main on return from SwapData, x:10y:100
Line No. 15: | we have passed data by call by value. Line Nos. 8 and 9 show that values inside Swapdata have indeed been swapped. These are local changes. |
Line Nos. 16 and 17: | show that values of x and y remain unchanged after return from SwapData. This is characteristic of Call by Value. |
For large data items occupying large memory space like objects, overheads like memory and access times, etc., become very high. Hence, we do not pass values as in call by value; instead, we pass the address to the function. Note that once the method receives a data item by reference, it acts on data item and the changes made to the data item also reflects on the calling function. This is like passing the address of the original document and not a photocopy. Therefore, changes made on the original document apply to the owner of the document as well.
Java passes objects only by reference. When an instance of object is created, we are creating the reference to object. As reference of the objects is passed, changes made to these objects by called program are reflected back to the calling program as well. Please make a note that reference itself is passed by call by value.
We can pass objects as arguments to a method and receive object from a method through return statement. In the example that follows, a method called StdGrade receives the object called Student as argument and computes the grade and returns the object to calling methods.
Example 18.6: StdGradeDemo.java A Program that Passes and Receives Objects To and From a Method
//StdGradedemo.java
1. package com.oops.chap19;
2. import java.io.*;
3. class StdGrade{
4. // member data or attributes
5. String name=””; // name of the student
6. int rollNo;
7. double totalMarks;
8. String grade=””;
9. public void DisplayData() {
10. System.out.println(“Students Details are………”);
11. System.out.println(“Roll Number:” + rollNo);
12. System.out.println(“Name:” + name);
13. System.out.println(“Total Marks:” + totalMarks);
14. System.out.println(”Grade:“ + grade);
15. }
16. public StdGrade ComputeGrade(StdGrade std) {
17. String grade=””;
18. if( totalMarks >=80.0) std.grade=”A”;
19. else if (totalMarks>= 60.0) grade=”B”;
20. else if (totalMarks>= 50.0) grade=”C”;
21. else grade=”D”;
22. return std;
23. }
24. }
25. class StdGradeDemo {
26. public static void main(String[] args) {
27. // create an object of class Student3
28. StdGrade std1 = new StdGrade();
29. std1.name=”Gautam”;
30. std1.rollNo=6274;
31. std1.totalMarks=98.78;
32. //compute grade by passing object and receiving back object
33. std1= std1.ComputeGrade(std1);
34. std1.DisplayData();
35. }
36. }// end of StudentDemo
Output: Students Details are………
Roll Number:6274 Name:Gautam Total Marks:98.78 Grade:A
Line No. 16: | shows the function StdGrade( StdGrade std) receiving the object and Line No. 22 returns the object. Please note that this transfer of the object is by Pass by Reference and hence changes made inside a method are reflected back to the calling program. |
As a second example of object passing, let us consider a case wherein we pass object to a constructor. We pass object to a constructor when we need a clone(copy) of the object initially.
Student std 1 = new Student ( “Ramesh”,50595,98.7,”A”) //
name,no,total,grade
Student std2 = new Student(std1); // std2 is a clone of std1
Example 18.7: PassObjConst.java A Program for Showing Overloaded Methods
//PassObjConst.java
1. package com.oops.chap19;
2. import java.io.*;
3. class Polar4{
4. private double a; // real
5. private double b; // imaginary
6. public void Setab(double ad, double bd){a=ad;b=bd;}
7. //parameterized constructor
8. Polar4(double a, double b){Setab(a,b);}
9. // public accessory functions
10. Polar4(Polar4 pol){ a= pol.a;b=pol.b;}//pass object
11. public void DisplayPolar(){
12. System.out.println(“Inside DisplayPolar .”);
13. System.out.println(“Real <a> :” + a + “Imag <b>” + b);
14. } // to display in cartesian form
15. }//end of class
16. class PassObjConst {
17. public static void main(String[] args) {
18. Polar4 pol4 = new Polar4(3.0,4.0); // 3 + J4
19. System.out.println(“Given Vector in Cartesian form .”);
20. pol4.DisplayPolar();
21. Polar4 pol4a = new Polar4(pol4); // we have passed pol4 object to make a clone of pol4
22. System.out.println(“Cloned Vector pol4a Cartesian form .”);
23. pol4a.DisplayPolar();
24. }
25. }// end of PassObjConst
Output: Polar4 parameterized(a & b) constructor………….
Given Vector in Cartesian form .
Inside DisplayPolar .
Real <a> :3.0Imag <b>4.0
Cloned Vector pol4 in Cartesian form .
Inside DisplayPolar .
Real <a> :3.0Imag <b>4.0
Line No. 10: | Polar4(Polar4 pol){ a= pol.a;b=pol.b;} and statement 21 Polar4 pol4a = new Polar4(pol4); shows passing of the object to a constructor. Pol4a ia clone of pol4 |
The same name for the method but with different number of arguments or different type of arguments, we can say methods are overloaded. Overloaded methods can have different types of return types. When the signature of the method, i.e. name and arguments, match, Java loads the particular version of the method into primary area. While there can be several versions of a method compiled, they are loaded at run time as per arguments supplied by the user, thus saving the primary memory. Consider the following examples of overloading because name is the same but there are different number of arguments.
public double Find(double side){ return side*side;}//Area of square
public double Find(double l, double b ){ return l*b;}//rectangle area
public double Find( double l , double b , double h){ return l*b*h;}
// cube vol
A second set of examples are for different types of arguments for overloaded methods
public int Find( int a , int b){ return ( a<b) ? a:b);}// smaller of a & b
integers
public double Find( double a , double b){ return ( a<b) ? a:b);}// smaller
of a & b double
Once you have declared the above overloaded methods, the following statements are not overloaded methods and lead to error. Why?
public float Find(double l, double b){return l*b;}//rectangle area
public short Find( int a, int b){ return ( a<b) ? a:b);}// smaller of
a & b integers
Example 18.8: Find.Java To Show Overloaded Methods
//FindDemo.java
1. package com.oops.chap19;
2. import java.io.*;
3. class OverLoadedFind{ // over loaded Find for square, rect, cube
4. public double Find( double side){ return side*side;}
5. public double Find( double l , double b ){ return l*b;}
6. public double Find(double l, double b, double h){return l*b*h;}
7. }
8. class FindDemo {
9. public static void main(String[] args) {
10. OverLoadedFind ovrfind = new OverLoadedFind();
11. System.out.println(“ Area of a square: “ + ovrfind.Find(10.0));
12. System.out.println(“Area of a rect”+ ovrfind.Find(10.0,20.0));
13. System.out.println(“ Vol ofCube:”+ovrfind.Find(10.0,20.0,30. 0));
14. }
15. }// end of FindDemo.java
Output: Area of a square: 100.0
Area of a rectangle: 200.0 Vol of a Cube: 6000.0
Line Nos. 4, 5 & 6: | define overloaded methods to determine area of square, rectangle and volume of the cube. |
Line Nos. 11, 12 & 13: | use overloaded Find. Note that Java automatically understands the data types as we have declared prototypes in statements 4 to 6. |
Recursion is an advanced feature supported by Java language. Recursion means a method calling itself. Consider the problem of finding a factorial of a number. In the example, we can clearly see that Fact (5) is calling Fact(4) and so on.
Fact(5) = 5 × 4 × 3 × 2 × 1
= 5 × Fact(4)
= 5 × 4 × Fact(3)
= 5 × 4 × 3× Fact(2)
= 5 × 4 × 3× 2 × Fact(1)
= 5 × 4 × 3× 2 × 1 × Fact(0)
= 5 × 4 × 3× 2 × 1 (Fact(0) =1)
Example 18.9: RecursionFact.Java To Calculate Factorial Using Recursion
1. //RecursionFact.java
2. package com.oops.chap19;
3. class Factorial{
4. public long factrecur(int a)//function definition*/
5. { long ans;
6. if(a<=0) return(1); // fact(0) = 1 by definition
7. else ans =a*factrecur(a-1); //method call with recursion*/
8. return(ans); //returns the value of fact to main*/
9. } //end of function fact*/
10. }// end of class Factorial
11. class RecursionFact{
12. public static void main(String[] args) {
13. Factorial fact = new Factorial();
14. System.out.println(“ Fact of 5 : “+ fact.factrecur(5));
15. System.out.println(“ Fact of 7 : “ + fact.factrecur(7));
16. System.out.println(“ Fact of 10 : “ + fact.factrecur(10));
17. }
18. }//end of recursionFact
Output : Factorial of 5 : 120
Factorial of 7 : 5040
Factorial of 10 : 3628800
Line No. 4: | defines factrecur(int a) to find the factorial by recursion. If you call the method with argiment 1, it will return 1 else it returns factrecur(a-1)*a. This means that we now call factrecur with a-1 as argument, i.e. the method calls itself. |
We are aware that memory management of Java allocates separate memory area called code section for your code. Accordingly, your method code will be in this area. But we also know that variables are stored in stack area. When a method is invoked by an object, there is a need to link up method that is called with the objects data. Therefore, the object is forwarded to method as an argument to that method. But this argument, i.e. address of the object invoking the method, is not visible like ordinary formal arguments and it is hidden. This hidden address is called this object. It is called this because it points this object, that is, the object that has invoked the method. In a method if you use this keyword explicitly, then it refers to object member data. Note that we can get the same effect by using the object instead. But note that this has all the advantages of instant and fast access to object. Line No. 22 in the next example shows this feature.
A second use of keyword this is to resolve naming conflicts. For example, if our method had the following definition: public void Setr( double r){ r=r;}, there is naming conflict. Keyword this comes to the rescue. We could write the method as: public void Setr(double r){this.r=r;} Line Nos. 8 to 11 show this feature. Look at the program in Example 18.5 rewritten using this operator.
Example 18.10: PolarThis.java To Show the Uses of this Operator. Constructors and Destructors of a Class
1. package com.oops.chap19;
2. import java.io.*;
3. class Polar3{
4. private double r; // magnitude
5. private double t; // angle theeta
6. private double a; // real
7. private double b; // imaginary
8. public void Setr(double r){this.r=r;}
9. public void Sett(double t){this.t=t;}
10. public void Seta(double a){this.a=a;}
11. public void Setb(double b){this.b=b;}
12. //constructors Default Constructor
13. Polar3() {
14. System.out.println(“Polar3 Default const..”);
15. Setr(0.0);Sett(0.0);Seta(0.0);Setb(0.0);}
16. Polar3(double a, double b){
17. System.out.println(“parameterized(a & b) const…”);
18. Setr(0.0);Sett(0.0);Seta(a);Setb(b);}
19. // public accessory functions
20. public void ConvertToPolar(){double x=0.0;
21. r=(a*a + b*b)*0.5; x=Math.atan(b/a);//x in radians
22. t=Math.toDegrees(x);
23. } // to convert to polar form
24. public void DisplayPolar(){
25. System.out.println(“Inside DisplayPolar .”);
26. System.out.println(“mag<r> :”+ this.r +”Angle<t>”+ this.t);
27. } // to display in polar and cartesian forms
28. }// end of class Polar1
29. class PolarThis1Demo {
30. public static void main(String[] args) {
31. Polar3 pol3a = new Polar3(3.0,4.0); // 3 + J4
32. pol3a.ConvertToPolar();
33. pol3a.DisplayPolar();
34. }
35. }// end of Polar2Demo
Output: Inside Polar3 parameterized(a & b) constructor………..
Inside DisplayPolar.
magnitude <r> :12.5Angle<t>53.13
Java resorts to automatic memory release for objects no more needed. Java uses automatic garbage collector to manage memory. So what is automatic garbage collector?
Garbage collector is a software program that runs in the background and picks up and clears memory space occupied by the dead objects. It follows a predetermined algorithm to decide which objects have no remaining reference, i.e. they are no longer referred and frees the memory automatically. This process will happen when the program is idle or when there is insufficient free memory to be allotted.
Java Run Time Environment calls Finalize() method just before the object is freed. An object may be holding several resources line handler to window and files, etc. We need to release these resources prior to the object's release. This job is done when Garbage collector handles the object and it automatically calls finalize() method.
protected finalize() {//write all the code for release of software}
Make a note that the time of execution of finalize() is not known as it is executed whenever Garbage collector calls for it and Garbage collectors follows random algorithm to release the object. Keyword protected to ensure code is not available outside the class.
Many a time, we need variables to hold a constant value and this does not change during the execution of the program. Then we need to use final specifier. For example, consider private final double PI = 3.141517; this means that we have declared a private variable PI which holds a double data type 3.141517. We want this value to be constant. Hence, we use the qualifier final.
The security access specifiers are public, private, protected, and default specifier package. Protected specifier is applicable in case of inheritance relationship.
Public: Member functions and data if any declared as public can be accessed outside the class member functions. This means that public member can be accessed by any other code. For example, we have defined main() as public, as it is called by Java outside the program.
package (default): You can access this from any other class in the same directory. Note that when no access specifier is specified, default is public up to package level, but private to members outside the package. We can refer to these default or public member data directly without the help of public function defined in the class.
Private: Member data declared as private can only be accessed within the class member methods and data is hidden from outside. We cannot access private members directly. Instead, we need public accessory methods to access these data.
Protected: Member data and member functions declared as protected is private to outsiders and public to descendants of the class in inheritance relationship. You will learn more about this in the inheritance chapter that follows.
//EmpAccess.java.
1. package com.oops.chap19;
2. class Employee{
3. String name; // default access . Package level
4. public int rollNo; // public to all
5. public String dept; // public
6. private double sal; //private
7. public double GetSal(){ return sal;}
8. public void SetSal(double s){ sal = s;}
9. }// end of class
10. class EmpAccess{
11. public static void main(String[] args) {
12. Employee emp = new Employee();
13. emp.name=”Ramesh”; // allowed since name is default
14. emp.rollNo=50595; // allowed since rollNo is public
15. //emp.sal=10000.00; // Not allowed since its private
16. // use public function like SetSal() and GetSal()
17. emp.SetSal(15000.00);
18. System.out.println(“Emp name:”+emp.name);//package default
19. System.out.println(“Emp id No:” +emp.rollNo);//public
20. System.out.println(“Emp Salary Set:”+emp.GetSal());//public method
21. }
22. }//end of RecursionFib
Output: Employess name: Ramesh
Employess id No: 50595
Employess Salary Set: 15000.0
Line No. 3: | String name. Default public to package members. Hence Line Nos. 13 & 18 are ok and allowed. |
Line Nos. 4 & 5: | declare public variables. Hence, Line Nos. 14 & 18 are ok. |
Line No. 6: | declares sal as private. Hence, it is an error if you try to access like in Line No. 15 directly. Instead, you have to use public accessory method like we have done in Line Nos. 17 & 20. |
Many a time, you will need a member of a class that is independent of any object of the class. For example, you need to keep a count of number of instances that are created. Variable declared as static, though residing inside a class, can keep track of the objects being created. This means that it is accessible to all instances of the class. We can say that static data belongs to class and not to an object.
One important advantage of static declaration is that once a member is declared static, it can be called before the object is created. For example, when we have declared void main() as public static void main( String[] args ), Java Run Time Environment calls the main() function before creation of any object.
Static variables are global variables. Whenever an instance of object is created, no resource is allocated to static variables. All instances of the class can have access to static variables. We can also declare a block as static block, in which case it can handle only static members.
Member methods can also be declared as static methods. But the rules of usage are as shown below:
Example 18.12: EmpStatic.java A Program to Demonstrate the Use of Static. Constructors and Destructors of a Class
//EmpStatic.java
1. package com.oops.chap19;
2. class EmpStatic{
3. static int countEmp;
4. static int mcount;
5. static int fcount;
6. static boolean mf;
7. static double totalSal;
8. // static block initilization
9. static
10. {System.out.println( “block initializes all static:”);
11. countEmp=0;mcount=0;fcount=0;mf=true;totalSal=0.0; }
12. static void Counts(boolean mf, double s)
13. {if (mf==true) ++mcount;
14. else ++fcount;
15. totalSal+=s;
16. ++countEmp;}
17. static void Display()
18. {System.out.println(“Total Sal:”+EmpStatic.totalSal);
19. System.out.println(“Total emp :”+ EmpStatic.countEmp);
20. System.out.println(“Male employess :”+ EmpStatic.mcount);
21. System.out.println(“Female employess :”+EmpStatic.fcount);}
22. public static void main(String[] args) {
23. EmpStatic.Counts(true, 10000.00);
24. EmpStatic.Counts(false, 12000.00);
25. EmpStatic.Display();}
26. }// end of EmpStatic class
Output: block initializes all static variable :
Total Sal:22000.0
Totall No of employess:2
No of male employess:1
No of female employess :1
After EmpStatic is run, the first thing that happens is that all the static statements are executed. Line No. 10 Static block is executed and all static variables are initialized.
Line No. 23: | As a next step void main() is executed. Main() in turns calls Count() at line Nos. 24 and 25 and Display() at Line No. 26 which displays the count of employees and total salary dispersed. |
A second important use of static declaration is that we can use static members outside the class in which they are declared. For this, you need to specify class name followed by dot. For example, StaticOutClass.totalSal; note that there is no need to use the object followed by dot, as we do for normal variables. Example 18.14 demonstrates this concept.
Example 18.13: EmpStatic2.java A Program to Demonstrate the Use of Static Outside the Class. Constructors and Destructors of a Class
//EmpStatic2.java
1. package com.oops.chap19;
2. class StaticOutClass{
3. static int countEmp;
4. static int mcount;
5. static int fcount;
6. static boolean mf;
7. static double totalSal;
8. // static block initilization
9. static
10. {System.out.println( “block initializes static vars :”);
11. countEmp=0;mcount=0;fcount=0;mf=true;totalSal=0.0;}
12. static void Counts(boolean mf, double s)
13. { if (mf==true) ++mcount;
14. else ++fcount;
15. totalSal+=s;
16. ++countEmp;}
17. static void Display(){
18. System.out.println(“total Sal:”+StaticOutClass.totalSal);
19. System.out.println(“Total empl:”+ StaticOutClass.countEmp);
20. System.out.println(“male emp:”+ StaticOutClass.mcount);
21. System.out.println(“female emp:”+StaticOutClass.fcount);}
22. }
23. class EmpStatic2{
24. public static void main(String[] args) {
25. StaticOutClass.Counts(true, 10000.00);
26. StaticOutClass.Counts(false, 12000.00);
27. StaticOutClass.Display();
28. // enter more
29. StaticOutClass.Counts(true, 20000.00);
30. System.out.println( “Display static vars outside class”);
31. System.out.println(“total Sal:”+StaticOutClass.totalSal);
32. System.out.println(“Total empl:”+ StaticOutClass.countEmp);
33. System.out.println(“male emp:”+ StaticOutClass.mcount);
34. System.out.println(“female emp:”+StaticOutClass.fcount);
35. }
36. }// end of EmpStatic2 class
Output: block initializes all static variable :
total employess salary :22000.0
Total No of employess :2
No of male employess :1
No of female employess :1
Display static variable directly outside class
total employess salary :42000.0
Total No of employess :3
No of male employess :2
No of female employess :1
Line Nos. 30 to 34: | show use of static variables directly by mentioning the class name, StaticOutClass, without using the object. |
What does a factory do? It simply produces an output depending on the customers’ choice. Factory methods in Java are designed to produce objects to the class to which factory method belongs. Factory methods are static methods. This means that they can be called directly without creating object.
The advantage of factory method is that it accepts arguments and returns the object of users’ choice; thus factory method removes the need to create several constructors and overload them.
As an example we will consider format() method and NumberFormat class provided by java.text package. The steps involved are:
Example 18.14: FactoryDemo.java To Show the Use of Factory Method and Numberformat Class. Constructors and Destructors of a Class
//FactoryDemo.java Factory Method usage
package com.oops.chap19;
import java.io.*;
import java.text.NumberFormat;
import java.util.*;
class FactoryDemo{
public static void main(String[] args)
{ final double PI = 3.1415197;
Scanner si = new Scanner(System.in);
System.out.print(“Enter angle in degrees:”);
double degrees =si.nextDouble();
double degrad = (degrees * PI)/180.0;
System.out.println(“Degrees in radians with outFormatting:” + degrad);
NumberFormat numfrmt = NumberFormat.getNumberInstance();
// format the number
numfrmt.setMaximumIntegerDigits(2);
numfrmt.setMaximumFractionDigits(2);
//convert to to string and display
String stg = numfrmt.format(degrad);
System.out.println(“Degrees in radians with Formatting using “+stg);
}
}//end of FactoryDemo
Output: Enter angle in degrees:180
Degrees in radians with out Number Formatting:3.1415196999999995
Degrees in radians with Formatting using Factory Method3.14
Nested class means class within a class, also called container class in the literature. Container class is one of the techniques provided by Java to achieve reusability of the code. Inheritance is another powerful feature for reusability which we will explore in the chapter on inheritance.
Container class means a class containing another class or more than one class. For example, a computer has a microprocessor in it. Further, a Student class can have a data member belonging to String class. Then we would say that String class is contained in Student class. In other words, it can also be called composition or aggregation of String class. The advantage of containment is that we can use String class within Student class to store the details of name and address, etc., belonging to String class. Similarly, if we define a class called Date with day, month and year information, we can define object of Date within the class called Student and define Date-related data such as DOB, DOJ, etc.
Composition is a “has”-type of relation. For the example we have given above, Student has name of string class and DOB of Date class. If class Date is defined inside a class called Student, we can call Date as inner class and Student as outer class. Rules of usage are as follows:
The nested classes can be divided into static and non-static as shown in Figure 18.2.
Figure 18.2 Nested classes
Class within a Class – Inner Class: Inner class is one of the techniques provided by Java to achieve reusability of the code. Inner class means a class containing another class or more than one class. Inner classes cannot be declared as static. There are four kinds of inner classes:
Example 18.15: DateStudent.java Student Class Contains Date Class. Constructors and Destructors of a Class
//StdNested.java
1. package com.oops.chap19;
2. import java.io.*;
3. class StdNested{
4. // member data or attributes
5. String name=”Ramesh”; // name of the student
6. int rollNo=50595;
7. double totalMarks=98.5;
8. String grade=”A”;
9. void UseInner() {
10. DateInner dateinner=new DateInner();
11. dateinner.DataDisplay();}
12. //Now define inner class DateInner
13. class DateInner{
14. int dd=15;int mm=10;int yy=10;
15. void DataDisplay(){
16. System.out.println(“Students Detail : outer class are………”);
17. System.out.println(“Roll Number:” + rollNo);
18. System.out.println(“Name:” + name);
19. System.out.println(“Total Marks:” + totalMarks);
20. System.out.println(”Grade:“ + grade);
21. System.out.println(“DOJ from inner class ………”);
22. System.out.println(“DOJ :”+dd+”/”+mm+”/”+yy);
23. } //end of DataDisplay()
24. }// End of class Dateinner
25. }//end of class StdNested
26. class StdNestedDemo {
27. public static void main(String[] args) {
28. StdNested stdouter = new StdNested();
29. stdouter.UseInner(); }
30. }// end of StdNestedDemo
Output: Students Details from outer class are………
Roll Number:50595
Name:Ramesh
Total Marks:98.5
Grade:A
DOJ from inner class ………
DOJ :15/10/10
18.191.93.12