Learn Java from Scratch: Access modifiers in Java6 min read

modifier types: access modifers in java

Modifier Overview

We have learned about variables and data types in Java, I think now it’s a good time to introduce some concepts about modifier types in Java. Modifier types in Java play an important role that are used to change the meaning of a variable or method, or even class. Modifiers are Java keywords that give the compiler information about the nature of code, data, or classes. In Java, modifiers are categorized into two types:

  • Access modifier
  • Non-access modifier

In this article, we will first learn about access modifiers. non-access modifiers will be discussed in the next article.

Java Access modifier

Access modifiers in Java control which classes may use data, variables, nested classes, and constructors. There are 4 access modifiers in Java:

  • public: the most generous modifier in Java, which is visible anywhere.
  • protected: has scope within the package and all subclasses even in the different packages.
  • default: has scope only inside the same package.
  • private: the most restrictive modifier in Java, has only scope in the class it is declared but other classes can still access private code through the public getter method.

public

The most generous access modifier in Java is public. A class, method, constructor, interface, etc. declared public can be accessed from any other class. Any public method may be overridden by any subclass. An application declares its main() method to be public so that main() can be invoked from any Java runtime environment. For example:

public class PublicClass {
    public static int a = 5;
    public static int squared(int x){
        return x * x;
    }
    public static void main(String[] args){
        System.out.println(squared(a)); // 25;
    }
}

So in this example above, we have a class named PublicClass declared as public, which means it is visible and can be accessed anywhere. Then inside this class, we declare a variable with the type of integer and assign to it the value of 5 and mark it as public. Next, we have a method named squared which takes one argument and returns its square number also marked as public. Finally, we want to print out the squared number of a given variable called a then we create a main() method to run this program. The point is, because both square() method and variable a have a public access, then we can access those method and variable inside the main() method and get the result, which is 25.

protected

The name protected I think it is a bit misleading. From its sound, you might reckon that protected access is extremely restrictive —perhaps the next closest thing to private access. In fact, protected features are even more accessible than default features–which we will learn right after this section.

Unlike public access modifier, which is applied to almost everything, from interfaces, classes, methods, to variables, etc…Only variables, methods, and constructors may be declared as protected. While declared as protected,
the code is accessible in the same package and subclasses, protected variables and methods allow the class itself to access them, classes inside of the same package to access them, and subclasses of that class in a different package to access them. It’s quite ambiguous for now, let’s take an example to clarify this:

package Books;
public class Book {
    public int page = 324;
    public String description = "The unforgettable novel of a childhood in a sleepy Southern town and the crisis of conscience that rocked it.";
    public double rating = 4.27;

    protected void bookTitle() {
        System.out.println("To Kill A Mockingbird");
    }
}

class BookInfo extends Book {
    public static void main(String[] args){
        Book aBook = new Book();
        aBook.bookTitle(); // works fine, access bookTitle method through inheritence 
    }
}
class AnotherClass {
    public static void main(String[] args){
        Book anotherBook = new Book();
        anotherBook.bookTitle(); // works fine, because protected access modifier available anywhere within the same package, then we can directly call bookTitle() method through an instance.
    }
}

So now pretend we create another package named anotherpackage and import the Book class in the Books and we want to access the bookTitle() method in the Book class:

package anotherpackage;
import Books.Book; // import class Book in the Books package.
package anotherpackage;
public class AnotherClass{
      public void getTitle() {
          Book aBook = new Book();
          aBook.bookTitle(); // compiling error
      } 
}

This code segment above will throw an error because bookTitle() method in the Book class which is located in Books package has protected access, which means another package cannot involve this method unless we declare a class that inherits the Book class, like this:

import Books.Book;
package anotherpackage;
public class AnotherClass extends Book{
    public void getTitle() {
        Book anotherBook = new Book();
        anotherBook.bookTittle(); // no more error, works fine now!
    }
}

As you can see, if you want to access the code with protected access in a different package, we need to inherit the class which contains protected code we want by using the extends keyword followed by the parent class (we’ll cover more about inheritance and OOP concepts in some next articles.)

default

Default is the name of the access of classes, variables, and methods if you don’t specify an access modifier. This access modifier is special because it doesn’t have an associated keyword. And default access modifier is more restrictive than the protected modifier.

A variable or method declared without any access control modifier is available to any other class in the same package, anything outside that package will not be allowed to access it. For example:

package Aminal;
class Dog{
    public void bark() {
        System.out.println("Woof woof!");
    }
}

And now we have another package, named Cat and want to access to the Dog class in the Animal package:

import Animal.Dog;
package Cat;
public class Cat {
    public void doSomething() {
        Dog cat = new Dog(); // compiling error
    }
}

Because class Dog has the default modifier, then classes in another package cannot access its code. We it’s ok if the Cat class in the same package with the Dog class:

package Animal;
public class Cat {
    public void doSomething() {
        Dog cat = new Dog(); // no problem, works just fine.
    }
}

private

The most restrictive access modifier is private,  it can be applied for members only. Top-level class or interface never can be declared as private (except the inner class or interface can be declared as private but we will leave it on some more advanced lectures). When a member is marked as private, it is only accessible from within the enclosing class. Nothing outside the class can access a private member. Private access is the ideal way to encapsulate the object itself and hides data from the outside world (again, talk more about it later :D). For example:

class Dog {
    private int numOfTail = 1;
    private int numOfLegs = 4;
    private void bark() {
        System.out.println("Woof woof!");
    }
    
}
class Cat {
    public void getDogProperties() {
        Dog cat = new Dog();
        cat.bark(); // compiling error!
    }
}

We get a compiling error, even in the class Cat we use keyword extends to inherit Dog class properties, again, because everything inside Dog class is marked as private, which are just visible in their enclosing brackets and nothing else:

class Dog {
    private int numOfTail = 1;
    public int numOfLegs = 4;
    private void bark() {
        System.out.println("Woof woof!");
    }
    
}
class Cat extends Dog {
    public void getDogProperties() {
        Dog cat = new Dog();
        cat.bark(); // still compiling error!
    }
}

So we just can access the private variables, methods within their enclosing brackets, e.g the Dog class:

class Dog {
    private int numOfTail = 1;
    private int numOfLegs = 4;
    private void bark() {
        System.out.println("Woof woof!");
    }
    public static void main(String[] args){
        Dog dog = new Dog();
        System.out.println(dog.numOfLegs);
        System.out.println(dog.numOfTail);
        dog.bark();
    }
}

Output:

4
1
Woof woof!

For better understanding, let us formulate a table of those 4 access modifiers:

Access ModifiersSame ClassSame PackageSubclassOther packages
publicYYYY
protectedYYYN
no access modifier (default)YYNN
privateYNNN

Facebook Comments

Previous Article
Next Article

Leave a Reply

avatar
  Subscribe  
Notify of

Sign up for newsletter

* indicates required

Categories

Archives