Packages
A package in Java is a mechanism for organizing related classes and interfaces into a single group or namespace. Like a folder on computer that groups related files.
A package is defined using the package keyword as the first statement in a Java source file.
package com.mycompany.myapp;
The primary purposes of packages are:
Namespace Management: Packages prevent naming conflicts. For example, you can have a
Date
class in your owncom.mycompany
package and also use the standardjava.util.Date
class without any confusion, because they exist in different namespaces.Access Control: Packages provide a level of access protection. You can define classes and members that are only visible within the same package, hiding them from outside code.
Organization: They make it easier to locate and use related classes, improving the overall structure and maintainability of large applications.
Access Specifiers / Modifiers
Access specifiers (or access modifiers) are keywords that determine the visibility and accessibility of a class and its members (fields, methods, constructors).
Java has four types of access specifiers:
public
: Apublic
member is accessible from any other code in the entire application, regardless of the package. It's the least restrictive level.protected
: Aprotected
member is accessible within its own package and by subclasses in other packages. It's used to expose things to child classes while hiding them from the general public.(default)
or package-private: If no modifier is specified, the access level isdefault
. A member with default access is only accessible by code within the same package. It's invisible to all classes outside its package, including subclasses in other packages.private
: Aprivate
member is only accessible within its own class. This is the most restrictive level and is key to encapsulation and data hiding.
Context | Private | Default (No Modifier) | Protected | Public |
---|---|---|---|---|
Same Class | ✅ | ✅ | ✅ | ✅ |
Same Package Subclass | ✅ | ✅ | ✅ | |
Same Package Non-subclass | ✅ | ✅ | ✅ | |
Different Package Subclass | ✅ | ✅ | ||
Different Package Non-subclass | ✅ |
3. Balance
Package and Access Control
This example demonstrates how a public
class in one package can be used by another, while its members are still protected.
project/
├── mybank/
│ └── Balance.java
└── TestBalance.java
mybank/Balance.java
package mybank;
public class Balance {
String name; // default access
private double bal; // private access
public Balance(String n, double b) {
this.name = n;
this.bal = b;
}
// A public method to display the balance
public void show() {
if (bal < 0) {
System.out.print("--> ");
}
System.out.println(name + ": $" + bal);
}
}
TestBalance.java
import mybank.Balance;
public class TestBalance {
public static void main(String[] args) {
Balance current = new Balance("K. J. Fielding", 123.23);
// OK: We can call the public 'show()' method
current.show();
// ERROR: cannot access the 'bal' directly.
current.bal = 50.0;
// ERROR: cannot access the 'name' variable directly
// default is for within same package
System.out.println(current.name);
System.out.println("Successfully used the Balance class from another package.");
}
}
4. geometry
Package
project/
├── geometry/
│ └── Circle.java
└── GeometryDemo.java
geometry/Circle.java
package geometry;
public class Circle {
private double radius;
public Circle(double r) {
this.radius = r;
}
public double calculateArea() {
return Math.PI * radius * radius;
}
}
GeometryDemo.java
import geometry.Circle;
public class GeometryDemo {
public static void main(String[] args) {
Circle myCircle = new Circle(10.0);
// Use the public method to calculate the area
double area = myCircle.calculateArea();
System.out.printf("The area of a circle with radius 10.0 is %.2f\n", area);
}
}
4. shape
Package
shape
package with three classes. A separate main
program then imports and uses them.
project/
├── shape/
│ ├── Circle.java
│ ├── Square.java
│ └── Triangle.java
└── Main.java
shape/Circle.java
package shape;
public class Circle {
public void draw() {
System.out.println("Drawing a Circle");
}
}
shape/Square.java
package shape;
public class Square {
public void draw() {
System.out.println("Drawing a Square");
}
}
shape/Triangle.java
package shape;
public class Triangle {
public void draw() {
System.out.println("Drawing a Triangle");
}
}
Main.java
import shape.Circle;
import shape.Square;
import shape.Triangle;
public class Main {
public static void main(String[] args) {
System.out.println("Using classes from the 'shape' package:");
Circle c = new Circle();
c.draw();
Square s = new Square();
s.draw();
Triangle t = new Triangle();
t.draw();
}
}
This example shows how access modifiers work from another class within the same package.
// In a file named Account.java
class Account {
public String ownerName; // Accessible by anyone
protected double balance; // package and by subclasses
String accountType; // only within this package
private String accountNumber; // ONLY within the Account class
public Account(String owner, double bal, String type, String num) {
this.ownerName = owner;
this.balance = bal;
this.accountType = type;
this.accountNumber = num;
}
// A public method to display the private account number
public void displayAccountNumber() {
System.out.println("Account Number: "
+ this.accountNumber);
}
}
// BankDemo.java (in the same package)
class BankDemo {
public static void main(String[] args) {
Account myAccount = new Account("John Doe", 5000.0, "Checking", "123-456-789");
// OK: ownerName is public
System.out.println("Owner: "
+ myAccount.ownerName);
// OK: balance is protected, in same package
myAccount.balance += 100;
System.out.println("New Balance: "
+ myAccount.balance);
// OK: accountType is default, in same package
System.out.println("Type: "
+ myAccount.accountType);
// ERROR! This line would cause a compiler error.
System.out.println(myAccount.accountNumber);
// 'accountNumber' has private access in 'Account'
// Access private data is through a public method
myAccount.displayAccountNumber();
}
}