The best programs are written so that computing machines can perform them quickly and so that human beings can understand them clearly. A programmer is ideally an essayist who works with traditional aesthetic and literary forms as
well as mathematical concepts, to communicate the way that an algorithm works and to convince a reader that the results will be correct. Donald E. Knuth

Classes and Objects

Basics of Java Classes and Objects
Everything in Java has to be encapsulated in a class since it is a truly object oriented language. Till now, we have been using classes just to satisfy the basic syntax of Java. Now we will see how classes and objects are used as a mechanism to follow a object oriented programming paradigm. A class is basically a template which define the structure of objects. Objects exhibits the properties and behaviours defined by its class. Class becomes a user-defined data type and any object of that class is a variable of that data type. Every class consists of some properties which are called fields and some behaviours which are represented in the form of methods in Java. For C++ programmers, fields are the data members and methods are the functions. The methods are defined such that they operate on the fields to perform some business logic. Let's see an example.

/* define a student class with necessary fields and methods */
class Student {
      /* declare the fields of the class */
      int roll;
      float percent;

      /* declare the methods */
      void setData(int roll_no, float percentage) { // stores the input data
	  roll = roll_no;
	  percent = percentage;
      }
      void getData() { // displays the stored data
          System.out.println("Student Info :- ");
          System.out.println("Roll : " + roll + "  Percentage : " + percent);
      }
}

public class StudentInfo {
   public static void main(String args[]) {
      Student stud1 = new Student();//create an object to store a student's info
      // call setData() to store student's roll and percentage
      stud1.setData(7, 73.67f); 
      Student stud2 = new Student(); // stud2 stores info about another student
      stud2.setData(11, 87.43f);
      /* display the information about 2 students */
      stud1.getData();
      stud2.getData();
   }
}

This program does a very simple task of taking 2 student's roll no. and percentage and then displays them.
First we define a class student with data members ( fields ) roll and percent. We also define two methods setData( ) and getData( ) which operate on data members. Thus, we see that data ( fields ) and methods related to an entity student is wrapped in a class. This is nothing but encapsulation.
So, a class student is now ready to be used as a data type.
Now, we declare two objects s1 and s2 of type student. Each of these objects have their own copy of the fields. So, memory for fields are allocated when objects are created. Memory for methods are allocated when the class is loaded. Finally, we take input and display data of two students using the respective objects and dot ( . ) operator. Following diagram shows the representation of the class student and the two objects s1 and s2 :

ClassObjects

student
roll, percent
inputData()
displayData()
s1 s2
roll = 3
percent = 87.39
roll = 7
percent = 75.43

Creating an object is also known as instantiating an object and the object itself is known as an instance of the class. In the above program, variables roll and percent are called instance variables since every instance of a class contain an individual copy of those variables.

Constructors
A constructor is a special type of method with the same name as that of the class and no return type. It is used to initialize the instance variables whenever an object is created. Every class has atleast one constructor. If we do not define any constructor explicitly, then the compiler automatically generates a default constructor. Default constructors take no arguments whereas parameterized constructors take one or more arguments. There can be more than one constructor in a class. Following program illustrates the use of constructor :

class SquareInfo {
   int size;
   SquareInfo(){}  // default constructor ( does nothing )
   SquareInfo(int length) { // parameterized constructor
      size = length;
   }
   int getArea() { // returns the area of the square
      int area = size*size; // compute area
      return area;
   }
}

public class Square {
   public static void main(String args[]) {
      SquareInfo sq = new SquareInfo(5); // create a new square of size 5 units
      int sq_area = sq.getArea();
      System.out.println("Area of the square is " + sq_area);
   }
}

Note : If no constructor is defined, then compiler generates the default constructor automatically. If a parameterized constructor is defined, then compiler no longer generates the default constructor. In that case, if we need to use the default constructor, then it has to be defined explicitly, else it would lead to compilation error.

Copy Constructor in Java
We can create a new object by copying the state of an old object. It means that the instance variables of the new object will be initialized with the the values of the instance variables of an old object. Following program illustrates this technique :

class CopyObjectDemo {
   int x, y;
   CopyObjectDemo(){}  // default constructor
   CopyObjectDemo(int val1, int val2) { // parameterized constructor
      x = val1;
      y = val2;
   }
   CopyObjectDemo(CopyObjectDemo cod) { // copy constructor
      x = cod.x;
      y = cod.y;
   }
   void displayData() { // displays the values of instance variables
      System.out.println("x = " + x + "  and  y = " + y);
   }
}

public class CopyObject {
   public static void main(String args[]) {
      CopyObjectDemo cod1 = new CopyObjectDemo(3, 7);
      CopyObjectDemo cod2 = new CopyObjectDemo(cod1);
      cod1.displayData();
      cod2.displayData();
   }
}


Static Members
Static Variables are global to the class and there is only one copy of each static variable created per class which is common to all objects. These variables are also known as class variables. Local variables cannot be declared as static.
Static Methods of a class are independent of any instance created and are accessed without using the object. They are known as class methods and are used to implement any logic/behaviour which is independent of the object. These methods can access only static data members and other static methods. In static context, we cannot use this or super. We will learn about these two keywords later in the tutorial.
Following program demonstrates the use of static variables and methods :

class StaticMembers {
   static int no_objects; // keep the count of no. of objects created
   int value; // instance variable
   StaticMembers() {
      /* Whenever a new object is created, constructor is
         invoked and we increment the object counter */
      no_objects++;
      value = 29;
   }
   static void displayObjCount() {
      // value++; // this is an error because 'value' is non-static
      System.out.println("No. of Objects created = " + no_objects);
   }
}

public class StaticDemo {
   public static void main(String args[]) {
      StaticMembers sm1 = new StaticMembers(); // one object created
      StaticMembers sm2 = new StaticMembers(); // another object created
      StaticMembers.displayObjCount(); // access static method using class name
   }
}

Why main( ) is static ?
Since the program execution begins at main( ), it has to be accessed even before the first object is created. Thus, main( ) is a static method.

Access Modifiers
Access modifiers in Java specifies the visibility or scope of variables and methods of a class i.e they control the accessibility of members of a class. The concept of access modifiers implements data abstraction in Java. We can impose different levels of protection on the members ( fields, methods, constructors ) of a class so that we can restrict the access to certain variables or methods from outside the class.
default access modifier : If we do not use any modifier with a class, variable or a method then, they can be accessed by any other classes in the same package ( a package is a collection of classes ).
public access modifier : If a class, method or variable is declared as public, then they can be accessed from any other class. However, if we are trying to access a public class in another package, then that class has to be imported.
private access modifier : This is most restrictive and private variables or methods cannot be accessed even by the objects of the same class. They can be accessed only by the public methods of that class. Using private modifier with variables, an object hides data from the external world ( data abstraction ). A good object oriented design strategy is to make fields private and provide access to them using public methods.
protected access modifier : This modifier makes the variables and methods accessible to all classes and subclasses in the same package and also to subclasses in the other packages. Subclass is a class derived from another class. We will elaborate this concept in the next section on inheritance.
Following program illustrates the use of public, private and protected modifiers.

class A {
   public int x = 5; // public modifier
   private int y = 7; // private modifier
   protected int z = 3; // protected modifier
   public int getY() { /* access the value of private variable
                          using a public method */
      return y;
   }
}
/* class B inherits from A */
class B extends A {
   int w = 13; // default modifier
   public void modifyVar() {
      x++;
      // y++; // compilation error ( y is not accessible )
      z++;
   }
   public void printVar() {
         System.out.println("x = " + x + " z = " + z + " w = " + w);
   }
}

public class AccessSpecifierDemo {
   public static void main(String args[]) {
      A obj1 = new A();
      int val_x = obj1.x;  // access public field
      //int val_y = obj.y;  // compile error ( object cannot access it )
      int val_y = obj1.getY();
      //int val_z = obj.z(); // compile error ( object can't access it )
      System.out.println("x = " + val_x + " y = " + val_y);

      B obj2 = new B(); // create an object of class B
      obj2.modifyVar();
      obj2.printVar();
   }
}


Aggregation of Classes
If a class has a data member ( instance variable ) which is an object of another class, then it is known as aggregation. Aggregation reflects a part of relationship between two entities ( classes ). Suppose there are two classes, Car and Wheel. Since Wheel is a part-of Car, we can declare an object of type Wheel as a data member of class Car. Aggregation or part-of relationship is a very important concept in object oriented programming and it allows reusability of an entire class. Following program illustrates this concept :

/*define a class 'Wheel' */
class Wheel {
   private float radius;
   Wheel() { }
   public void setRadius(float r) {
      radius = r;
   }
   public float getRadius() {
      return radius;
   }
}

/* define another class 'Car'
 * 'Wheel' is a part of 'Car'
 */
class Car {
   private int model_no;
   private String color;
   private Wheel w; // declare an object of 'Wheel' type
   Car() {
     w = new Wheel(); // instantiate the object of class 'Wheel'
   }
   public void setCarInfo(int car_model, String car_color, float wheel_radius) {
      model_no = car_model;
      color = car_color;
      w.setRadius(wheel_radius);
   }
   public void getCarInfo() {
      System.out.println("Model : " + model_no);
      System.out.println("Color : " + color);
      System.out.println("Wheel Radius : " + w.getRadius());
   }
}

public class AggregationDemo {
   public static void main(String args[]) {
      /* declare an object of type 'Car'
         object of type 'Wheel' is automatically instantiated */
      Car c = new Car();
      c.setCarInfo(7188, "red", 103.76f);
      c.getCarInfo();
   }
}


' this ' keyword
this keyword refers to the object that is currently invoking a method. It has a lot of usage but we will demonstrate two use cases :
1 ) Refer to instance variable of the class
2 ) Invoking the constructor of the class
Following program illustrates the use of this keyword :

class Employee {
   int id;
   String name;
   int dept_id;
   Employee() { // default constructor
      dept_id = 7; // assume dept_id is common to all employees
   }
   /* parameterized constructor
    * arguments and instance variables are same ( 'this' keyword
    * removes the ambiguity )
    */
   Employee(int id, String name) {
      this(); // invoke the default constructor
      this.name = name;
      this.id = id;
   }
   void displayData() {
      System.out.println("Dept. Id : " + dept_id);
      System.out.println("Employee Name : " + name);
      System.out.println("Employee ID : " + id);
   }
}

public class ThisKeywordDemo {
   public static void main(String args[]) {
      Employee emp = new Employee(4417, "Rahul");
      emp.displayData();
   }
}

Back | Next