In Java programming, modifiers are keywords that provide additional information about classes, methods, variables, etc. They help in defining the scope and behavior of these elements. Understanding modifiers is crucial for controlling access to your code components and ensuring encapsulation.
This tutorial will cover two types of modifiers: access modifiers (public, private, protected) and non-access modifiers (final, static, abstract). By the end of this lesson, you'll be able to effectively use these modifiers to manage the visibility and behavior of your Java classes and objects.
Modifiers in Java play a vital role in defining how different parts of your code interact with each other. They ensure that your classes and methods are accessible only when intended, enhancing security and maintainability.
Access modifiers control the visibility of classes, methods, and variables across different packages. Non-access modifiers provide additional functionalities such as making classes or methods immutable, static, or abstract.
Access modifiers determine the scope of visibility for classes, methods, and variables. Java provides four access levels:
The public modifier allows a class, method, or variable to be accessed from any other class in the same package or different packages.
1public class PublicModifier {2public int x = 5;34public void display() {5System.out.println("x: " + x);6};7}89class AnotherClass {10public static void main(String[] args) {11PublicModifier obj = new PublicModifier();12obj.display(); // Output: x: 513}14}
x: 5
Tip: Use the public modifier when you want to expose your class, method, or variable to all other classes.
The private modifier restricts a class, method, or variable so that it can only be accessed within its own class.
1public class PrivateModifier {2private int x = 5;34private void display() {5System.out.println("x: " + x);6}78public static void main(String[] args) {9PrivateModifier obj = new PrivateModifier();10// obj.display(); // This will cause a compile-time error11System.out.println(obj.x); // This will also cause a compile-time error12}13}
Tip: Use the private modifier to encapsulate your class members, ensuring they are not accessible from outside the class.
The protected modifier allows a class, method, or variable to be accessed within its own package and by subclasses (even if they are in different packages).
1package com.example.package1;23public class Parent {4protected int x = 5;56protected void display() {7System.out.println("x: " + x);8}9}1011// In a different package12package com.example.package2;1314import com.example.package1.Parent;1516public class Child extends Parent {17public static void main(String[] args) {18Child obj = new Child();19obj.display(); // Output: x: 520System.out.println(obj.x); // Output: 521}22}
Tip: Use the protected modifier when you want to allow access within the same package and subclasses, but not from other packages.
When no access modifier is specified, a class, method, or variable has default visibility. It can only be accessed within its own package.
1package com.example.package1;23class DefaultClass {4int x = 5;56void display() {7System.out.println("x: " + x);8}9}1011// In a different package12package com.example.package2;1314import com.example.package1.DefaultClass;1516public class AnotherClass {17public static void main(String[] args) {18DefaultClass obj = new DefaultClass();19// obj.display(); // This will cause a compile-time error20// System.out.println(obj.x); // This will also cause a compile-time error21}22}
Tip: Use the default modifier when you want to restrict access to the same package only.
Non-access modifiers provide additional functionalities to classes, methods, and variables. We'll cover three non-access modifiers: final, static, and abstract.
The final modifier can be applied to classes, methods, and variables.
final cannot be subclassed.final cannot be overridden by subclasses.final must be initialized at the time of declaration and cannot be changed afterward.1public class FinalClass {2final int x = 5;34public final void display() {5System.out.println("x: " + x);6}78public static void main(String[] args) {9FinalClass obj = new FinalClass();10obj.display(); // Output: x: 511}12}1314// Attempting to subclass a final class will cause a compile-time error15// class SubFinalClass extends FinalClass {} // This will not compile
Tip: Use the final modifier when you want to prevent further modification or inheritance.
The static modifier can be applied to methods and variables.
static belongs to the class rather than any object of the class. It can be called without creating an instance of the class.static is shared among all instances of the class. Changes to a static variable are reflected across all objects.1public class StaticModifier {2static int x = 5;34public static void display() {5System.out.println("x: " + x);6}78public static void main(String[] args) {9StaticModifier.display(); // Output: x: 510System.out.println(StaticModifier.x); // Output: 51112StaticModifier obj = new StaticModifier();13obj.x = 10;14System.out.println(obj.x); // Output: 1015}16}
Tip: Use the static modifier when you want to associate a method or variable with the class itself, rather than any specific instance.
The abstract modifier can be applied to classes and methods.
abstract cannot be instantiated on its own. It must be subclassed.abstract does not have an implementation in the abstract class. Subclasses must provide implementations for these methods.1abstract class Animal {2abstract void makeSound();34void breathe() {5System.out.println("Breathing...");6}7}89class Dog extends Animal {10void makeSound() {11System.out.println("Bark");12}13}1415public class Main {16public static void main(String[] args) {17// Animal obj = new Animal(); // This will cause a compile-time error18Dog dog = new Dog();19dog.makeSound(); // Output: Bark20dog.breathe(); // Output: Breathing...21}22}
Tip: Use the abstract modifier when you want to define a class that cannot be instantiated on its own and requires subclasses to provide specific implementations.
Let's create a practical example that demonstrates the use of access and non-access modifiers in a real-world scenario. We'll create a simple banking application where we have an abstract class Account with different types of accounts like SavingsAccount and CheckingAccount.
1abstract class Account {2protected String accountNumber;3protected double balance;45public Account(String accountNumber, double initialBalance) {6this.accountNumber = accountNumber;7this.balance = initialBalance;8}910abstract void deposit(double amount);1112abstract void withdraw(double amount);1314public final void displayBalance() {15System.out.println("Account Number: " + accountNumber);16System.out.println("Balance: $" + balance);17}18}1920class SavingsAccount extends Account {21private static int interestRate = 5;2223public SavingsAccount(String accountNumber, double initialBalance) {24super(accountNumber, initialBalance);25}2627@Override28void deposit(double amount) {29balance += amount;30}3132@Override33void withdraw(double amount) {34if (amount <= balance) {35balance -= amount;36} else {37System.out.println("Insufficient funds");38}39}4041public static int getInterestRate() {42return interestRate;43}44}4546class CheckingAccount extends Account {47private double overdraftLimit;4849public CheckingAccount(String accountNumber, double initialBalance, double overdraftLimit) {50super(accountNumber, initialBalance);51this.overdraftLimit = overdraftLimit;52}5354@Override55void deposit(double amount) {56balance += amount;57}5859@Override60void withdraw(double amount) {61if (amount <= balance + overdraftLimit) {62balance -= amount;63} else {64System.out.println("Exceeds overdraft limit");65}66}67}6869public class Main {70public static void main(String[] args) {71SavingsAccount savings = new SavingsAccount("SA001", 1000);72CheckingAccount checking = new CheckingAccount("CA001", 500, 200);7374savings.deposit(200);75savings.withdraw(300);76savings.displayBalance(); // Output: Account Number: SA00177// Balance: $9007879checking.deposit(100);80checking.withdraw(800);81checking.displayBalance(); // Output: Account Number: CA00182// Balance: -$30083}84}
| Modifier | Description |
|---|---|
| Access Modifiers | |
| public | Accessible from any class |
| protected | Accessible within the same package and subclasses |
| default | Accessible within the same package only (no modifier) |
| private | Accessible only within its own class |
| Non-Access Modifiers | |
| final | Prevents further modification or inheritance |
| static | Associated with the class, not an instance |
| abstract | Defines a class that cannot be instantiated and requires subclasses to provide implementations |
In the next lesson, we'll dive into Java Encapsulation, which is a fundamental concept in object-oriented programming. Encapsulation helps in bundling the data (variables) with the methods that operate on the data, thereby protecting it from unauthorized access.
Stay tuned for more insights and practical examples to enhance your Java programming skills!