Monday, January 25, 2016

Topic 27: Packages in Java

  • Packages are containers for classes that are used to keep the class name space compartmentalized thus allowing us to create similar named classes across packages without concern of name conflicts. 

  • Packages are stored in a hierarchical manner and are explicitly imported into new class definitions.

  • To create a package simply include a package command as the first statement in a Java source file. Any classes declared within that file will belong to the specified package. 

    The package statement defines a name space in which classes are stored. If we omit the package statement, the class names are put into the default package, which has no name. 

    The general form of the package statement:

package pkg;

Here, pkg is the name of the package.

  • Java uses file system directories to store packages. For example, the .class files for any classes we declare to be part of package MyPackage must be stored in a directory called MyPackage. Remember that case is significant, and the directory name must match the package name exactly.

  • We can create a hierarchy of packages. To do so, simply separate each package name from the one above it by use of a period. The general form of a multileveled package statement is shown here:

package pkg1[.pkg2[.pkg3]];


A package hierarchy must be reflected in the file system of our Java development system. For example, a package declared as package java.awt.image; needs to be stored in java\awt\image in a Windows environment. 

We cannot rename a package without renaming the directory in which the classes are stored.


  • The Java run-time system looks for packages that we create as follows:

First, the current working directory as its starting point. Thus, if our package is in a subdirectory of the current directory, it will be found.

Second, we can specify a directory path or paths by setting the CLASSPATH environmental variable.

Third, we can use the -classpath option with java and javac to specify the path to your classes.


  • If MyClass is part of the package MyPack, it means that MyClass cannot be executed by itself, but it must be qualified with package name, i.e. we have to use following  statements to execute the program: java MyPack.MyClass

  • Java addresses four categories of visibility for class members:

  • Subclasses in the same package

  • Non-subclasses in the same package

  • Subclasses in different packages

  • Classes that are neither in the same package nor subclasses


The three access specifiers, private, public, and protected, provide a variety of ways to produce the many levels of access required by these categories.


Anything declared public can be accessed from anywhere. 

Anything declared private cannot be seen outside of its class.

A member with no explicit access specification and is visible to subclasses and other classes in the same package. This is the default access.

If we want to allow an element to be seen outside our current package, but only to classes that subclass our class directly, then declare that element protected.

When a class is public, it must be the only public class declared in the file, and the file must have the same name as the class.

The following example shows all combination of the access control modifiers. This example has two packages(in this case, p1 and p2) and five classes.

This is file Protection.java:
package p1; public class Protection //public so that it can be accessed from outside this package.
{
int n = 1;
private int n_pri = 2;
protected int n_pro = 3;
public int n_pub = 4;

public Protection()
{
System.out.println("base constructor");
System.out.println("n = " + n);
System.out.println("n_pri = " + n_pri);
System.out.println("n_pro = " + n_pro);
System.out.println("n_pub = " + n_pub);
}
}

This is file Derived.java:
package p1;
class Derived extends Protection
{
Derived()
{
System.out.println("derived constructor");
System.out.println("n = " + n);
// System.out.println("n_pri = " + n_pri); //private in superclassSystem.out.println("n_pro = " + n_pro);
System.out.println("n_pub = " + n_pub);
}
}

This is file SamePackage.java:
package p1;
class SamePackage
{
SamePackage()
{
Protection p = new Protection();
System.out.println("same package constructor");
System.out.println("n = " + p.n);
// System.out.println("n_pri = " + p.n_pri);
System.out.println("n_pro = " + p.n_pro);
System.out.println("n_pub = " + p.n_pub);
}
}

This is file Protection2.java:
package p2;
class Protection2 extends p1.Protection

{
Protection2()
{
System.out.println("derived other package constructor");
// System.out.println("n = " + n);
// System.out.println("n_pri = " + n_pri);

System.out.println("n_pro = " + n_pro);
System.out.println("n_pub = " + n_pub);
}
}

This is file OtherPackage.java:
package p2;
class OtherPackage
{
OtherPackage()
{
p1.Protection p = new p1.Protection(); System.out.println("other package constructor");
// System.out.println("n = " + p.n);
// System.out.println("n_pri = " + p.n_pri);
// System.out.println("n_pro = " + p.n_pro);

System.out.println("n_pub = " + p.n_pub);
}
}

// Demo package p1.
package p1;
public class Demo
{
public static void main(String args[])
{
// Instantiate the various classes in p1.
Protection ob1 = new Protection();
Derived ob2 = new Derived();
SamePackage ob3 = new SamePackage();
}
}

The test file for p2 is shown next:
// Demo package p2.
package p2;
public class Demo
{
public static void main(String args[])
{
// Instantiate the various classes in p2.
Protection2 ob1 = new Protection2();
OtherPackage ob2 = new OtherPackage();
}
}

  • Java includes the import statement to bring certain classes, or entire packages, into visibility. Once imported, a class can be referred to directly, using only its name.

In a Java source file, import statements occur immediately following the package statement (if it exists) and before any class definitions. This is the general form of the import statement:  

import pkg1[.pkg2].(classname|*);

Here, pkg1 is the name of a top-level package, and pkg2 is the name of a subordinate package inside the outer package separated by a dot (.). There is no practical limit on the depth of a package hierarchy, except that imposed by the file system. Finally, we specify either an explicit classname or a star (*), which indicates that the Java compiler should import the entire package. This code fragment shows both forms in use:

 import java.util.Date;

 import java.io.*;

CAUTION The star form may increase compilation time but has no effect on the run-time performance or size of our classes.

  • All standard Java classes are stored in a package called java

    The basic language functions are stored in a package inside of the java package called java.lang

    java.lang, it is implicitly imported by the compiler for all programs.

  • If a class with the same name exists in two different packages that we import using the star form, the compiler will remain silent, unless we try to use one of the classes. In that case, we will get a compile-time error and have to explicitly name the class specifying its package.

The import statement is optional. Any place we use a class name, we can use its fully qualified name, which includes its full package hierarchy. For example, this fragment uses an import statement:

import java.util.*;

class MyDate extends Date

{

}

The same example without the import statement looks like this:

class MyDate extends java.util.Date

{

}

In this version, Date is fully-qualified.

  • When a package is imported, only those items within the package declared as public will be available to non-subclasses in the importing code.


 Click for NEXT article.

 

Please feel free to correct me by commenting your suggestions and feedback.

No comments:

Post a Comment