Understanding Modifiers in Java

Afzal Badshah, PhD
7 min readSep 21, 2024

Modifiers in Java are used to control the behaviour and accessibility of classes, methods, and variables. They define who can access certain parts of a program and how the components of the class behave. Modifiers are categorized into two main types: Access Modifiers and Non-Access Modifiers. Access modifiers determine the visibility of classes and their members, while non-access modifiers control aspects like immutability or the necessity of subclass implementation. Visit the detailed tutorial here.

Access Modifiers

In Java, access modifiers determine who can access or modify classes, attributes, and methods. These modifiers help manage access control within your program, ensuring that important data is protected while allowing access to essential functionalities. There are three primary access modifiers in Java: public, private, and protected.

Let’s explore these access modifiers step by step, using the Calculator program.

public class Calculator {
    // Attributes of the class
private int a;
private int b;
// Method for sum
public int sum(int a, int b) {
return a + b;
}
// Method for subtraction
public int subtract(int a, int b) {
return a - b;
}
// Method for multiplication
public int multiply(int a, int b) {
return a * b;
}
}

Public Modifier

When you declare a class, method, or variable as public, it can be accessed from anywhere in your program. In the example above, the Calculator class is declared public:

public class Calculator { 
public int a;
public int b;
public int sum(a, b) {
return a + b;
}
}

This means that any other class can create an object of the Calculator class and use its methods. For example, you could create an object of this class and use its methods like this:

Calculator calc = new Calculator();
int result = calc.sum(10, 5);

Here, the sum, subtract, and multiply methods are also declared public:

public int sum(int a, int b) { 
return a + b;
}

Since these methods are public, they are accessible from anywhere in your code. So, if another class wants to call any of these methods, it can do so without any restrictions. You use the public modifier when you want methods or attributes to be available for interaction with other classes.

Private Modifier

The private modifier is used to restrict access to certain variables or methods within the class itself. It means that anything declared private can only be accessed inside that class and cannot be accessed or modified directly by any other class.

In Calculator program, the attributes a and b are declared private:

private int a;
private int b;

These variables are only accessible inside the Calculator class. No other class can directly access or modify these values. For example, this line of code would cause an error:

Calculator calc = new Calculator();
calc.a = 10; // Error: 'a' has private access in 'Calculator'

This is important for data protection. By making the variables private, you ensure that other parts of the program can’t change the values of a and b unless you explicitly allow it through public methods. In your program, you provide public methods like sum and subtract that use the values of a and b indirectly. This is called encapsulation—hiding the details but exposing the necessary functionality.

If you ever need to allow access to a and b (but still keep control), you can create getter and setter methods like this:

public int getA() {
return a;
}
public void setA(int value) {
this.a = value;
}

Protected Modifier

The protected modifier allows access to a variable or method within the same package and to subclasses (even if those subclasses are in different packages). This is especially useful in the context of inheritance.

For example, if you have a class that extends Calculator and you want certain methods or variables to be accessible only to that subclass or classes in the same package, you would use the protected modifier:

protected void display() {
System.out.println("This is a protected method");
}

This method can be accessed by classes in the same package or by any class that inherits from Calculator. However, it cannot be accessed from a completely unrelated class.

  • Public: Allows access from anywhere in the program. In Calculator class, the class itself and the methods (sum, subtract, multiply) are public, so they can be accessed from any other class in your project.
  • Private: Limits access to only within the same class. The attributes a and b in Calculator class are private, meaning they cannot be accessed or modified directly from outside the class. You can, however, access them through public methods.
  • Protected: Primarily used in inheritance scenarios. It allows access within the same package or in subclasses, but not from completely unrelated classes.

Why are Access Modifiers Important?

Access modifiers help you organize and control the visibility of your code. In Calculator class, making the methods public allows other classes to perform operations like addition, subtraction, and multiplication, while keeping the variables a and b private ensures that no one can directly manipulate these values. This is called data encapsulation, which is a key principle of object-oriented programming.

Non-Access Modifiers

In addition to access modifiers like public, private, and protected, Java provides non-access modifiers that control other aspects of the behavior of classes, methods, and variables. Some common non-access modifiers are final and abstract. Let’s explore these with the Calculator example.

Final Modifier

The final modifier in Java is used to restrict the modification of a class, method, or variable. Once something is declared as final, its value or definition cannot be changed.

Final Variable

A final variable cannot be modified after it has been assigned a value. For example, if you wanted to define a constant in Calculator class (like a fixed value of pi), you would use the final modifier:

public class Calculator {
private final double pi = 3.14159;
    // Other attributes and methods...
}

In this case, pi is a constant. Once initialized, its value cannot be changed. If you try to modify it later in the program, Java will throw an error. This is helpful when you need to define values that should not change throughout the execution of your program.

Final Method

A final method means that the method cannot be overridden by any subclass. For instance, if you want to make sure that the method sum in the Calculator class remains the same in any subclass, you can declare it as final:

public final int sum(int a, int b) {
return a + b;
}

Now, if another class extends Calculator, it will not be allowed to change the behavior of the sum method. This is useful when you have a method that works perfectly and should not be modified in subclasses.

Final Class

A final class means that no other class can extend or inherit from it. This prevents subclassing. If you want to ensure that no one can create a subclass of Calculator, you can declare the class as final:

public final class Calculator {
// Class content...
}

Once you declare the class as final, it cannot be extended:

class AdvancedCalculator extends Calculator {
// Error: Cannot subclass a final class
}

This is typically used when you want to make the class completely sealed and prevent further modification or extension.

Abstract Modifier

The abstract modifier is used to create abstract classes and methods. An abstract class cannot be instantiated on its own, and an abstract method must be implemented by a subclass. This is useful when you are creating a base class that provides a general structure, but you want to leave some details to be defined in child classes.

Abstract Class

An abstract class cannot be used to create objects. It can have both abstract and concrete (non-abstract) methods. If you want to create a base class for calculators that will later be extended by specific types of calculators (like scientific calculators or financial calculators), you can declare the class as abstract:

public abstract class Calculator {
// Abstract method
public abstract int divide(int a, int b);
    // Concrete method
public int sum(int a, int b) {
return a + b;
}
}

In this example, the Calculator class is abstract, meaning you cannot create an object of Calculator directly. Instead, you would need to create a subclass that provides the implementation of the divide method.

Abstract Method

An abstract method is a method that has no body (no implementation) in the abstract class. Subclasses that extend the abstract class are required to provide an implementation for this method. In the example above, the method divide is abstract:

public abstract int divide(int a, int b);

Any subclass of Calculator must implement this method:

public class AdvancedCalculator extends Calculator {
@Override
public int divide(int a, int b) {
if (b != 0) {
return a / b;
} else {
throw new ArithmeticException("Cannot divide by zero");
}
}
}

In this case, the AdvancedCalculator class extends Calculator and provides the implementation for the divide method. This allows you to enforce that all calculators must have a divide method, but the details of how division works can vary between different types of calculators.

  • Final: Used to prevent modification. A final variable cannot be changed, a final method cannot be overridden, and a final class cannot be extended.
  • Abstract: Used to create a blueprint for other classes. An abstract class cannot be instantiated directly, and abstract methods must be implemented by subclasses.

By using non-access modifiers like final and abstract, you can create more secure and flexible Java programs. The final modifier helps protect critical parts of your code, while the abstract modifier allows you to build a base structure for other classes to follow, promoting reuse and maintainability.

Visit the presentation here

--

--

Afzal Badshah, PhD
Afzal Badshah, PhD

Written by Afzal Badshah, PhD

Dr Afzal Badshah focuses on academic skills, pedagogy (teaching skills) and life skills.

No responses yet