Encapsulation and Access Modifiers in Java
Protect an object's data with private fields, getters and setters, and control who can see what with access modifiers and packages.
Learning objectives
- βExplain encapsulation and why fields are usually private
- βWrite getters and setters, with validation inside the setters
- βKnow what private, default, protected and public each allow
- βPut a class in a package and import it from another class
π‘ Key points
- Encapsulation means keeping the data (fields) and the methods that work on it together, and hiding the data behind private.
- private means visible only inside the same class. Other classes must go through public methods.
- A getter (getName()) reads a field. A setter (setName()) changes it and can reject bad values.
- To make a field read-only from outside, give it a getter and no setter.
- Access levels from narrowest to widest: private, then default (no keyword, same package), then protected (same package plus subclasses), then public (everywhere).
- A package groups related classes, like a folder. The package line must be the first statement, and import lets you use a class from another package.
- A top-level class can only be public or default, and a .java file can hold at most one public class, named after the file.
π» Code examples(5)
class Account {
String holder;
double balance;
}
public class NoGuard {
public static void main(String[] args) {
Account acc = new Account();
acc.holder = "Amit";
acc.balance = -5000; // nothing stops this!
System.out.println(acc.holder + ": Rs."
+ acc.balance);
}
}
Amit: Rs.-5000.0
class Student {
private String name;
private int marks;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMarks() {
return marks;
}
public void setMarks(int marks) {
if (marks >= 0 && marks <= 100) {
this.marks = marks;
} else {
System.out.println("Rejected: " + marks);
}
}
}
public class GetSet {
public static void main(String[] args) {
Student s = new Student();
s.setName("Priya");
s.setMarks(92);
s.setMarks(150);
// s.marks = 150; // error: private access
System.out.println(s.getName() + " "
+ s.getMarks());
}
}
Rejected: 150 Priya 92
class BankAccount {
private final String accountNo;
private double balance;
BankAccount(String accountNo, double opening) {
this.accountNo = accountNo;
this.balance = opening;
}
public String getAccountNo() { return accountNo; }
public double getBalance() { return balance; }
public void deposit(double amt) {
if (amt > 0) balance += amt;
}
public boolean withdraw(double amt) {
if (amt > 0 && amt <= balance) {
balance -= amt;
return true;
}
return false;
}
}
public class BankDemo {
public static void main(String[] args) {
BankAccount acc = new BankAccount("SB-1021", 1000);
acc.deposit(500);
System.out.println(acc.withdraw(2000));
System.out.println(acc.withdraw(300));
System.out.println(acc.getAccountNo() + ": Rs."
+ acc.getBalance());
}
}
false true SB-1021: Rs.1200.0
// File: school/Student.java
package school;
public class Student {
public String name; // everywhere
protected int rollNo; // package + subclasses
String house; // default: package only
private int marks; // this class only
public Student(String name, int marks) {
this.name = name;
this.rollNo = 7;
this.house = "Red";
this.marks = marks;
}
public boolean passed() {
return marks >= 33; // private used inside
}
}
// File: Main.java
import school.Student;
public class Main {
public static void main(String[] args) {
Student s = new Student("Ravi", 67);
System.out.println(s.name);
System.out.println(s.passed());
// s.rollNo, s.house, s.marks: errors here,
// because Main is outside package school
}
}
Ravi true
// File: shapes/Shape.java
package shapes;
public class Shape {
protected String colour = "red";
}
// File: Main.java
import shapes.Shape;
class Circle extends Shape {
void paint() {
// allowed: Circle is a subclass of Shape
System.out.println("Circle is " + colour);
}
}
public class Main {
public static void main(String[] args) {
new Circle().paint();
Shape s = new Shape();
// s.colour = "blue"; // error: protected
}
}
Circle is red
π― Practice
Q1. Which access modifier makes a field visible only inside its own class?+
private.
Q2. A field is written with no modifier, as in int count;. Who can access it?+
Only code in the same package (this is called default or package-private access). Subclasses in other packages cannot.
Q3. Write a getter and a setter for private double price, where the setter ignores negative prices.+
public double getPrice() { return price; } public void setPrice(double price) { if (price >= 0) { this.price = price; } }
Q4. How do you make a field read-only for other classes?+
Make it private and provide a getter but no setter, and set its value in the constructor. Making it final as well stops even the class itself from changing it later.
Q5. Why is encapsulation useful even when you trust everyone who uses your class?+
It keeps the checking rules in one place, and it lets you change how the data is stored inside the class later without breaking any code that uses its methods.
π Notes
Who can see what
| Modifier | Same class | Same package | Subclass in another package | Anywhere |
|---|---|---|---|---|
private | Yes | No | No | No |
| default (none) | Yes | Yes | No | No |
protected | Yes | Yes | Yes | No |
public | Yes | Yes | Yes | Yes |
A good habit is to make fields private, make methods public only when other classes really need them, and use protected for parts meant for subclasses.
Packages and import
package school.exams; // must be the first line
import java.util.Scanner; // one class
import java.util.*; // every class in java.util
The folders must match the package name, so this file belongs in school/exams/. Classes in java.lang, such as String, Math and System, are imported automatically. That is why you have never had to import them.
What the errors look like
When Main (outside package school) touches the hidden members of Student:
- marks has private access in Student
- house is not public in Student; cannot be accessed from outside package
- rollNo has protected access in Student
Common mistakes
- Writing a setter for every field automatically. A setter with no checks is hardly better than a public field. Add only the setters you need, with validation.
- Writing
name = name;in a setter. Usethis.name = name;, otherwise the field never changes. - Putting a file in the wrong folder. A class in
package schoolthat is not insideschool/will not be found. - Marking a top-level class
private. This gives modifier private not allowed here. Onlypublicor default is allowed.
Next: Day 18, Exception Handling. Your programs will deal with errors without crashing.