|
Packages
Related Java classes can be grouped together into packages. A package roughly relates to a folder -- if several Java classes are put into the same folder, they are in the same package. The package keyword can be used to designate the complete name of a package. For example, the first line in the code below defines the package com.kiowok.sales:
package com.kiowok.sales;
public class Order
{
private int orderNum;
public Order(int orderNum)
{
if (orderNum > 0)
this.orderNum = orderNum;
}
public String toString()
{
return "Order: " + this.orderNum;
}
}
The code above puts the Order class is in the package named "com.kiowok.sales". This package name also indicates the folder hierarchy in which the Order.class file should be located -- in a folder named sales, which is in a folder named kiowok, which is in a folder named com. If a class in another folder wishes to use the Order class, then it must import Order, as done by the Customer class below (note that the Customer class is in a different package, "com.kiowok.clients"):
package com.kiowok.clients; // defines the Customer class' package
import com.kiowok.sales.Order; // imports Order from its package
public class Customer
{
public static void main(String [] args)
{
Order orderShoes = new Order(3);
System.out.println(orderShoes);
Complaint pants = new Complaint(4, "Too short");
System.out.println(pants);
}
}
Classes within the same package have special access to some of the entities defined in the other classes in that same package. The level of access to an object's members are controlled by the access modifiers. There are four possible access modifiers: public, private, protected and package (the first three are Java keywords -- package access is granted by saying nothing). In the example below, the class Xyz has four instance variables with four different levels of access:
class Xyz
{
private int w; // private access -- the most restrictive
int x; // package access
protected int y; // protected access
public int z; // public access -- the least restrictive
}
The table below summarizes the four levels of access, going from the most restrictive (private) to the least restrictive (public):
| Acces Modifier |
Description |
| private |
Only accessible to code within this class. |
| package |
Accessible to all code in all classes in this package. |
| protected |
Accessible to all code in all classes in this package AND to all subclasses (even subclasses defined in other packages). |
| public |
Accessible to all code in all classes in all packages. |
A Note on Compilation
In these examples I have kept the Java source code (.java files) in one common folder. The folder might have a name like "E:\java\development". The files were compiled with the "-d ." option, which causes the javac compiler to create the necessary package folders (e.g., com/kiowok/sales) under the one common folder and place the byte code (.class files) in appropriate subfolder. For example, if Order.java is in "E:\java\development\Order.java", then the byte code would end up in "E:\java\development\com\kiowok\sales\Order.class".
If you are using jGRASP (version 1.8.6_01), you can modify the compiler flags by clicking Settings/CSD Window Settings/Workspace, then click the Compiler tab, then the Flags/Args/Main tab. Deselect the square radio button next to the "Compile" box to open it for editing, then enter into the box the following:
-d .
That is a dash, followed by the letter 'd', followed by a space and then a period. Click OK.
A Short Example
The following example has five classes which are broken up into two different packages: sales and clients. The following graphic shows the classes and the folders in which they reside (for example the CreateOrder class is in the sales package and folder, which is then contained in the kiowok and com folders):

This graphic shows the relationship between the classes (and the folders in which the classes reside):

The code for the five classes is shown below. First is all of the code for the classes in the sales class, kept in three separate files:
//
// File: Order.java
//
package com.kiowok.sales;
public class Order
{
private int orderNum;
public Order(int orderNum)
{
if (orderNum > 0)
this.orderNum = orderNum;
}
public String toString()
{
return "Order: " + this.orderNum;
}
}
........................................................................................
//
// File SpecialOrder.java
//
package com.kiowok.sales;
public class SpecialOrder extends Order
{
private int priority; // 1 to 10 range
public static final int MIN_PRIO = 1;
public static final int MAX_PRIO = 10;
public SpecialOrder(int orderNum, int priority)
{
super(orderNum);
if (priority >= MIN_PRIO && priority <= MAX_PRIO)
this.priority = priority;
else
this.priority = MIN_PRIO;
}
public String toString()
{
return "Special Order -- priority " + priority + ", " + super.toString();
}
}
..............................................................................................
//
// File: CreateOrder.java
//
package com.kiowok.sales;
public class CreateOrder
{
public static void main(String [] args)
{
Order o1 = new Order(1);
System.out.println(o1);
SpecialOrder rush = new SpecialOrder(2, SpecialOrder.MAX_PRIO);
System.out.println(rush);
}
}
Here is the code for the classes in the clients package (kept in two different Java files):
//
// File: Customer.java
//
package com.kiowok.clients;
import com.kiowok.sales.Order;
public class Customer
{
public static void main(String [] args)
{
Order orderShoes = new Order(3);
System.out.println(orderShoes);
Complaint pants = new Complaint(4, "Too short");
System.out.println(pants);
}
}
......................................................................................
//
// File: Complaint.java
//
package com.kiowok.clients;
import com.kiowok.sales.Order;
public class Complaint extends Order
{
private String description;
public Complaint(int order, String description)
{
super(order);
this.description = description;
}
public String toString()
{
return "Complaint about " + super.toString() + " -- " + this.description;
}
}
Another Example
The classes defined in the following example are extremely compact. This example focuses on the variable x defined in the class A, and which lines of code can access x. The lines to consider are marked with the comment
// LEGAL?
Consider which lines are LEGAL (i.e., will compile) if the access to x is private, as shown in the code below. Then consider which lines are LEGAL if the access for the variable x is changed to package, protected or public. This picture indicates the relationships between the classes.

Here is the code from the classes in the oak package:
//
// File: A.java
//
package com.kiowok.oak;
public class A
{
public int x; // What code can access this x???
void increase()
{
x += 10; // LEGAL?
}
}
........................................................................
//
// File: B.java
//
package com.kiowok.oak;
public class B extends A
{
int y;
void process()
{
y = 3;
x = 22; // LEGAL?
}
}
........................................................................
//
// File: C.java
//
package com.kiowok.oak;
public class C
{
public static void main(String [] args)
{
A aref = new A();
aref.x = 100; // LEGAL?
}
}
Here is the code from the classes in the maple package:
//
// File: D.java
//
package com.kiowok.maple;
import com.kiowok.oak.A;
public class D extends A
{
int w;
void set()
{
w = 2;
x = 3; // LEGAL?
}
}
.........................................................................
//
// File: E.java
//
package com.kiowok.maple;
import com.kiowok.oak.A;
public class E
{
public static void main(String [] args)
{
A aref = new A();
aref.x = 55; // LEGAL?
}
}
The Default Package
If a programmer chooses not to explicitly designate a package for a class (i.e., does not define a package using the package keyword on the first line of the file) then the class is placed in the default package. The default package is the current folder. If several classes are in the same default package (the same folder) then they will have package access to each other's member variables and methods.
In the examples below, none of the classes explicity define a package and therefore are in the same default package. Therefore, variables "numPassengers" and "weight" are accessible to all classes defined below. They would be inaccessible to all classes defined in other packages.
public class MyProgram1
{
public static void main (String [] args)
{
Bicycle b = new Bicycle(40);
System.out.println(b.report());
b.numPassengers = 25; // package access (accessible IF this class is
// in the same package as Transport)
}
}
abstract class Transport
{
int numPassengers = 0; // package: public to all classes in this file/directory
// Inaccessible to classes outside this package, even if that
// class extends Transport
abstract public int maxSpeed();
}
class Bicycle extends Transport
{
int weight; // package: public to all classes in this file/directory
public Bicycle(int weight)
{
this.weight = weight;
numPassengers = 1; // package: public to all classes in this file/directory
// but an error if this class is in a different
} // package (directory) than Transport
public int maxSpeed()
{
return 45;
}
public String report()
{
return "Bicycle with weight of " + weight + "pounds";
}
}
Public
If we set the two variables to "public", they will still be available to all classes in this file and directory. They will now also be available to any classes in different packages (directories) that might want to import our classes:
public class MyProgram2
{
public static void main (String [] args)
{
Bicycle b = new Bicycle(40);
System.out.println(b.report());
b.numPassengers = 25; // public access
}
}
abstract class Transport
{
public int numPassengers = 0; // public here and everywhere else
abstract public int maxSpeed();
}
class Bicycle extends Transport
{
public int weight; // public here and everwhere else
public Bicycle(int weight)
{
this.weight = weight;
numPassengers = 1; // public here and everywhere else
}
public int maxSpeed()
{
return 45;
}
public String report()
{
return "Bicycle with weight of " + weight + "pounds";
}
}
Private
The "safest" way to define a variable is to make it private. However, if we simply change "public" to "private" for the current example, we will have problems:
public class MyProgram3
{
public static void main (String [] args)
{
Bicycle b = new Bicycle(40);
System.out.println(b.report());
b.numPassengers = 25; // error!
}
}
abstract class Transport
{
private int numPassengers = 0; // changed to private
abstract public int maxSpeed();
}
class Bicycle extends Transport
{
private int weight; // changed to private
public Bicycle(int weight)
{
this.weight = weight;
numPassengers = 1; // error!
}
public int maxSpeed()
{
return 45;
}
public String report()
{
return "Bicycle with weight of " + weight + "pounds";
}
}
Private -- get/set
Even the subclass of Transport cannot access its private variables.
Either make numPassengers public (or better yet, protected), or else
supply "get" and "set" methods for the private variable.
Keep numPassengers private and supply public "get" and "set" methods:
public class MyProgram4
{
public static void main (String [] args)
{
Bicycle b = new Bicycle(40);
System.out.println(b.report());
b.numPassengers = 25; // error for this directory (or another directory)!
}
}
abstract class Transport
{
private int numPassengers = 0;
public int getNumPassengers()
{
return numPassengers;
}
public void setNumPassengers(int num)
{
if (num > 0 && num < 1000000)
numPassengers = num;
}
abstract public int maxSpeed();
}
class Bicycle extends Transport
{
private int weight;
public Bicycle(int weight)
{
this.weight = weight;
setNumPassengers(1); // use the public "set" method
}
public int maxSpeed()
{
return 45;
}
public String report()
{
return "Bicycle with weight of " + weight + "pounds";
}
}
Private -- use constructor to set
Another alternative is to keep the variable private, set the variable in a constructor and just supply the "get" method:
public class MyProgram6
{
public static void main (String [] args)
{
Bicycle b = new Bicycle(40);
System.out.println(b.report());
b.numPassengers = 25; // error for this directory (or another directory)!
b.weight = 3; // error for this directory (or another directory)!
}
}
abstract class Transport
{
private int numPassengers = 0;
public Transport(int num)
{
this.numPassengers = num;
}
public int getNumPassengers()
{
return numPassengers;
}
abstract public int maxSpeed();
}
class Bicycle extends Transport
{
private int weight;
public Bicycle(int weight)
{
super(1);
this.weight = weight;
}
public int maxSpeed()
{
return 45;
}
public String report()
{
return "Bicycle with weight of " + weight + "pounds";
}
}
Protected
One more possibility is to use the keyword "protected". Protected is very similar to package access
(saying nothing) in that a protected variable is open to access by all of the classes defined in the same
file/directory. It is less restrictive than package access in that a
"protected" variable CAN be accessed by a class outside the current package (directory) if that
class is a subclass of the class containing the protected variable.
public class MyProgram5
{
public static void main (String [] args)
{
Bicycle b = new Bicycle(40);
System.out.println(b.report());
b.numPassengers = 25; // OK if in this directory, still an error if this
// class is in different package than Transport (unless this
// outside class extends Transport
}
}
abstract class Transport
{
protected int numPassengers = 0; // changed to protected
abstract public int maxSpeed();
}
class Bicycle extends Transport
{
protected int weight;
public Bicycle(int weight)
{
this.weight = weight;
numPassengers = 1; // NO LONGER an error
}
public int maxSpeed()
{
return 45;
}
public String report()
{
return "Bicycle with weight of " + weight + "pounds";
}
}
The following list gives, in order, the levels of accessibility for a variable defined as:
- public Accessible to all code in all classes, in or out of the this package.
- protected Accessible to all code in all classes in this package, accessible to all
code in classes outside of this package IF they extend the class containing the protected variable, otherwise inaccessible to code in classes in outside classes.
- package Accessible to all code in all classes in this package -- inaccessible to
all code in classes out of this package (even those classes that extend the class containing the
package-access variable).
- private Accessible only to code in the class that declares this private variable.
Interfaces and Abstract Methods
An informal description of an interface is that it is a class definition that contains only
abstract method definitions. Instead of "extend"ing a interface you "implement" it, but the result is the same --
if a class implements an interface, it must implement all of the methods in the interface if it is to be a
concrete class. Otherwise, the class must declare itself to be abstract. Similarly, a class can define an abstract method -- an abstract method has a header line but no body. The class must then declare itself to be abstract. An abstract class cannot be instantiated. If another class extends an abstract class, it must define the inherited abstract method or declare itself to be abstract also. If subclass defines the abstract method, it can then be instantiated (a class that can be instantiated is referred to as a "concrete" class).
Programs With Problems
Problem 1
Find the problem(s) with the following code:
public class MyProgram2
{
public static void main (String [] args)
{
Bicycle b = new Bicycle(40);
System.out.println(b.report());
b.numPassengers = 25; //
}
}
abstract class Transport
{
private int numPassengers = 0; //
abstract public int maxSpeed();
}
class Bicycle extends Transport
{
public int weight; //
public Bicycle(int weight)
{
this.weight = weight;
numPassengers = 1; //
}
}
Problem 2
Find the problem(s) with the following code:
public interface Financial
{
public double getCost();
public String identifyOwner(int year);
public void setMaxValue(double value);
}
public class MyProgram2
{
public static void main (String [] args)
{
Bicycle b = new Bicycle(40);
System.out.println(b.report());
b.numPassengers = 25; //
}
}
abstract class Transport implements Financial
{
public int numPassengers = 0; //
abstract public int maxSpeed();
}
class Bicycle extends Transport
{
public int weight; //
public Bicycle(int weight)
{
this.weight = weight;
numPassengers = 1; //
}
public int maxSpeed()
{
return 45;
}
public String report()
{
return "Bicycle with weight of " + weight + "pounds";
}
}
Problem 3
Find the problem(s) with the following code:
public interface Financial
{
public double getCost();
public String identifyOwner(int year);
public void setMaxValue(double value);
}
public class MyProgram2
{
public static void main (String [] args)
{
Bicycle b = new Bicycle(40);
System.out.println(b.report());
b.numPassengers = 25; //
}
}
abstract class Transport implements Financial
{
public int numPassengers = 0; //
abstract public int maxSpeed();
public double getCost()
{
return 1.00;
}
}
class Bicycle extends Transport
{
public int weight; //
public Bicycle(int weight)
{
this.weight = weight;
numPassengers = 1; //
}
public int maxSpeed()
{
return 45;
}
public String report()
{
return "Bicycle with weight of " + weight + "pounds";
}
public String identifyOwner(int year)
{
if (year > 1983)
return "Bill Gates";
else
return "Henry Ford";
}
public void setMaxValue(double value)
{
System.out.println("Max value is: " + value);
}
}
Problem 4
Find the problem(s) with the following code:
public interface Financial
{
public double getCost();
public String identifyOwner(int year);
public void setMaxValue(double value);
}
public class MyProgram2
{
public static void main (String [] args)
{
Bicycle b = new Bicycle(40);
System.out.println(b.report());
b.numPassengers = 25; //
}
}
abstract class Transport implements Financial
{
public int numPassengers = 0; //
abstract public int maxSpeed();
public double getCost()
{
return 1.00;
}
}
class Bicycle extends Transport
{
public int weight; //
public Bicycle(int weight)
{
this.weight = weight;
numPassengers = 1; //
}
public int maxSpeed()
{
return 45;
}
public String report()
{
return "Bicycle with weight of " + weight + "pounds";
}
public String identifyOwner(int year)
{
if (year > 1983)
return "Bill Gates";
else
return "Henry Ford";
}
public void setMaxValue(double value, int x, int y, int z, int a, int b, int c)
{
System.out.println("Max value is: " + value);
}
}
Problem 5
Find the problem(s) with the following code:
public interface Financial
{
public double getCost();
public String identifyOwner(int year);
public void setMaxValue(double value);
}
public class MyProgram2
{
public static void main (String [] args)
{
Bicycle b = new Bicycle(40);
System.out.println(b.report());
b.numPassengers = 25; //
}
}
abstract class Transport implements Financial
{
private int numPassengers = 0; //
abstract public int maxSpeed();
public double getCost()
{
return 1.00;
}
public void setMaxValue(double value)
{
System.out.println("Max value is: " + value);
}
}
class Bicycle extends Transport
{
public int weight; //
public Bicycle(int weight)
{
this.weight = weight;
numPassengers = 1; //
}
public int maxSpeed()
{
return 45;
}
public String report()
{
return "Bicycle with weight of " + weight + "pounds";
}
}
|