Chapter 4

Interfaces and Packages in Java

by Debasis Samanta


CONTENTS

Introduction

There is no concept of multiple-inheritance in Java, but, Interfaces in Java are, for the most part, unique to the language, play a role similar to that of multiple-inheritance. Another unique feature in Java is Packages. Packages are containers for classes that are used to keep the class name space compartmentalized. By organizing the users classes into packages, their reusing to write other classes are easier. This Chapter is for getting a lesson of Interfaces and Packages.

Interfaces in Java

An interface in Java is essentially a special kind of class. Like classes, interfaces contain methods and variables; unlike classes, interfaces are always completely abstract. Let us first take a look at the general form of an interface definition.

  interface  InterfaceName [ extends Name1, [ Name2, . . . .  ]  {
		[ Variable  declaration ; ]
		[ Method declaration ; ]
	}

Thus, an interface is defined just like a class except the key word interface in place of class. Although member elements are present in an interface they are static and final; although methods are defined in an interface, the code to implement the method is not. While classes can inherit from only one super class but, interfaces are able to inherit from as many as interface one can provide.

After defining an interface, it is require to implement with classes which can be done with the following syntax :

  class  ClassName [ extends SuperClassName ]
		[ implements InterfaceName1 [, Interface Name2 …] )  {
			class body 
	}

Now, let us consider an example to illustrate the use of interface technique. See the Figure 4.1 Here, Teacher and Student are two classes each of them having their own unique components. We want to define an interface, say, Resume which will include all the components both in Teacher and Student.


Figure 4.1 :Interface of classes

Following is the Illustration 4.1 to snap shot the implementation of the above and its use.


Illustration 4.1				

    interface Resume {
	    ……. 				
	   void bioData (  ) ; 			// By default it is an abstract method.
		…………			                // when it is declared in an interface
	} 
 
   class Teacher extends Employee implements Resume {
		. . .  . 				// Assume Employee is a class defined some where
	    Qualification ; 			// A  member element			
		……..
		experience (  )  {………}   	// A member function 
		……….
		public void bioData (  ) {
			                       // Code for this method for preparing the bio-data of a teacher //
		}
	}

    class Student implements Resume {
	    …….
        Discipline; 			// A member element.
        ……….
        result (  ) { …….} 		// A member function
        ……..

    public void bioData (  ) {
				// Code for  the method for preparing the bio-data of a student //
		}
	}

In this example, the interface Resume is declared which is implemented by two classes: Teacher and Students; Teacher is an inherited class from a class Employee ( the definition of all classes are understood ). With this definitions it should be noted that the method (s ) which is / are in interface must be defined in their respective classes with which the interface is implemented. We can, therefore, run the following through a main class which extends the above defined interface, namely Resume.


Teacher x = new Teacher (  ) ;   	//   X is an instance of Teacher 
Student y = new Student (  ) ; 	//  Y is an instance of Student 
Resume object ; 			//   Object is reference to an instance of Resume.
object  = x;  		        	//   Object is now a teacher 
object. bioData (  ); 	        	//   Obtain the bio-data of  a teacher X
object  = y ; 		       	//   Object is now a student 
object. bioData 		      	//   Obtain the bio-data of a student Y

Note that for object.bioData( ); at line 5, and object.bioData ( ); at line 7 of the above piece of codes, the respective codes for preparing bio-data of Teacher and Student will be in effect.

If the above mentioned example is a skeleton of how a method is sharable in two classes then following is the Illustration 4.2 giving executable code how member elements are sharable.


Illustration 4.2 				

/*Creating an interface and using the same in a Java program*/

package myInterface;
  
public interface anInterface { 
     
    //final public static int a = 10; // public, static and final 
    int a = 10; // public, static and final 
    void display();  // public and abstract 
} 

import myInterface.*;
  
// A class that implements interface.
 
class Demonstration_91 implements anInterface { 
       public void display()  // Implementing the abstract method    
    { 
        System.out.println("Fine!"); 
    } 
  
    // The main method()
    public static void main (String[] args)     { 
        Demonstration_91 t = new Demonstration_91(); 
        t.display(); 
        System.out.println("The final value a in myInterface "+ a); 
    } 
}

Illustration 4.3				

/* Interface, in many way, similar to a class; however, no object can be instantiated from an interface. The following program is to illustrate this fact. */

interface C {
    public static void int i = 555;
    void printInterface();
}

 
//Attempting to create an object of interface
  class Demonstration_92 { 
        public static void main (String[] args)     { 
              C c = new C(); //ERROR: Object cannot be instantiated
               
              C c2; // OK: Declaration of object is possible

              C c3[] = new C[]; // This is also OK: declaration of
                 // array of objects for an interface is permitted.
       } 
  }

Interface methods

Interface methods are those methods which are abstract methods appearing in the interface. Here, we will see, how they expect attention from the programmer. If a class implements an interface but does not implement one or more of interface’s methods, the whole class becomes an abstract class and cannot be instantiated. Let us take a look at a brief example ( Illustration 4.4 ) of this :


Illustration 4.4					

interface I1 {
     
    public static final double PI = 3.1413434567;   //OK
    static final double lambda = 0.04; //OK: public is implicit

    //int x;  //Declaration of any instance variable is NOT allowed.
	int x=100;// Initialization of variable is necessary.
	
	//private static final int p = 444;   
                   //ERROR: private/ protected is NOT allowed.
	//abstract public static void methodI1(); // Static method is not allowed

	void methodI2(); //public abstract by default
}


class A1 implements I1 {
       public int a1 = 555;
       public void methodI1(){
           System.out.println("From I1 " + PI);
       }
       public void methodI2(){
          System.out.println("Again from I1 " + lambda); 
      }
}

  // Here, is the main class
public class Demonstration_93 {
	public static void main(String[] args) {
		A1 a = new A1();
        a.methodI1();
        a.methodI2();
     }
}


Illustration 4.5					
/* We have learnt that a class MUST implements an interface and then that 
class will be used as a normal class. However, the reverse is not true. 
That, is an interface cannot implement another interface */

interface I1 {
    public static int i = 555;
    void printInterface();
}

//The following code is invalid!

interface I2 implements I1 {
    public static int j = 111;
    public void printInterface(){
             System.out.print("Geek!");
   }
}

Illustration 4.6				

// We have learnt that a class MUST implements an interface and then that class will be used as a normal class. However, the reverse is not true. That is, an interface cannot implement another class (abstract or non-abstract */

/*OR 
The following code that an interface implements a class is also invalid! */

//The following code is invalid!

abstract class  C {
    public static int j = 111;
    void print(){
             System.out.print("Geek1!");
   }
}


interface I2 implements C {
    public static int j = 222;
    void print (){
             System.out.print("Geek2!");
   }
}

Illustration 4.7					

/* An interface method cannot be made final */

interface I1 {
    public static int i = 555;
    public final static void printInterface(); //ERROR
}

//The following code is invalid!

class C implements I1 {
    public static int j = 111;
    void printInterface(){
             System.out.print("Geek!");
   }
}

Inheritance in Interfaces

Like classes, interfaces also have a chain of inheritance i.e. an interface can be derived from other interface. Consider the example, given below :


Illustration 4.8				

/* An interface acts like a class. 
That is, we can do everything as we do with class except the object instantiation. Here, is an example on the single inheritance with interface.
*/
interface I1 {
    double x = 4.444;
	void methodI1(); //public static by default
}

interface I2 extends I1 {
    double y = 5.555;
	void methodI2(); //public static by default
}


class A1 implements I2 {
       public int a1 = 555;
	   
       public void methodI1(){
           System.out.println("From I1"+x+y);
       }
       public void methodI2(){
          System.out.println("From I2"+x+y); 
      }
}   
	

public class Demonstration_97 {
	public static void main(String[] args) {
	  A1 a = new A1();
	  a.methodI1();
	  a.methodI2();
     }
}


OUTPUT:
From I14.4445.555
From I24.4445.555


Illustration 4.9				

/* An interface is a significant feature in Java in the sense that  it enables the multiple inheritance. Here, is an example on the multiple inheritance with interface.
Case 1:  Example of class which "implements" two interfaces 
*/

interface I1 {
    int i = 123;
    void printI1();
    }


interface I2 {
    public static int j = 555;
    void printI2();
}

class A implements I1, I2{
     public int aValue = 999;
     
     public void printI1() {
          System.out.println("I am from I1 " + i);
     }
     public void printI2() {
         System.out.println("I am from I2 " + j);    
    }
    public void printA() {
         System.out.println("I am from A " + (aValue = i+j));    
    }

}

class Demonstration_98 { 
        public static void main (String[] args)     { 
		  A a = new A(); 
		  a.printA(); 
		  a.printI2(); 
		  a.printI1(); 
    } 
}


OUTPUT:
I am from A 678
I am from I2 555
I am from I1 123


Illustration 4.10					

/* Example on the multiple inheritance with interface.
Case 2:  Example of "extends" with "implements"
*/

class A {
    protected int j = 1000;
    void print() { System.out.println("I am from A "+j);
    }
}

interface I {
    public static int i = 555;
    void printInterface();
}

class B extends A implements I{
     public int aValue = 999;
     
     public void printInterface() {
          System.out.println("I am from I " + i);
     }
     public void printB() {
         super.print();
         printInterface();
    }
}


//Driver code in main class
public class Demonstration_99 { 
        public static void main (String[] args)     { 
			  B b = new B(); 
			  b.printB(); 
    } 
}

OUTPUT:
I am from A 1000
I am from I 555


Illustration 4.11					

/* Example on the multiple inheritance with interface. */

/* Case 3:  Example of extends with implements two or more interfaces*/


class A {
    protected int i = 1000;
    public void print() { System.out.println("I am from A "+i);
    }
}

interface C {
    public static int j = 555;
    void printInterfaceC();
}

interface D {
    public static int k = 666;
    void printInterfaceD();
}

class B extends A implements C, D{
     public int aValue = 999;
     public void printInterfaceC() {
          System.out.println("I am from C " + j);
     }
     public void printInterfaceD() {
          System.out.println("I am from D " + k);
     }
public void printB() {
         super.print();
         printInterfaceC();
         printInterfaceD();
    }

}


class Demonstration_910 { 
	public static void main (String[] args)     { 
		  B b = new B(); 
		  b.printB(); 
   } 
}


OUTPUT:
I am from A 1000
I am from C 555
I am from D 666


Illustration 4.12					
/* How an interface helps a programmer? A program demonstrating sharing variables like a library */

package myInterface;

public interface SharedConstants {
	   int NO = 0;
	   int YES = 1;
	   int MAYBE = 2;
	   int LATER = 3;
	   int SOON = 4;
	   int NEVER = 5;
}
import myInterface.*;

class Demonstration_911 implements SharedConstants {
    static void answer(int result) {
        switch(result) {
 		case NO:
	    		System.out.println("No");
 	    		break;
          case YES:
	    		System.out.println("Yes");
              	break;
   		case MAYBE:
	    		System.out.println("Maybe");
 	    		break;
 		case LATER:
	    		System.out.println("Later");
 	    		break;
 		case SOON:
	    		System.out.println("Soon");
			break;
		case NEVER:
 	    		System.out.println("Never");
	    		break;
 		}
       }
   
 
public static void main(String args[]) {
	Question q = new Question();
	answer(q.ask());
	answer(q.ask());
	answer(q.ask());
	answer(q.ask());
	}
}

Illustration 4.13					

/* Runtime polymorphism with interface objects
   GeoAnalyzer program implementation using interface */

package myInterface;
 
interface GeoAnalyzer {
	final static float pi = 3.142F;
	float area();
	float perimeter();
}

class Circle implements GeoAnalyzer {
	float radius;

	Circle(float r) {
		radius = r;
	}

	public float area() {
		return (pi * radius * radius);
	}

	public float perimeter() {
		return (2 * pi * radius);
	}
}

class Ellipse implements GeoAnalyzer {
	float major;
	float minor;

	Ellipse(float m, float n) {
		major = m;
		minor = n;
	}

	public float area() {
		return (pi * major * minor);
	}

	public float perimeter() {
		return (pi * (major + minor));
	}
}
class Rectangle implements GeoAnalyzer {
	float length;
	float width;

	Rectangle(float l, float w) {
		length = l;
        width = w;
	}

	public float area() {
		return (length * width);
	}

	public float perimeter() {
		return (2 * (length + width));
	}
}

class Demonstration_92 {
	static void display(float x, float y) {
		System.out.println("Area = " + x + "Perimeter = " + y);
	}

public static void main(String args[]) {
	Circle c = new Circle(5.2f);
	Ellipse e = new Ellipse(4.5f, 3.6f);
	Rectangle r = new Rectangle(6.5f, 4.3f);
	GeoAnalyzer geoItem;
	geoItem = c;
	display(geoItem.area(), geoItem.perimeter());
	geoItem = e;
	display(geoItem.area(), geoItem.perimeter());
	geoItem = r;
	display(geoItem.area(), geoItem.perimeter());
	}
}


OUTPUT:
Area = 84.95968Perimeter = 32.6768
Area = 50.9004Perimeter = 25.450201
Area = 27.95Perimeter = 21.6


Illustration 4.14					

// Runtime polymorphism with abstract class
   GeoObjects program implementation using abstract class 

// Abstract class versus Interface …

//An abstract class  and its sub class 

package myInterface;

public abstract class Geometry {
  public abstract double area ();
  public abstract double circumference();
}

package myInterface; import myInterface.*; // Extending Geometry for Circle class Circle extends Geometry { public double r; protected static final double PI = 3.14159265358979323846; public Circle (}{ r=1.0 } public Circle (double r){ this.r=r; } public double area() { return PI*r*r; } public double circumference() { return 2*PI*r; } public double getRadius() { return r; } } class Rectangle extends Geometry { protected double l,w; public Rectangle() { l = 0.0; w = 0.0; } public Rectangle(double l, double w) { this.l = l; this.w = w; } public double area() { return l*w; } public double circumference() { return 2*(l+w); } public double getwidth() { return w; } public doub;le getlength() { return l; } }
package myInterface; import myInterface.*; class Ellipse extends Geometry { protected double a,b; public Ellipse() { a = 0.0; b = 0.0; } public Ellipse(double a, double b) { this.a = a; this.b = b; } public double area() { return PI * a*b; } public double circumference() { return PI*(a+b); } public double getMinorAxis() { return a; } public double getMajorAxis() { return b; } }
package myInterface; import myInterface.*; public class GeoDemo { public static void main(String args[]) { // use the above class definition Geometry [] geoObjects = new Geometry[3] // create an array to hold Geometry objects geoObjects [0] = new Circle (2.0); geoObjects [1] = new Rectangle (1.0,3.0); geoObjects [2] = new Ellipse (4.0,2.0); double totalArea = 0; for (int i = 0; i < 3; i++) { totalArea = totalArea + geoObjects[i].area(); } Sytem.out.println(“Total area of the geo-objects is “ ” + totalArea); }

Packages in Java

One of the main advantage of object oriented programming is its ability to reuse code by sub classing existing classes (that is by inheritance ) where programmers have to define the difference between super class and sub class. Although this is an extremely powerful capability but its real benefit cannot be achieved unless one have the complete knowledge of library of classes. There are two problems occurs with library of classes : one is the problem in name collisions and the other is to control the visibility of classes, interfaces, methods, and the variables define within them. The solution to these problems is the use of systematic class libraries, or what Java refers to as packages.

Packages are collection of classes and interfaces, usually according to functionality, such as graphics, audio, text, or project. Here, we are to organize our classes and interface so that reusing these packages in other programs will be easier. Having a package organization, a programmer can refer this package by import statement as the first non-comment statement of a program. When a class is referred to in a program, the compiler will check all the imported packages to find out where the class is defined. If there is only one imported packages to find out where the class is defined, the definition of the class in that package will be used. If more than one imported package contains the definition of the named class, then there is ambiguity which can be resolved by specifying the exact reference (e.g. there is a class Abc located in both the package X and Y and we want to refer the Abc in Y, then its reference should be Y.Abc).

All classes and interfaces in a package are accessible to all other classes and interfaces in that package. All the member elements and method of a class can be accessed from any method of any class under the same package, except when the data and method are declared private. In the next few sections, we are to discuss about the handling and managing packages.

API : The built-in Java Packages

Most of the time, our primary dealings with packages provided with the Java release. The Java Development Kit contains over 15 packages that we can use to obtain classes for use in our programs. All these built-in packages are known as the core API (Application Programming Interface). This standard set of libraries are extremely useful for writing Java programs and evolved over several years of writing Java code to implement a variety of systems, ranging from consumer device networks to animated user interfaces to operating systems to compiler. Many people, both from inside and outside Sun, have been involved in the design of the API.

The API contains the following packages :

Core packages 
	java.lang : The Java language Package
	java.io :   The Java  I/O Package 
	java.util   : The Java Utility Package 
	java.net   : The Java Networking Package

Window Toolkit and applet 
	java.awt 	: Abstract Window Toolkit (AWT) package 
	java.awt. image 	: The AWT Image package 
	java.awt. peer    	: The AWT peer package 
	java.applet       	: The Java Applet package 

Let us take an overview of the API.

java. lang : The Java language package
    The java.lang package provides the classes and interfaces that form the core of the Java language and the Java Virtual Machine. For example, the classes Object, String, and Thread are used by almost every program and are closely inter wined with the Java language definition. Other classes define the Exceptions and Errors that the Java Virtual Machine can throw. Another set of java.lang classes provide wrappers for primitive types. For example, the Integer class provides object to  contain int values. 
    Note :The java.lang package is imported automatically into  every Java program.

java. io : The Java I/O package 
    The java.io package provides a set of input and output (I/O ) streams used to read and write data to files or other I/O sources. Java streams are byte oriented and the classes defined here can be chained to implement more  sophisticated stream functionality.   

java util : The Java  utility package 
     The java.util package contains a collection of utility classes and related interfaces. It includes classes that provide generic data structures (Dictionary, Hashtable, Stack, Vectors ), String  manipulation (String Tokekenizer ), Calender  and date utilities (Date). The java.util package also contains the Observer interface and  Observable class, which allow objects to notify one another when they change. 

java net : The Java Networking package 
     The java.net  package contains networking classes and interfaces, including classes that represent a URL and URL  connection, classes that implement a socket connection, and a class that represent an Internet address.

java .awt : The Abstract Window Tool kit package
     The java.awt package provides the standard graphical user interface (GUI) elements  such as buttons, lists, menus, and text areas. It also includes containers (such as windows and menu bars) and higher-level components( such as dialogs for opening and saving files). The  AWT contains two more package java.awt.image and java.awt.peer.

java.awt.image : The AWT Image package 
     The java.awt.image package contains classes and interfaces for performing sophisticated image processing. These classes and interfaces  can be used by applications that need to create or manipulate images and colors.

java.awt.peer : The AWT Peer package
     The java.awt.peer package contains interfaces used to connect AWT components to their window system-specific implementation  such as Motif widgets  ). Unless you are creating a window system specific implementation  of the AWT, you should not need to use the interfaces in the java.awt.peer package.

java.applet : The Applet package
    The java.applet package contains classes and interfaces for creating applets. 

The Java API is generally consulted by the advance Java programmer, and this Part is to give the Java programming for beginners. The complete API documentation is presented in the Part III of this book.

Using API Packages :

After a stock of the API, we will see how they can be used in Java programs. Suppose, in the package java.util, there is a class called Date. If you want to use this class in order to instantiate an object from that you should use the fully qualified class name; a code fragment is given :

	   java.util.Date toDay = new java.util.Date( );
		System.out.print (toDay);

One can pull a class or can pull all the classes from a package. Java provides the import keyword to allow one to import specific classes or entire packages. The import key word is used as follows :

	 import PackageName.ClassName ;	    // To get access of a  specific class ClassName
	 import PackageName.* ; 			// To get access the enter package PackageName
 

By importing this way, we no longer have to use its fully qualified ClassName to use it. An example is given below :

	  import java.util.Date; 			// or import java.util.*;
		Date toDay = new Date( );
		System.out.print (toDay);

Illustration 4.15					

// Accessing a package from a Java built-in APIs

import java.lang.*;  //Math class is defined in this package
 
   class Calculator{
       double i;
       double x ;
	   void p(){
		   x = Math.sqrt(i);
	   }
	   
   }

   class Demonstration_81{
     public static void main(String args[]){
	   Calculator a = new Calculator();
	   a.i = 20.0;
	   a.p();
	   System.out.println("Square root of "+a.i+" is "+a.x);
     }
}


OUTPUT:
Square root of 20.0 is 4.47213595499958


Illustration 4.16					

/* Java program to demonstrate accessing of members when it is imported */

import java.util.Vector; 
   
class Demonstration_82 { 
   public Demonstration_82()    { 
      // java.util.Vector is imported, hence we are 
      // able to access directly in our code. 
      Vector newVector = new Vector(); 
      // The code dealing with the object newVector…..   
   } 
   
   public static void main(String arg[]) 
   { 
      //Here is the code in the main class… 
   } 
}


Illustration 4.17					

/* Java program to demonstrate accessing of members when it is not imported explicitly*/
   
public class Demonstration_83 { 
   public Demonstration_83()    {   
      java.util.ArrayList newList = new java.util.ArrayList(); 
      
      // java.util.ArrayList is not imported, hence we referring 
      // to it using the complete  package. 

      // The code dealing with the object newList…..   

   } 
   
   public static void main(String arg[])   { 
      //Here is the code in the main class…
   } 
}

Illustration 4.18					

/* Importing an entire package, that is, all classes in a package */

import java.util.*;
  
public class Demonstration_84 { 
   public Demonstration_84()    { 
      Vector newVector = new Vector(); 
      // java.util.Vector is imported, hence we are 
      // able to access directly in our code. 

      ArrayList newList = new ArrayList();
   
      // java.util.ArrayList is imported, hence  
      // we are able to accees it directly in the program 
      // package.  
   } 
   
   public static void main(String arg[]) 
   { 
      // The code dealing with the object newVector and newList…..   

   } 
} 

Organization of user packages

Till this point we have discussed about packages from the system packages. Now, a user can develop several classes and then wish to share with different programs. To do this, user has to construct his own package. Let us consider an example for this. Suppose, we want to create a simple package which will contain only one class, say MyClass. Let the name of the package be MyPackage. Illustration 4.19 is for this purpose.


Illustration 4.19					// User defined Package //
/*Creating a user's own package */

/*Save the following code as myClass.java in a sub-directory, say myPackage. Compile the .java file and save the .class file in the same sub-directory */
   
package myPackage; 
 
public class myClass {  
  public void msg(){System.out.println("Class: Hello! ");}  
}

This listing would be saved in a file called MyClass.java and would be located in directory named MyPackage. The class then should be compiled and compiled version (i.e MyClass.class ) would be stored in the same directory as in source file ( i.e. MyPackage). Now, let us finish the example by looking at a simple program that will import the class MyClass from the package MyPackage:

/*Save the following code as Demonstration_85.java in a sub-directory, say Demonstration_85 */
 
import myPackage.myClass;  
  
class Demonstration_85{  
	public static void main(String args[]){  
		myClass obj = new myClass();  
		obj.msg();  
	}  
}


Illustration 4.20					

/*Creating a user’s own package */

/*Save the following code as myClass1.java in a sub-directory, say myPackage. Compile the .java file and save the .class file in the same sub-directory */
   
package myPackage; 
 
public class myClass1 {  
  public void msg(){
  System.out.println("muClass1: Hello! ");
  }  
}  


/*Save the following code as myClass2.java in the same sub-directory myPackage. Compile the .java file and save the .class file in the same sub-directory */
   
package myPackage; 
 
public class myClass2 {  
  public void msg(){
  System.out.println("muClass2: Hello! ");
  }  
}  

/*Save the following code as Demonstration_86.java in a sub-directory, say Demonstration-VIII */

 
import myPackage.*;  
  
class Demonstration_86{  
  public static void main(String args[]){  
   myClass1 obj1 = new myClass1();  
   obj1.msg(); 

   myClass2 obj2 = new myClass2();  
   obj2.msg();  
 
  }  
}


Illustration 4.21					

// Careful about default access specification. Check the following… 

package myPackage;    // Creating a package with class myClass1
 
class myClass1 {  
  public void msg(){
  System.out.println("muClass1: Hello! ");
  }  
}  

package myPackage;   // Creating a package with class myClass2
 
class myClass2 {  
  public void msg(){
  System.out.println("muClass2: Hello! ");
  }  
}  

import myPackage.*;  
  
class Demonstration_87{  
  public static void main(String args[]){  
      myClass1 obj1 = new myClass1();  
      obj1.msg(); 
      myClass2 obj2 = new myClass2();  
      obj2.msg();  
  }  
}


Illustration 4.22					

//Example of package by import package.classname
//Save the class as A88.java   
 
package myPackage; 
 
public class A88{  
  public void msg(){
  System.out.println("Class A88: Hello");
  }  
}  

//Save the following Java program as  Demonstration_88.java 
 
import myPackage.A88;  
  
class Demonstration_88{  
  public static void main(String args[]){  
   A88 obj = new A88 ();  
   obj.msg();  
  }  
}


Illustration 4.23					

// Example of package by import package.classname
//Save the class as A88.java   
 
package myPackage; 
 
public class A88{  
  public void msg(){
  System.out.println("Class A88: Hello");
  }  
}  

//Save the following Java program as  Demonstration_89.java 
 
import myPackage.A88;  
  
class Demonstration_89{  
  public static void main(String args[]){  
   myPackage.A88 obj = new myPackage.A88 ();//using the fully qualified name                           
   obj.msg();  
  }  
}


Illustration 4.24					

/* A simple package: Utilization of package in any java application */

package myPackage;     // Adding another class into myPackage

public class Balance {
String name;
double bal;

Balance(String n, double b) {
	name = n;
	bal = b;
}

void show() {
	if (bal < 0) {
	System.out.print("Sorry! Negative balance ");
	}
	System.out.println(name + ": $" + bal);
	}
}


// Run the following java program from Demonstration-VIII directory

import myPackage.*;

class Demonstration_810{
public static void main(String args[]) {
	Balance current[] = new Balance[3];
	current[0] = new Balance("D. Samanta", 123.23);
	current[1] = new Balance("T. Ahmed", 157.02);
	current[2] = new Balance("N. Sinhababu", -12.33);

	for (int i = 0; i < 3; i++) {
	current[i].show();
     }
   }
}


Illustration 4.25					
/* Can the same class name but in two different packages and the classes are then referred in a java program? */


package myPackage1;   // Creating a package myPackage1

 public class myClass { 
    public void msg1() { 
    System.out.println("Hello! It is myPackage1 Class!! "); 
    } 
} 

package myPackage2;   // Creating a package myPackage2

 public class myClass { 
    public void msg2() { 
        System.out.println("Hello! It is myPackage2 Class!! "); 
    } 
} 

import myPackage1.myClass; 
import myPackage2.myClass; 
  
public class Demonstration_811{ 
    public static void main(String[] args){ 
        myPackage1.myClass a = new myPackage1.myClass(); 
        myPackage2.myClass b = new myPackage2.myClass (); 
        a.msg1(); 
        b.msg2(); 
    } 
} 



Illustration 4.26					

/* Can we use a class in a package to derive a sub-class? */

package myPackage;     // A class in a myPackage

public class Balance {
	String name;
	double bal;

Balance(String n, double b) {
	name = n;
	bal = b;
}

void show() {
	if (bal < 0) {
	System.out.print("Sorry! Negative balance ");
	}
	System.out.println(name + ": $" + bal);
	}
}
/* Derive a sub-class in a program to be run from Demonstration-VIII directory */

import myPackage.Balance;

public class Savings extends Balance{
     String branch;
     Int customerID;
     Savings(String n, double bal, String br, int id) {
         Balance(n, bal);
         Branch = br;
         customerID = id;
     }

void show() {
	if (bal < 0) {
	System.out.print("Sorry! Negative balance ");
	}
	System.out.println(name + ": $" + bal + “ “+ branch + “ “+id);
}



class Demonstration_810{
	public static void main(String args[]) {
	Savings current[] = new Savings[3];
	current[0] = new Balance("D. Samanta", 123.23, “Kolkata”, 555);
	current[1] = new Balance("T. Ahmed", 157.02, “Chennai”, 420);
	current[2] = new Balance("N. Sinhababu", -12.33, “Mumbai” + 999);

	for (int i = 0; i < 3; i++) {
	current[i].show();
	}
  }
}


Illustration 4.27				

/* This program shows all combinations of the access control modifiers. In this program, we define two packages and five classes.

MyPackage1:
	class X
	class Y  extends X
	class A
MyPackage2:
	class Z extends X
	class B
*/
// Defining package MyPackage1

package MyPackage1;
 
public class X {
	int n = 1;
	private int p = 2;
	protected int q = 3;
	public int r = 4;	
	// A constructor of the class protection	
	public X() {
		system.out.println("I am constructor from class X:");
		system.out.println("n="+n);
		system.out.println("p="+p);
		system.out.println("q="+q);
		system.out.println("r="+r);
	}
}
//Save this as X.java in Mypackage1 directory


package MyPackage1;
 
class Y extends X {
	Y() {
	system.out.println("I am constructor from class Y:");
	system.out.println("n="+n);
	system.out.println("p="+p); // Error p is a private
					  // member of X. Not accessible outside X.
	system.out.println("q="+q);	// Protected is accessible
	system.out.println("r="+r);	// public is accessible
	}
}
//Save this as Y.java in Mypackage1 directory



//Save this as A.java in Mypackage1 directory

class A { 	        // class with default protection
	A() {   	        // default constructor with default access
	X x = new X();    // create an object of class X	
	System.out.println("Same package constructor ....");
	System.out.println("n from A"+x.n);  
	// Default variable is accessible in the same package
	System.out.println("p from A"+x.p);	// Error 
	System.out.println("q from A"+x.q);	//Error 
	 System.out.println("r from A"+x.r); // OK: public 
	}
}
//Save this as Z.java in Mypackage2 directory
   package MyPackage1; 
   class Z extends MyPackage1.X {
      Z() {
		System.out.println("I am constructor from class Z:");
		System.out.println("n from Z"+n); // Error:
		// Default is not accessible outside its package.
		System.out.println("p from Z"+p); // Error : private of X 	   
		System.out.println("q from Z"+q);
		// Protected member is accessible by inheritance
		System.out.println("r from Z"+r);
		// public is accessible
	}
     }



//Save this as B.java in Mypackage2 directory

class B {	    // class with default protection		
	 B() {     // default constructor with default access
	 MyPackage1.X x = new MyPackage1.X();  
	 // create an object of class X			
	 System.out.println("I am constructor from class B of MyPackage2");
	 System.out.println("n from B of myPackage2"+x.n); 
	 // default variable but is not accessible in this package
	 System.out.println("p from B of myPackage2"+x.p);	
	 // Error 
	 System.out.println("q from B of myPackage2"+x.q);
	 // Error protection 
	 System.out.println("r from A of myPackage2"+x.r);
	}
}


/* Finally, run the above0defined classes from any working directory…*/

//This is the demo of MyPackage1

import MyPackage1.*;

public class Demo1{
	public static void main(String args[])
	  X x1 = new X();
	  Y y1 = new Y();
	  A a1 = new A();		
}
//This is the demo of MyPackage2

import MyPackage2.*;
public class Demo2{
	public static void main(String args[])	
	  Z z2 = new Z();
	  B b2 = new B();		
}

Managing user packages

Packages solves many problems from an access control and name space collision perspective. However, it does cause some curious difficulties when you are compiling and running your programs. Compiling your program to make use of your own packages can be slightly more difficult then using the standard packages. The Java compiler automatically knows where to look for the Java Packages. But for user packages, it is the responsibility of the user to specify it and hence a source of complexities. Three cares should be taken in order to avoid the complexities :

  • Exact location of the package should be mentioned in package statement. One can specify the directory hierarchy also, e.g.
    package Project.Fractal.Geo;
      This means that the class (es) is (/ are) stored in project / fractal / geo directory.
  • The directory in which package is stored should be under the directory where Java applications want to share the package classes. For example, for Illustration 4.7, directory hierarchy appear as :
  • By setting the system variable CLASSPATH. The specific location that the Java compiler will consider as the root of any package hierarchy can be controlled by CLASSPATH.
    e.g. SET CLASSPATH = Java \ classes ; Java \ project \ packages;
      with this then compiler will be enforced to resolve a package name for an import statement.
  • Practice Questions
    Practice 4.1
    /* A simple package */
    
    	package MyPack;
    
    	class Balance {
    	String name;
    	double bal;
    
    	Balance(String n, double b) {
    	name = n;
    	bal = b;
    	}
    
    	void show() {
    	if (bal < 0) {
    	System.out.print("--> ");
    	}
    	System.out.println(name + ": $" + bal);
    	}
    	}
    
    	class AccountBalance {
    	public static void main(String args[]) {
    	Balance current[] = new Balance[3];
    	current[0] = new Balance("K. J. Fielding", 123.23);
    	current[1] = new Balance("Will Tell", 157.02);
    	current[2] = new Balance("Tom Jackson", -12.33);
    	for (int i = 0; i < 3; i++) {
    	current[i].show();
    	}
    	}
    	}
    what is the output?
    
    Practice 4.2
    /* An  example of interface in Java */
    
    	interface GeoAnalyzer {
    	final static float pi = 3.142F;
    	float area();
    	float perimeter();
    	}
    
    	class Circle implements GeoAnalyzer {
    	float radius;
    
    	Circle(float r) {
    	radius = r;
    	}
    
    	public float area() {
    	return (pi * radius * radius);
    	}
    
    	public float perimeter() {
    	return (2 * pi * radius);
    	}
    	}
    
    	class Ellipse implements GeoAnalyzer {
    	float major;
    	float minor;
    
    	Ellipse(float m, float n) {
    	major = m;
    	minor = n;
    	}
    
    	public float area() {
    	return (pi * major * minor);
    	}
    
    	public float perimeter() {
    	return (pi * (major + minor));
    	}
    	}
    
    	class Rectangle implements GeoAnalyzer {
    	float length;
    	float width;
    
    	Rectangle(float l, float w) {
    	length = l;
    	width = w;
    	}
    
    	public float area() {
    	return (length * width);
    	}
    
    	public float perimeter() {
    	return (2 * (length + width));
    	}
    	}
    
    	class Geometry {
    	static void display(float x, float y) {
    	System.out.println("Area = " + x + "Perimeter = " + y);
    	}
    
    	public static void main(String args[]) {
    	Circle c = new Circle(5.2f);
    	Ellipse e = new Ellipse(4.5f, 3.6f);
    	Rectangle r = new Rectangle(6.5f, 4.3f);
    	GeoAnalyzer geoItem;
    	geoItem = c;
    	display(geoItem.area(), geoItem.perimeter());
    	geoItem = e;
    	display(geoItem.area(), geoItem.perimeter());
    	geoItem = r;
    	display(geoItem.area(), geoItem.perimeter());
    	}
    	}
    what is the output?
    
    Practice 4.3
    	/* Interface with sharing member elements */
    
    	import java.util.*;
    
    	interface SharedConstants {
    	int NO = 0;
    	int YES = 1;
    	int MAYBE = 2;
    	int LATER = 3;
    	int SOON = 4;
    	int NEVER = 5;
    	}
    
    	class Question implements SharedConstants {
    	Random rand = new Random();
    
    	int ask() {
    	int prob = (int) (100 * rand.nextDouble());
    	if (prob < 30) {
    	return NO; // 30%
    	} else if (prob < 60) {
    	return YES; // 30%
    	} else if (prob < 75) {
    	return LATER; // 15%
    	} else if (prob < 98) {
    	return SOON; // 13%
    	} else {
    	return NEVER; // 2%
    	}
    	}
    	}
    
    	class AskMe implements SharedConstants {
    	static void answer(int result) {
    	switch (result) {
    	case NO:
    	System.out.println("No");
    	break;
    	case YES:
    	System.out.println("Yes");
    	break;
    	case MAYBE:
    	System.out.println("Maybe");
    	break;
    	case LATER:
    	System.out.println("Later");
    	break;
    	case SOON:
    	System.out.println("Soon");
    	break;
    	case NEVER:
    	System.out.println("Never");
    	break;
    	}
    	}
    
    	public static void main(String args[]) {
    	Question q = new Question();
    	answer(q.ask());
    	answer(q.ask());
    	answer(q.ask());
    	answer(q.ask());
    	}
    	}
    what is the output?
    
    Practice 4.4
    /* Inheritance in interface */
    
    	interface I1 {
    	void methodI1(); //public static by default
    	}
    
    	interface I2 extends I1 {
    	void methodI2(); //public static by default
    	}
    
    
    	class A1 {
    	public String methodA1() {
    	String strA1 = "I am in methodC1 of class A1";
    	return strA1;
    	}
    
    	public String toString() {
    	return "toString() method of class A1";
    	}
    	}
    
    	class B1 extends A1 implements I2 {
    	public void methodI1() {
    	System.out.println("I am in methodI1 of class B1");
    	}
    	public void methodI2() {
    	System.out.println("I am in methodI2 of class B1");
    	}
    	}
    
    	class C1 implements I2 {
    	public void methodI1() {
    	System.out.println("I am in methodI1 of class C1");
    	}
    
    	public void methodI2() {
    	System.out.println("I am in methodI2 of class C1");
    	}
    	}
    
    	/* Note that the class is declared as abstract as it does not satisfy the interface contract */
    	abstract class D1 implements I2 {
    	public void methodI1() {
    	}
    	//This class does not implement methodI2() hence declared abstract.
    	}
    
    	public class InterFaceEx {
    	public static void main(String[] args) {
    	I1 i1 = new B1();
    	i1.methodI1(); 			//OK as methodI1 is present in B1
    	// i1.methodI2(); Compilation error as methodI2 not present in I1
    	// Casting to convert the type of the reference from type I1 to type I2
    	((I2) i1).methodI2();
    	I2 i2 = new B1();
    	i2.methodI1(); //OK
    	i2.methodI2(); //OK
    	// Does not Compile as methodA1() not present in interface reference I1
    	// String var = i1.methodA1();
    	//Hence I1 requires a cast to invoke methodA1
    	String var2 = ((A1) i1).methodA1();
    	System.out.println("var2 : " + var2);
    	String var3 = ((B1) i1).methodA1();
    	System.out.println("var3 : " + var3);
    	String var4 = i1.toString();
    	System.out.println("var4 : " + var4);
    	String var5 = i2.toString();
    	System.out.println("var5 : " + var5);
    	I1 i3 = new C1();
    	String var6 = i3.toString();
    	System.out.println("var6 : " + var6);	//It prints the Object
    	// toString() method
    	Object o1 = new B1();
    	// o1.methodI1(); does not compile as Object class
    	//does not define methodI1()
    	//To solve the probelm we need to downcast o1 reference.
    	// We can do it in the following 4 ways
    	((I1) o1).methodI1(); //1
    	((I2) o1).methodI1(); //2
    	((B1) o1).methodI1(); //3
    	/* B1 does not have any relationship with C1 except they are "siblings".
    	Well, you can't cast siblings into one another. */
    	// ((C1)o1).methodI1(); Produces a ClassCastException
    	}
    	}
    what is the output?
    

    Assignment

    Q:
    Define two different classes namely, Student and Employee. These classes are derived from a base class Person. Define other two classes Staff and Faculty. Staff and Faculty classes are derived from Employee class. The Person class has name and age data and display method to display the name and age of a person. The Student class has data like rollNo and branch and display method to display name, age, rollNo and branch of the student. Stuff has ecNo and doj(date of joining) data and display method to display name, age, ecNo, doj of the stuff. Faculty has designation data (Assistant Professor, Associate Professor and Professor) and display method to display the name, age, ecNo, doj and designation of the Faculty. Staff has designation data (Technical and Clerical) and display method to display the name, age, ecNo, doj and designation of the Staff. Each class have their own constructor to initialize the value of each data field. Finally create MainDemoClass and create an object of each class. Print the values of all objects in the MainDemoClass.

    Q&A

    Q:
    What is an Interface?
    A:
    An interface is a description of a set of methods that conforming implementing classes must have.
    Note:
    • You can’t mark an interface as final.
    • Interface variables must be static.
    • An Interface cannot extend anything but another interfaces.
    Q:
    Can we instantiate an interface?
    A:
    You can’t instantiate an interface directly, but you can instantiate a class that implements an interface.
    Q:
    Can we create an object for an interface?
    A:
    Yes, it is always necessary to create an object implementation for an interface. Interfaces cannot be instantiated in their own right, so you must write a class that implements the interface and fulfill all the methods defined in it.
    Q:
    Do interfaces have member variables?
    A:
    Interfaces may have member variables, but these are implicitly public, static, and final- in other words, interfaces can declare only constants, not instance variables that are available to all implementations and may be used as key references for method arguments for example.
    Q:
    What modifiers are allowed for methods in an Interface?
    A:
    Only public and abstract modifiers are allowed for methods in interfaces.
    Q:
    When should I use abstract classes and when should I use interfaces?
    A:
    Use Interfaces when…
    • You see that something in your design will change frequently.
    • If various implementations only share method signatures then it is better to use Interfaces.
    • you need some classes to use some methods which you don't want to be included in the class, then you go for the interface, which makes it easy to just implement and make use of the methods defined in the interface.
    Use Abstract Class when…
    • If various implementations are of the same kind and use common behavior or status then abstract class is better to use.
    • When you want to provide a generalized form of abstraction and leave the implementation task with the inheriting subclass.
    • Abstract classes are an excellent way to create planned inheritance hierarchies. They're also a good choice for nonleaf classes in class hierarchies.
    Q:
    When you declare a method as abstract, can other nonabstract methods access it?
    A:
    Yes, other nonabstract methods can access a method that you declare as abstract.
    Q:
    Can there be an abstract class with no abstract methods in it?
    A:
    Yes, there can be an abstract class without abstract methods.
    Q:
    Can I import same package/class twice? Will the JVM load the package twice at runtime?
    A:
    One can import the same package or same class multiple times. Neither compiler nor JVM complains wil complain about it. And the JVM will internally load the class only once no matter how many times you import the same class.
    Q:
    Do we need to import java.lang.package ?
    A:
    No, It is loaded by default by the JVM.
    Q:
    Name few classes of package java.lang
    A:
    [Throwable, Error, Object, Exception, IllegalArgumentException]
    Q:
    What Restrictions Are Placed On The Location Of A Package Statement Within A Source Code File?
    A:
    A package statement must appear as the first line in a source code file (excluding blank lines and comments).
    Q:
    Explain the usage of Java packages.
    A:
    A Java package is a naming context for classes and interfaces. A package is used to create a separate name space for groups of classes and interfaces. Packages are also used to organize related classes and interfaces into a single API unit and to control accessibility to these classes and interfaces.
    Q:
    Why do we need to use package in Java?
    A:
    Package provides encapsulation in Java program. Default access modifier for any variable or class is package-private i.e. they are only visible into package, on which they are declared. By using package you Encapsulate whole functionality which allows you to change the functionality, include new functionality or just change the implementation without breaking whole application. Though package is not the highest degree of Encapsulation in Java which is achieved using 'private' keyword, it is still the second best option and a must in order to encapsulate whole functionality rather than just a class.
    Q:
    How to create a package in Java?
    A:
    If you are using IDE like 'Eclipse' for developing your Java program then you don't need to do anything. Just click on new-->package and Eclipse will ask you name of the package, put name of the package and you are good to go. Now if you want to create Java class on that package, just select the package in package explorer and create new-->Java Class. If you are not using any IDE than you manually need to create directories corresponding to package in Java.