Sei sulla pagina 1di 19

Interfaces and Packages

The concept of inheritance is a useful feature for code reuse. Consider the following example of hybrid inheritance
as shown below. Mango and Banana are both inherited from Fruit class. MixedFruit is inherited from Mango
and Banana.
Fruit

Mango

Banana

Mixed Fruit

Hybrid Inheritance.
This type of inheritance is commonly known as diamond inheritance. Many legitimate designs require such
type of inheritance. But, there is a technical problem because of inheritance. For example, if the makeJuice()
method is defined in both the base classes Banana and Mango with the same signature, the derived class
MixedFruit has a conflict because of two different implementations of inherited makeJuice(). Because of
two methods with the same signature being inherited from Banana and Mango for makeJuice() method, an
object of MixedFruit will have the problem while invoking makeJuice() method. To overcome such difficulty,
the interface abstraction is used.
The technical difficulty of diamond inheritance discussed above restricts Java from multiple inheritance. Java
designers decided to keep the language simple and clear. Hence, full-fledged multiple inheritance is not allowed
in Java.
Inheritance represents a hierarchical relationship between classes. It is very important to follow the IS A
relationship for inheritance. For example, the Apple class can be inherited from the Fruit class and not from the
Vegetable class. Sometimes, it may be necessary to dictate common behavior among objects from diverse
classes where IS A relationship does not exist. For example, behaviors such as steering(), accelerate() and
break() may be defined in a separate class Drive. These behaviors may be used in the class Vehicle. The
classes such as Car, Jeep, Van, Lorry, and Bus may be inherited from both Vehicle and Drive. Such
organization results in multiple inheritance. The classes Car, Jeep, etc., have an IS A relationship with the base
class Vehicle whereas they do not possess an IS A relationship with the base class Drive. Java does not support
multiple inheritance. But, it provides an alternative abstraction known as interface. Interface is a reference data
type that encapsulates behaviors. It supports multiple inheritance, common behavior, and may be inherited from
diverse base classes where the IS A relationship does not exist. For example, an interface IDrive may be defined
with necessary behaviors. An interface IDriveVehicle may be derived from both the class Vehicle and the
interface IDrive. Each class Car, Jeep, and so on can be inherited from IDriveVehicle. Thus, multiple
inheritance is supported by means of interfaces in Java.
Interfaces are specific reference data type like and they share some commonalities with classes. Like for
classes it is possible to define references of interface type, assign compatible instances to them and invoke
methods. A class encapsulates fields and methods. The methods in a class make use of the fields in the same class
to exhibit a behavior. The methods are also provided with implementation. Interfaces define only behavioral
characteristics in the form of methods without defining the fields in it. The methods in an interface can not have
implementation. Only the signature of each method is given and the method body is not defined. A semicolon is
placed at the end of the method header meaning that no implementation is provided for the method. The basic
difference between an interface and a class can be understood from the following example:
Program 1
// Sample.java: A program to illustrate an interface.
interface ISample {
// An interface declaration.
void mnotify();
// Implementation is not defined.

double cubic(double a);


}
class Sample implements ISample { // Interface implementation
public void mnotify() {
System.out.println("\nNotify in Sample");
}
public double cubic(double x) {
return x*x*x;
}
public static void main(String[]args) {
Sample s = new Sample();
s.mnotify();
System.out.printf("Cubic value: %.3f", s.cubic(10.5));
ISample s1 = (ISample)s; // Casting is a good practice
s1.mnotify();
System.out.printf("Cubic value: %.6f", s1.cubic(10.5));
}
}

OUTPUT
Notify in Sample
Cubic value: 1157.625
Notify in Sample
Cubic value: 1157.625

The syntax for declaring an interface is similar to the declaration of a class. But, the method does not have an
implementation and hence each method declaration ends with a semicolon. The keyword interface is used
instead of the keyword class in a class declaration. Since the implementation of the methods is not given, it is
not possible to make use of an interface as such. An interface cannot be instantiated. Hence, a class is declared to
inherit the interface and all the methods of the interface are implemented in it. This derived class may have main()
method or another class with main() may be written to make use of the interface. Thus inheriting an interface is
mandatory for programs using interfaces. Even though an interface is not instantiated, its reference can be assigned
the reference of its derived class as given in the above example. It is always a good practice to cast the object
reference to the interface type. Thus, to write a program using an interface, the following steps are followed:
1. Declare the interface with methods reflecting the behaviors. No implementation should be provided.
2. (a). Declare a class that is derived or inherited from the interface.
(b). Provide implementations for all the methods of the interface in this derived class.
(c). Provide the main() method in the derived class or use this derived class in
some other
class provided with main().
Declaration and Implementations of Interfaces
Interface programs involve:

Interface declarations

Interface implementations
The syntax of interface declaration is given below:
accessModifier interface InterfaceName {
member declarations;
}

Only the methods are considered as members of an interface to start with. Hence, member declarations in the
given syntax include only method declarations without implementation details.
The syntax of interface implementation involves inheritance. Interfaces may be implemented by using classes
or structs. A class or struct that implements an interface inherits from the interface. The syntax of interface
implementation using a class is given below:
accessModifier class ClassName implements InterfaceName {

method implementations;
member declarations of the class;
public static void main(String[]args)

{}

where
class and implements
ClassName
InterfaceName

are keywords.
represents the name of the class.
represents the name of the interface.

The accessModifier may be one of the following keywords:

public
private
protected

The members of an interface are:

methods

properties
It is important to know that interfaces cannot contain:

constants

fields (private data members)

constructors and destructors

non public members

static members
All the members of an interface are public by definition. The compiler generates error if any other modifier is
specified. The interfaces follow the naming convention beginning with the uppercase letter I.
It can be observed that a class is a mix of design and implementation whereas an interface is an expression of
pure design. Interface can be thought of as a collection of contracts that provides a useful way to partition
functionality. The overall architects of the software system could design the interfaces and the developers within
the team would construct objects, which inherit from the interfaces. Thus, interface programming is a powerful
concept that helps in designing the software with behavior decomposition.
The following example will help the reader to understand the idea of interface as a collection of contracts.
Each method of an interface can be treated as a contract that guarantees a specific behavior to users. For example,
steering is a contract between the driver (user) and the car (object). A car may have many contracts such as brake,
accelerator, horn, etc. The driver must know the contracts involved in driving a car. Thus, there are a number of
contracts (executable tasks) between a user and an object. But, the internal mechanism of steering, brake or horn
in each vehicle may vary and the user is not interested in the implementation details. The user must know how to
use each and every contract provided to an object.
The interaction between the car and driver for turning the car is initiated by operating the steering. Likewise,
the accelerator and brake can also be operated to initiate the action of increasing the speed of the car and reducing
the speed of the car, respectively. To drive the car, it is essential to operate all the required contracts in a proper
sequence. Likewise, the interaction between a user and a contract of an object is initiated by invoking a method.
The proper sequence of interaction leads to the execution of the desired task entrusted to an object.
A class can implement the methods of an interface in any way that the developer of the class chooses. An
interface thus has many more possible implementations than a class has. (Refer to Program 2).
Interfaces are very much useful in developing applications where visual components such as buttons, menus,
text boxes, etc. are involved. There are many ways to interact with application programs. An end user may feed
input from the keyboard or from any other input device. Windows environment is popular because of easier
interaction by means of graphical user interface (GUI). GUI components are also known as visual components.
GUI facility helps the end user to interact with the program easily and quickly. Clicking the menus and pressing
the buttons carry out many actions. For example, the end user selects a menu by pressing a button to execute the
program to exhibit the desired behavior. There are three entities involved while programming with GUI
components. The end user, clients code written for the visual component (such as button) and the main application
program that uses the visual component are the three entities. The clients code of the interacting component is
the contract between the interacting component and the application program. The method (clients code) for the
visual component may be entirely different from that of the application program. The clients code involves system
level services for visual components. Such services may be provided by library of classes. When an end user
initiates an action by operating the visual component, the clients code communicates with the application
program. Thus, there are two disparate pieces of code, viz., the clients code and the application program. The

situation is handled easily by using interfaces. Such codes are known as event handlers that are discussed
later in this chapter. Interfaces are part of Java language. Java compiler ensures that when a class is initiated from
an interface to implement the methods of the interface, the class does what is required. Before using interfaces, it
is necessary to know the difference between a class and an interface. The differences and comparisons are listed
below.
Comparison of a class and an interface.
Sl.No.
1.
2.
3.
4.

Class
It encapsulates fields and methods.
The methods are implemented.
It allows single inheritance.
A class is inherited if there exists IS
A relationship.

Interface
It encapsulates contracts.
Methods are not implemented.
It allows multiple inheritance.
An interface is inherited to implement the
methods. Even though there is no IS A
relationship, the class is derived to execute
common behaviors

An interface is the same as a class but contains only abstract members. A class with abstract members is known
as abstract class. But, an abstract class is declared with the keyword abstract in the abstract class header. The
interface and abstract class are compared.
Comparison of abstract class and interface
Sl.No.
1.
2.

Abstract class
An abstract class is declared with the
keyword abstract.
It can contain both abstract methods and
non-abstract methods.

Interface
An interface uses the keyword interface.
All the methods in an interface are treated as
abstract methods even though there is no abstract
keyword in the methods.

The difference between an abstract class and an interface does not only rely on the different syntax but on
different meaning. Abstract classes define a common base type whose instances can only be obtained through
specialization of the type (i.e. by implementing non abstract derived classes). Interfaces define only a set of related
operations that are expected to be implemented by some instances. When the design requires the presence of a
common base class, an abstract class must be defined. When the design requires the availability of a set of
operations, notwithstanding the specific type, an interface must be defined.
Interfaces are reference data types supporting:

Multiple implementations (a class can implement more than one interface)

Interaction between two disparate codes (event handling) in GUI environment

Inheritance from diverse concepts where IS A relationship does not hold good

Functional decomposition

Pure design concept


It is also possible to implement each interface by a separate class resulting in hierarchical inheritance.
Polymorphism in Interfaces
Since inheritance is involved in the implementation of an interface, polymorphic behaviors are also achieved in
interfaces. It is possible to have two or more classes that implement the same interface with different
implementations. Through the instances of each class, polymorphic behaviors are achieved for the given interface.
This is illustrated in the following program:
Program 2
/* MyVehicle.java: A program to illustrate hierarchical inheritance of an
interface. */
interface IVehicle {
void steering();
void brake();
}
class Bus implements IVehicle {
public void steering() {

System.out.println("Steering is used to turn the Bus.");


}
public void brake() {
System.out.println("Brake is applied to reduce the speed " +
"of the Bus.");
}
}
class Lorry implements IVehicle {
public void steering() {
System.out.println("Steering is used
}
public void brake() {
System.out.println("Brake is applied
"Lorry. ");
}
}
class Car implements IVehicle {
public void steering() {
System.out.println("Steering is used
}
public void brake() {
System.out.println("Brake is applied
" Car.");
}
}
class MyVehicle {
public static void main(String[]args) {
IVehicle b = new Bus();
b.steering();
b.brake();
IVehicle v = new Lorry();
v.steering();
v.brake();
IVehicle c = new Car();
c.steering();
c.brake();
}
}

to turn the Lorry.");

to reduce the speed of the" +

to turn the Car.");

to reduce the speed of the +

OUTPUT
Steering
Brake is
Steering
Brake is
Steering
Brake is

is used
applied
is used
applied
is used
applied

to
to
to
to
to
to

turn the Bus.


reduce the speed of the Bus.
turn the Lorry.
reduce the speed of the Lorry.
turn the Car.
reduce the speed of the Car.

Multilevel Inheritance
It is also possible to declare an interface IName2 derived from another interface IName1. The interface IName1
must also be implemented in a class that is derived from IName2. Then only the interfaces can be made use of in
the program.
Program 3
// Place.java: A program to illustrate multilevel inheritance.
interface IContinent {

void contDisplay();
}
interface ICountry extends IContinent {
void showCountry();
}
interface IState extends ICountry {
void displayState();
}
class Place implements IState {
public void contDisplay() {
System.out.println("Continent: ASIA");
}
public void showCountry() {
System.out.println("Country: INDIA");
}
public void displayState() {
System.out.println("State: TAMILNADU");
}
void location() {
System.out.println("Place: TIRUNELVELI");
}
public static void main(String[]args) {
Place p = new Place();
IContinent cont = p;
cont.contDisplay();
ICountry country = p;
country.showCountry();
IState state = p;
state.displayState();
p.location();
}
}

OUTPUT
Continent: ASIA
Country: INDIA
State: TAMILNADU
Place: TIRUNELVELI

Observe that the class Place implements the base interface IState. As IState is inherited from the interface
ICountry and ICountry is inherited from the interface IContinent, the class Place also implements the
ICountry and IContinent interfaces even though they are not explicitly included after the colon in the
declaration of class Place. The methods of all the interfaces implemented must be defined without fail in the case
of multilevel inheritance.
Multiple Inheritance
An interface can inherit from one or more other interfaces. An interface inherits all members of its base interfaces.
A class that implements an interface also implicitly implements all of the interfaces base interfaces. The syntax
for multiple inheritance of an interface varies only in the interface implementation as given below:
accessModifier class ClassName extends BaseClassName
implements IntefaceList {
method implementations;
member declarations of the class;

public static main()

{}

where
InterfaceList represents the list of interface names separated by commas.

The interfaces declared in InterfaceList are known as explicit base interfaces. In the case of multilevel
inheritance, the base interfaces of an interface are the explicit base interfaces and their base interfaces. The
following points must be kept in mind while using interface inheritance.
1. It is an error to inherit directly or indirectly from an interface itself.
2. The explicit base interfaces of an interface must be at least as accessible as the interface.
It is important to remember that while it is allowed only one class as base class, the InterfaceList can list
multiple interfaces.
Program 4
// House.java: A program to illustrate multiple inheritance.
interface IKitchen {
void store();
}
interface IDrawingHall {
void showcase();
}
interface IBedRoom {
void acProvision();
}
class House implements IKitchen, IDrawingHall, IBedRoom {
public void store() {
System.out.println("Place the groceries on the shelf.");
}
public void showcase() {
System.out.println("Keep the prizes, memento and"
+ " medals in the showcase.");
}
public void acProvision() {
System.out.println("Provide an Airconditioner in the bed room.");
}
public static void main(String[]args) {
House h = new House();
h.store();
h.showcase();
h.acProvision();
IKitchen k = new House();
k.store();
IDrawingHall d = h;
d.showcase();
IBedRoom b = h;
b.acProvision();
}
}

OUTPUT
Place the groceries on the shelf.
Keep the prizes, memento and medals in the showcase.
Provide an Airconditioner in the bed room.
Place the groceries on the shelf.
Keep the prizes, memento and medals in the showcase.

Provide an Airconditioner in the bed room.

The program contains the interfaces IKitchen, IDrawingHall and IBedRoom. The class House inherits these
three interfaces.
Program 5
/* Stay.java: A program to illustrate multiple inheritance where the
baselist contains a base class and interfaces. */
import java.util.Scanner;
interface Lift {
void move();
void display();
}
interface Room {
void roomType();
void display();
}
class Inn {
public void display() {
System.out.println("\nThe hotel Barani is a Three Star type.");
}
}
class Stay extends Inn implements Lift, Room {
// extends must appear first
int duration;
void rwValue() {
Scanner sc = new Scanner(System.in);
System.out.println("\nEnter the duration of stay( No. of days):");
duration = sc.nextInt();
System.out.printf("\nDuration of stay: %d days.", duration);
}
public void move() {
System.out.println("\nGo to fifth floor.");
}
public void roomType() {
System.out.println("\nRoom type is AC Doubles.");
}
public static void main(String[]args) {
Stay s = new Stay();
s.rwValue();
Lift l = s;
l.display();
l.move();
Room r = s;
r.roomType();
r.display();
}
}

INPUT/OUTPUT
Enter the duration of stay( No. of days):
7
Duration of stay: 7 days.
The hotel Barani is a Three Star type.
Go to fifth floor.
Room type is AC Doubles.
The hotel Barani is a Three Star type.

Explicit Interface Member Implementations


Hybrid inheritance is supported by interfaces. Java provides a mechanism to overcome the difficulty in hybrid
inheritance. Observe the following program:
Program 6
/* MixedFruit.java: A program to illustrate diamond inheritance of interface. */
interface IFruit {

void display();
}
interface IBanana extends IFruit {
void makeJuice();
}
interface IMango extends IFruit {
void makeJuice();
}
class MixedFruit implements IBanana,IMango {
public void display() {
System.out.println("Fruits are natural food.");
}
public void makeJuice() {
System.out.println("Fruit juice is sweet.");
}
public static void main(String[]args) {
MixedFruit mf = new MixedFruit();
IBanana b = mf;
b.makeJuice();
IMango m = mf;
m.makeJuice();
IFruit f = mf;
f.display();
}
}

OUTPUT
Fruit juice is sweet.
Fruit juice is sweet.
Fruits are natural food.

The method makeJuice() provides a common implementation for both interfaces IBanana and IMango in
the interface implementation. If two different implementations are required for these two interfaces, the above
program cannot solve the problem. This difficulty is overcome by using fully qualified name of the interface
member. An interface member may be referred to by its fully qualified name consisting of the name of the interface
followed by the name of the member separated by a dot. For example, IMango.makeJuice() is the fully
qualified name of the method makeJuice() of the interface IMango. The mechanism of referring to a member
of an interface by its fully qualified name in the interface implementation results in explicit interface member
implementation.
Program 7
/* MixedFruit.java: A program to provide separate implementation for the method
makeJuice() in Program 6. */
interface IFruit {
void display();
}
interface IBanana extends IFruit {
public void makeJuice(IBanana b);
}
interface IMango extends IFruit {
public void makeJuice(IMango m);
}
class MixedFruit implements IBanana,IMango {
public void display() {
System.out.println("Fruits are natural food.");
}

public void makeJuice(IBanana b) {


System.out.println("Banana juice is sweet.");
}
public void makeJuice(IMango m) {
System.out.println("Mango juice is much sweeter.");
}
public static void main(String[]args) {
MixedFruit mf = new MixedFruit();
IBanana b = mf;
b.makeJuice(b);
IMango m = mf;
m.makeJuice(m);
IFruit f = mf;
f.display();
}
}

OUTPUT
Banana juice is sweet.
Mango juice is much sweeter.
Fruits are natural food.

Validating Interfaces
An interface is derived by a class to provide implementation. Since an interface cannot be instantiated, the class
that inherits it is instantiated first. According to the inheritance characteristics the reference to the derived class
can be assigned to its base interface. When more number of classes is involved in multiple implementations of an
interface, it is necessary to check whether a reference to an object may be assigned to the reference of an interface
or not. Such validation is performed at runtime before assignment. This process of checking the reference as a
specific type is known as validating interfaces.
The operator instanceof is used to check whether an object is of the given type. For example, the expression
loan instanceof IHouse returns true, if the object loan belongs to the type IHouse; otherwise, it returns
false. The syntax of using the instanceof operator is:
identifier instanceof type

This operator instanceof is helpful to check whether an object supports a specific interface or not.
Program 8
// Loan.java: A program to illustrate instanceof operator.
interface IHouse {
void construct();
public double loanInterest(IHouse h);
}
interface IEducation {
void result();
public double loanInterest(IEducation e);
}
interface IVehicle {
void drive();
public double loanInterest(IVehicle v);
}
class Loan implements IHouse, IEducation, IVehicle {
public void construct() {
System.out.println ("House construction is going on.");
}
public double loanInterest(IHouse h) {
System.out.println ("House Loan : 11 %");

return 500000 * 0.11;


}
public void result() {
System.out.println ("\nCongrats!! You have secured first rank.");
}
public double loanInterest(IEducation e) {
System.out.println ("Education Loan : 18 %");
return 100000 * 0.18;
}
public void drive() {
System.out.println("\nDrive the car after getting driving " +
"license.");
}
public double loanInterest(IVehicle v) {
System.out.println ("Vehicle Loan : 14 %");
return 200000 * 0.14;
}
public static void main(String[]args) {
Loan loan = new Loan();
IHouse h = (IHouse)loan ;
IEducation e =(IEducation) loan;
IVehicle v = (IVehicle)loan;
if (h instanceof IHouse) {
h.construct();
System.out.printf("House Loan Interest: Rs.%.2f",
h.loanInterest(h));
}
if (e instanceof IEducation) {
e.result();
System.out.printf("Education Loan Interest: Rs.%.2f",
e.loanInterest(e));
}
if (v instanceof IVehicle) {
v.drive();
System.out.printf("Vehicle Loan Interest: Rs.%.2f",
v.loanInterest(v));
}
}
}

OUTPUT
House construction is going on.
House Loan : 11 %
House Loan Interest: Rs.55000.00
Congrats!! You have secured first rank.
Education Loan : 18 %
Education Loan Interest: Rs.18000.00
Drive the car after getting driving license.
Vehicle Loan : 14 %
Vehicle Loan Interest: Rs.28000.00

Problems in Interfaces Because of Inheritance


The inheritance involved in the interface implementation may result in missing implementations of methods in
some situations. The following example illustrates one such situation:
Program 9

/* Sample.java: A program to illustrate an interface that is implemented by a


class, which inherits another base class and this interface, and assumes that both
the interface and the base class have the same method. */
interface ILaserjet {
public void printGraph();
}
class Inkjet {
public void printGraph() {
System.out.println("Graphics resolution: Fair");
}
}
class Printer extends Inkjet implements ILaserjet {
public void display() {
System.out.println("Printers: INKJET and LASERJET");
}
}
class Sample {
public static void main(String[]args) {
Printer p = new Printer();
p.printGraph();
p.display();
Inkjet j1 = new Inkjet();
j1.printGraph();
j1 = p ;
j1.printGraph();
Inkjet j2 =(Inkjet)p ;
if (j2 != null) {
System.out.println("Inkjet printer");
j2.printGraph();
}
else
System.out.println("Printer:NOT INKJET");
ILaserjet j3 = (ILaserjet)p ;
if (j3 != null) {
System.out.println("Laserjet printer");
j3.printGraph();
}
else
System.out.println("Printer:NOT LASERJET");
}
}

OUTPUT
Graphics resolution:
Printers: INKJET and
Graphics resolution:
Graphics resolution:
Inkjet printer
Graphics resolution:
Laserjet printer
Graphics resolution:

Fair
LASERJET
Fair
Fair
Fair
Fair

Even though the implementation of the method printGraph() is not provided in the class Printer, there is no
sign of this missing implementation. The method printGraph() is inherited from the base class Inkjet and
hence this is not notified. The actual implementation of printGraph() of ILaserjet may be different from

what is provided in Inkjet. If the implementation is provided in the class Printer, the output will be different
for the same program. The reader can provide an implementation to verify the output.

Packages: Putting classes Together


A class library is a collection of classes that supports the development of programs. A compiler is provided with
a class library. Each class in a class library provides a separate functionality. The programmers always use
methods in a class library to develop their programs. Strictly speaking, they are not in the language definition. For
example, String is a class and it is not an inherent part of Java language. It is part of the Java Standard Class
Library that is available in any Java Development Environment. Sun Microsystems developed the Java Standard
Class Library and is supplied with the Java Development Kit such as J2SE 1.5.
Java standard class libraries are organized using packages. A folder (directory) on a file system contains
physical grouping of many files. Similarly, a package can be viewed as a container for classes. The logically
related classes and/or interfaces are grouped together and these classes may be put into a package. Such grouping
under a package avoids the risk of name collisions. Choosing a unique name to every class is difficult because
many programmers are involved in the software development. The Java Standard Class Library also provides a
number of useful types such as Double, Single, ArrayList, Event, System, etc. It is not possible to remember all
the names available in the class library. Chance of using the existing name in a program is quite possible. Such
name clashes are prevented by creating package. Two classes with the same name can coexist without any conflict,
if each class is declared in a separate package. It is very important to understand that a package is not a type.
Packages are used to organize the different types to avoid name clashes. Packages have no access restrictions.
They are always publicly accessible. On the contrary, interface and class definitions inside a package may be
subject to access restrictions.
The advantages of using packages are listed below:
1. It avoids name collisions.
2. It enables reusing of classes.
3. It helps in easier distribution of software.
4. It protects the classes so that access by external classes is not possible.
Java Foundation Packages
Java provides a large number of classes groped into different packages based on their functionality. The six
foundation Java packages are:

java.lang

Contains classes for primitive types, strings, math functions, threads, and exception

java.util

Contains classes such as vectors, hash tables, date, etc.

java.io

Contains Stream classes for I/O

java.awt

Contains classes for implementing GUI windows, buttons, menus, etc.

java.net

Classes for networking

java.applet

Contains classes for creating and implementing applets


Package Naming Conventions
Packages are organised in a hierarchical structure. For example, a package named java contains the package
awt, which in turn contains various classes required for implementing GUIs (graphical user interfaces) as
illustrated. It is also possible to nest packages within each other. A package may contain other packages similar
to a folder containing other folders. For example, java.util.Scanner represents that Scanner is a class in the
package lang and that lang is a package in the package java. By convention, package names are all in lowercase.

java
java Package containing
lang, awt,.. packages;
Can also contain classes.

lang
awt
Graphics
Font
Image

awt Package containing


classes
Classes containing
methods

Package java and its sub-packages illustrates hierarchical organization


Java designers recommend Java programmers to follow domain name in reverse order as a package prefix.
Domain names are unique in the Internet. To create a package called GridApplications on a host machine with the
Internet domain name as gridlab.com, the complete package name may be com.gridlab.GridApplications.

Directory structure and package structure mapping


It is important to have one-to-one mapping between the package name and the file system directory structure.
For the package named com.gridlab.GridApplications, the directory structure is created as shown next.
The package is actually a directory that contains the bytecodes of the classes. The package
com.gridlab.gridApplications is mapped to a directory structure in the file system as shown in Figure 9.3.
The com directory can be created in any directory as you like. Suppose com directory is created under the
D:\JavaPrg. To access the classes available in the created package, the Java environment must know where the
package is in the file system. For that purpose, the environment variable classpath must be modified so that it
points to the directory where the package resides. The classpath can be set by the command:
classpath = .; D:\JavaPrg;

The period (.) indicating the current directory is always in the classpath. The directory D:\JavaPrg is in
the classpath for accessing classes in package com.gridlab.gridApplications. Any number of
directories may be added to the classpath. The classpath variable is set in Windows and Unix as given next.
For Windows 95 and Windows 98, edit autoexec.bat using a text editor such as notepad. For Windows
2000/Windows NT, go to Start button and choose control panel. Select System icon and modify classpath in
the environment. For Windows XP, select My Computer on desktop and select Properties, which displays system
properties. Select Advanced tab in it and click Environment Variables. Edit CLASSPATH and click OK. For UNIX,
use the setenv command to set classpath such as setenv classpath .:/home/JavaPrg. If the command
is inserted into the .cshrc file, the classpath variable will be automatically set when you log on.
Creating Packages
Java supports a keyword called package for creating user-defined packages. The package statement must be the
first statement in a Java source file (except comments and white spaces) followed by one or more classes.
package myPackage;
public class ClassA {
// class body
}
class ClassB {
// class body
}

Package name is myPackage and classes are considered as part of this package; The code is saved in a file
called ClassA.java and located in a directory called myPackage.
Each class in Java belongs to a package. When the class is compiled, the class is added to the package. All the
classes so far used were placed in a default package, the current directory, when compiled. If you want to place a
class in a particular package, the following statement has to be added. It should be the first non-commented and
non-blank statement.
package pkgName;

You may store the .java file in the package directory and then compile it using javac command. If the
.java file is not in the package directory, you can use the command:
javac SemanticDiscovery.java -d d:\JavaPrg\com\gridlab\gridApplications

with d option to specify where to store the .class file. Now the SemanticDiscovery.class file is stored in
the directory d:\JavaPrg\com\gridlab\gridApplications. Once the compiled class is stored into the class path, it
can be easily accessed by importing it. Java provides a specific statement to perform this task which requires the
full name of the class to be specified. The full name comprises the class name preceded by the package name and
a dot. In this case we would have: com.gridlab.gridApplications.SemanticDiscovery.
Creating Sub Packages
Classes in one or more source files can be part of the same packages. As packages in Java are organised
hierarchically, sub-packages can be created as follows:
package myPackage.Math
package myPackage.secondPackage.thirdPackage

In this case, we need to store thirdPackage in a subdirectory named myPackage\secondPackage; and


secondPackage and the Math class in a subdirectory myPackage.
Accessing Classes from Packages
There are two ways of accessing the classes stored in packages:
Using fully qualified class names
java.lang.Math.sqrt(x);

Importing the packages they belong to and using the class names directly
import java.lang.Math
Math.sqrt(x);

Selected or all classes in packages can be imported:


import package.ClassName;
import package.*;
import static package.ClassName.*;

The Java compiler automatically imports the java.lang.* package in all programs. This package as
previously seen contains the definition of all the fundamental classes and interfaces of the Java programming
language such as Object, String, System, etc.. In program files, package statement(s) must appear first. The
import static is useful when a particular class has a lot of static methods, to use those methods directly with their
method name instead of the fully qualified name. For example, suppose Class A has a static method showMe.
Accessing the method without static import would be as follows:
ClassA.showMe();

By import the static methods use


import static ClassA.*;

The way of accessing the code becomes the following:


showMe();

The ClassA is not necessary any more to access the showMe method.
Accessing a Package
Classes in packages can be accessed using a fully qualified name or using a short-cut as long as we import a
corresponding package. The general form of importing a package is:
import package1[.package2][].classname

Example:
import myPackage.ClassA;

import myPackage.secondPackage

All classes/packages from higher-level package can be imported as follows:


import myPackage.*;

Using a Package: An Example


To illustrate creation and usage of package, let us assume that that the user is currently working in a directory
named abc. Our aim is to create a new package called myPackage and define two classes within that package.
We then import a specific class called ClassA from that package with the aim of accessing it within a program
placed in the current directory. Steps for achieving this are illustrated below:

Let us store the code listed below in a file named ClassA.java in subdirectory named myPackage within
the current directory (say abc).
/* ClassA.java: A program illustrating the creation of a package myPackage
containing two classes. */
package myPackage;
public class ClassA {
// class body
public void display() {
System.out.println("Hello, I am ClassA");
}
}
class ClassB {
// class body
}

Within the current directory (abc) store the following code in a file named ClassX.java
/* ClassX.java: A program illustrating the usage of previously created
package myPackage. */
import myPackage.ClassA;
public class ClassX {
public static void main(String args[]) {
ClassA objA = new ClassA();
objA.display();
}
}

OUTPUT
Hello, I am ClassA

Compiling and Running


When the program ClassX.java is compiled, the compiler compiles it and produces .class file and places it in
the current directory. If .class file of ClassA in the subdirectory myPackage is not found, it compiles ClassA.java
program also. It should be noted that it does not include the code of ClassA into ClassX. When the program
ClassX is run, java loader looks for ClassA.class file in a package called myPackage and loads it.
It is important to remember that classes defined in the same package are automatically visible without need to
specify any import statement. This also explains why all the previous code samples involving more than one class
defined in separate files run without any error: they were all defined in the current directory as classes of the same
package are.
Further extending the program
Extend the above program by creating a new package called secondPackage and write a main program that
accesses packages stored in its subdirectories. A program below illustrates the same:

Let us store the code listing below in a file named ClassC.java in subdirectory named second package
within the current directory (say abc).
// ClassC.java: A program that creates a new package secondPackage.
package secondPackage;

public class ClassC {


// class body
public void display() {
System.out.println("Hello, I am ClassC");
}
}

Within the current directory (abc) store the following code in a file named ClassY.java
/* ClassY.java: A program which illustrates the use of two previously
created packages myPackage and secondPackage. */
import myPackage.ClassA;
import secondPackage.ClassC;
public class ClassY {
public static void main(String args[]) {
ClassA objA = new ClassA();
ClassC objC = new ClassC();
objA.display();
objC.display();
}
}

OUTPUT
Hello, I am ClassA
Hello, I am ClassC

Adding a Class to an Existing Package


Let us consider an existing package called pack1 that contains a class called Teacher:
package pack1;
public class Teacher {
// class body
}

This class is stored in Teacher.java file within a directory called pack1. Process of adding a new public class
called Student to this package is illustrated below:

Define the public class Student and place the package statement before the class definition as follows:
package pack1;
public class Student {
// class body
}

Store this in Student.java file under the directory pack1. When the Student.java file is compiled, the
.class file will be created and stored in the directory pack1. Now, the package pack1 will contain both
the classes Teacher and Student.

Packages and Name Clashing


When packages are developed by different organizations, it is possible that multiple packages will have classes
with the same name as shown. When such classes are accessed directly, it can lead to clashing, which can be
avoided by using fully qualified names as illustrated below.
package pack1;

package pack2;

class Teacher

class Student

class Student

class Courses

Multiple packages having some classes with same names


We can import and use these packages as follows:

import pack1.*;
import pack2.*;

If we try to make use of Student class directly as indicate below:


Student student1;

The compiler generates errors due to name clashing since it is confused about which version of the Student class
this statement is referring. Such name classing is resolved by accessing classes with the same name in multiple
packages by their fully qualified name as illustrated below:
import pack1.*;
import pack2.*;
pack1.Student student1;
pack2.Student student2;
Teacher teacher1;
Courses course1;

Extending a Class from Package


A new class called Professor can be created by extending the Teacher class defined in package pack1 as
follows:
import pack1.Teacher;
public class Professor extends Teacher {
// body of Professor class
// It is able to inherit public and protected members,
// but not private or default members of Teacher class.
}

Creating Java Archives


While developing software using Java, it is hard to manage classes that distributed in different packages and
physically located in different directories in the file system, Java provides a way to pack multiple classes and
packages into a single library file called a jar (Java ARchive) file. Java provides a command to create a jar file,
for example:
Jar cf Foo.jar com/javabook/*.classes

Whereas the c option ask for creating jar file and f option ask for specifying a jar file name such as Foo.jar. The
command creates a Foo.jar file that contains all the classes from the package com.javabook.
Jar file can be executed directly as an application given that a special manifest file in METAINF/MANIFEST.MF which describes the main entry class for the whole application. For example, there is a Jar
file called exec.jar which has a manifest file that makes this jar file executable and the manifest file should at least
defines an entry as follows:
Main-Class: myPrograms.MyClass

It tells the Java runtime that the myProgram.MyClass is the entry class for that particular jar file. The following
command creates the exec.jar file with a given manifest file and classes.
jar cmf myManifestFile exec.jar *.class

whereas the m option ask for specifying a manifest file for the jar. To execute this Jar file, simply use the Java
command by providing a command line jar with the jar file:
Java jar exec.jar

Another typical usage of Jar file is to make them as libraries that can be referenced by other applications. In this
case, there is no need to provide a manifest file containing main class entry, as those Jar files are libraries and will
never be executed directly.
Set Java Classpath
In order to reference the Java classes or objects within a Jar file, a specific operation has been performed to let the
JVM know exactly which of those Jar files have been used. A term called Classpath is normally refereed to this
situation. A classpath defines location information about all the classes or jars that a particular application needs
to use. Without providing classpath information, applications may not be able to perform correctly as classes that
are loaded dynamically during runtime not compilation time will be missing if they are in other places or not in
the standard classpath. There are two ways to solve the classpath issue. The first approach is to define a
environment variable CLASSPATH, and set location information of all the related classes or jars files. For
example, in a Windows command line, it looks like the following:

set CLASSPATH= C:\java\MyClasses;C:\java\lib\myJar.jar;

Whereas only directory information is needed for classes, full path information is required for jar file and for each
jar file, a path is required. * cannot be used to match all the jar files in a certain directory.
Extra jar files or classes can be added during compilation or execution using javac or java command. For
example, compiling certain Java files with extra jar files:
javac classpath %CLASSPATH%;myJar.jar myPackage.MyClass.java

whereas a classpath option has been used. In this example, besides referencing the standard classpath, a myJar jar
file has been added to the classpath . Executing the Java class with extra classpath information can be achieved as
follows:
java cp myJar.jar myPackage.MyClass

whereas a cp option has been used to refer to the classpath, in this example, myJar jar file is used instead of the
standard classpath.
Read Environment Variables
It is important sometime to read system environment variables to get necessary information from Java
applications. Java provides a fairly easy way to access the environment variables as a Map. The following simple
program is used to retrieve all the environment variables in a particular system
Program 10
/* EnvReader.java. Reads all the system environment variables and their values */
import java.util.Map;
public class EnvReader {
public static void main (String[] args) {
Map<String, String> env = System.getenv();
for (String envName : env.keySet()) {
System.out.format("%s=%s%n", envName, env.get(envName));
}
}
}

Potrebbero piacerti anche