Java

Public, Private, Protected Access Modifiers and No Modifiers in Java

Public Private Protected Access Modifiers and No Modifiers in Java
Levels of AccessPrivateNo ModifierProtectedPublic
Same ClassYesYesYesYes
Same Package Sub ClassNo YesYesYes
Same Package Non-Sub ClassNoYesYesYes
Different Package Sub ClassNoNoYesYes
Differnt Package Non-Sub ClassNoNoNoYes

Note – In this table, Sub Class means there is a child-parent relationship involved between the two classes.

If you do not understand the above table do not worry because you will be able to understand it after going through the complete article.

Table of Contents

Why I am writing this in-depth article

After discussing Interfaces in our last article, today we will discuss the access modifiers in detail. This article is going to be very long because I will be explaining everything in depth. When I was studying, I found it very challenging to get one article that could explain all the access modifiers and all the scenarios in a single article. I had to go through the books plus a lot of internet articles on public, private and protected modifiers independently. The people who write the articles maybe they have less time or they care about the number of articles in their blog. Whatever the reason is, I felt the need to write an article that explains all the access modifiers in depth.

Please note that Java is a case sensitive programming language so all of these access modifiers can be used in all lower case while developing an application. Anywhere if I mention public private protected in upper-case, please ignore it.

BEFORE WE START YOU NEED TO KEEP IN MIND THAT ACCESS MODIFIERS, ACCESS SPECIFIER, SCOPE MODIFIERS AND SCOPE SPACIFIERS ARE THE SAME THING. DO NOT GET CONFUSED WITH DIFFERENT NAMES.

Why Do We Need Access Modifiers

Suppose if you have the most crucial diamond in this world, where will you keep it? If your answer is the safest place you can find. You are correct because losing the diamond is your biggest loss. The same goes with the data when we start developing an application. If you will talk to the person you are developing this application for, he does not understand technical stuff but the only thing he cares about is his data.

You need to make sure that in any case the data can not be left unprotected. Since you are a student of the programming language you understand the data flow in the classes like blood in our veins. We need to deploy protection and limit access. When we talk about limiting the access we are talking about limiting access to the other classes. To achieve this limitation, we use access modifiers.

Levels of Access Limitation

There are two levels of limitation is Java.

  • Class Level Access Limitation
  • Package Level Access Limitation

Class Level Limitation

Class Level Access Limitation means you do not want your data to be accessed outside a particular class. Here we need to keep in mind when we talk about data, we are talking about methods and variables that should not be accessed outside a class. There will be scenarios where you do not want a method or a variable to be accessed outside a class. There are other techniques to set the value of a variable or get the outcome of a method from a class without accessing the method directly. Some of those techniques are setters and getters. We will talk about setter and getters in a separate article because this article is about access modifiers.

Package Level Limitation

Before we start talking about package level limitation we need to make sure we understand what is a package and why we need it.

What is a package and why we need it?

The package means a folder or a directory. As you know the code that we write in java is inside a class. A class is a file that is saved on our hard drive with the extension as .java. You know the class names can not be the same because there will be a naming conflict and our main method will not be able to understand which class it needs to pick and run.

In the small application, you can deal with this problem easily by choosing different names for your classes because you are the only programmer who is working on this application. But think about a big organization where hundreds of programmers are working and you will see dozens of people are working to develop the same application. Imagine your colleague is fighting with you over the name of a class. He says why did you choose the class name as Employee.java. He wants to keep his class name as Employee.java but because you have already used it he can not use the same name.

To solve this problem the developers of Java introduced the package names. A package is a folder (directory) that is created on the hard drive and you can keep all relevant classes inside that one directory. By using packages you don’t need to worry about the naming conflicts because your class is in a unique folder and every time some other class needs to use the class you made, that class needs to import the package name first and then only that class can use your class. Due to unique package names, the Java compilers will be able to understand easily where to look for a particular class. The class name does not matter now because the class is inside a package and package name is the identity for all the classes inside this package.

Now you just need to keep in mind that you are not using the same class names inside the same package.

Additionally, these packages provide a second layer of protection where we can use the appropriate modifier and limit the access of the class components such as variables and methods on package level. How to choose an appropriate access modifier we will be able to understand once we understand all the access modifiers and also understand our need for limiting access in the application we are developing.

Now that we have understood about the levels of access limitation, its time to talk about all access modifiers and their functionality. We will start with a public access modifier first.

public

The public access modifier is the most famous one. This one gives the maximum level of access. If a class or variable or a method is public it can be accessed at all levels. All level means all levels mentioned in the table on the top of this article. For your ease, I am mentioning it below as well.

Levels of Access
Same Class
Same Package Sub-Class
Same Package Non-Sub-Class
Different Package Sub-Class
Different Package Non-Sub-Class

To understand the public access modifiers let us create a small program for each level.

The public Access Modifier Same Class Scenario

ClassA Code

package mainPackage.Parent;

public class ClassA {
	
	public String message = "Fun Method Statement from ClassA";
	
	public void Fun() {
		System.out.println(message);
		
	}
}

Main Class Code

package mainPackage;

import mainPackage.Parent.ClassA;

public class Hello {

	public static void main(String[] args) {
		
		ClassA classA = new ClassA();
		classA.Fun();
		

	}

}

Program Output

Fun Method Statement from ClassA

Explanation

As you can see the string variable message and Fun() method are inside the same ClassA. The String variable message has the access modifier as public and it is being used inside the Fun() method in the same class. There is no error at all.

We only need to import a package if we are using a class that exist in a different package.

The public Access Modifier Same Package Sub-Class

ClassA Code

package mainPackage.Parent;

public class ClassA {
	
	public void Fun() {
		System.out.println("Fun Method Statement from ClassA");
		
	}
}

ClassB Code

package mainPackage.Parent;

public class ClassB extends ClassA {
	
	public void Fun() {
		System.out.println("Fun Method Statement from ClassB");
		
	}

}

Main Class Code

package mainPackage;

import mainPackage.Parent.ClassA;
import mainPackage.Parent.ClassB;

public class Hello {

	public static void main(String[] args) {
		
		ClassA classB = new ClassB();
		classB.Fun();

	}

}

Program Output

Fun Method Statement from ClassB

Explanation

You can see the ClassA and ClassB are in the same package as mainPackage.Parent and they are in Child parent relationship because ClassB extends ClassA. Both ClassA and ClassB are in use so we need to import their packages as well. Once we import their packages, the ClasssB function is available when we create an object of ClassB and save that object in the variable type of ClassA type.

The public Access Modifier Same Package Non-Sub-Class

ClassA Code

package mainPackage;

public class ClassA {
	
	public void Fun() {
		System.out.println("Fun Method Statement from ClassA");
		
	}
}

Hello Class Code with Main Method

package mainPackage;

public class Hello {

	public static void main(String[] args) {
		
		ClassA classA = new ClassA();
		classA.Fun();
		
	}

}

Program Output

Fun Method Statement from ClassA

Explanation

Both the ClassA and the Hello class are available in the same package. They have no child-parent relationship. Because the Fun() method of ClassA has access modifier as public, the method is available to use in the Hello class.

The public Access Modifier Different Package Sub-Class

ClassA Code

package mainPackage.Parent;

public class ClassA {
	
	public void Fun() {
		System.out.println("Fun Method Statement from ClassA");
		
	}
}

ClassB Code

package mainPackage.Child;

import mainPackage.Parent.ClassA;

public class ClassB extends ClassA{
	
	public void Fun() {
		System.out.println("Fun Method Statement from ClassB");
		
	}

}

Hello Class with Main Method Code

package mainPackage;

import mainPackage.Child.ClassB;
import mainPackage.Parent.ClassA;

public class Hello {

	public static void main(String[] args) {
		
		ClassA classA = new ClassB();
		classA.Fun();
		
	}

}

Program Output

Fun Method Statement from ClassB

Explanation

ClassA and ClassB are in different packages, ClassA is inside package mainPackage.Parent and ClassB is inside package mainPackage.Child. ClassB is a subclass of ClassA. The Fun() method inside ClassB is visible to ClassA due to the access modifier as public.

The public Access Modifier Different Package Non-Sub-Class

ClassA Code

package mainPackage.Parent;

public class ClassA {
	
	public void Fun() {
		System.out.println("Fun Method Statement from ClassA");
		
	}
}

Hello Class with Main Method

package mainPackage;

import mainPackage.Parent.ClassA;

public class Hello {

	public static void main(String[] args) {
		
		ClassA classA = new ClassA();
		classA.Fun();
		
	}

}

Program Output

Fun Method Statement from ClassA

Explanation

The Hello Class with Main Method and ClassA are in different packages and they have no child-parent relationship yet ClassA Fun() method is available because it has access modifier as public. Due to different packages importing the ClassA package is mandatory.

private

This is the time to discuss private access modifier. You can say private access modifier is almost the opposite of public access modifier because it restricts access on all both levels class and package. It only allows access inside the same class. If a variable or method is declared as private it can not be accessed outside the class in any situation.

Level of Access
Same Class

The private Access Modifier Same Class

ClassA Code

package mainPackage.Child;

public class ClassB {
	
	public void Fun() {
		System.out.println("Fun Method Statement from ClassB");
		
	}

}

Hello Class with Main Method

package mainPackage;

public class Hello {

	public static void main(String[] args) {
		
		ClassA classA = new ClassA();
		classA.Fun();
		
	}

}

Program Output

Fun Method Statement from ClassB

Explanation

As you can see the message variable inside ClassA is a local string variable message and can easily be assessed by Fun() method inside the ClassA because both ClassA and string variables exist in the same class. But if we try to access the private variable message outside ClassA then it will not be accessed and the following error will occur.

Exception in thread “main” java.lang.Error: Unresolved compilation problem:
            The field ClassA.message is not visible

            at mainPackage.Hello.main(Hello.java:8)

Inside the class is the only way to access private property or method. There is no other way.

protected

In terms of a protected modifier, we need to keep one thing in mind. There is only one situation in which the property or method will not be accessible and that one situation is.

The package is different and no child-parent relationship. The object can not be accessed.

The Property can not be accessed situation

In every other situation, the property or method can be accessed except the situation mentioned above. If you want the property to be accessed outside a class then you will have to maintain at least one relationship either the same package or child-parent relationship or both.

The protected Access Modifier Same Class

ClassA Code

package mainPackage.Parent;

public class ClassA {
	
	protected String message = "Message from ClassA";

	protected void Fun() {
		System.out.println(message);
	}
	
}

Hello Class with Main Method Code

package mainPackage;

import mainPackage.Parent.ClassA;

public class Hello {

	public static void main(String[] args) {
		
		ClassA classA = new ClassA();
		classA.Fun();
		
	}

}

Program Output

Message from ClassA

Explanation

Despite the String variable being protected, it is accessible to the Fun() method. The Fun() method is protected. Because both the variable and the Fun() method are inside the same class that is why it is possible.

The protected Access Modifier Same Package Sub-Class

ClassA Code

package mainPackage.Parent;

public class ClassA {
	
	protected String message = "Message from ClassA";

	protected void Fun() {
		System.out.println(message);
	}
	
}

ClassB Code

package mainPackage.Parent;

import mainPackage.Parent.ClassA;

public class ClassB extends ClassA {
	
	protected void Fun() {
		System.out.println("Fun Method Statement from ClassB");
		
	}

}

Hello Class with Main Method

package mainPackage.Parent;

import mainPackage.Parent.ClassA;

public class Hello {

	public static void main(String[] args) {
		
		ClassA classB = new ClassB();
		classB.Fun();
		
		}

}

The output of the Program

Fun Method Statement from ClassB

Explanation

All the classes Hello, ClassA and ClassB exist in the same package. ClassB is a subclass of ClassA. The Fun() method in the ClassB is protected but yet accessible out of the class. There are two reasons for accessibility. One is they are in the same package and another is they are in the child-parent relationship.

The protected Access Modifier Same Package Non-Sub-Class

ClassA Code

package mainPackage.Parent;

public class ClassA {
	
	protected String message = "Message from ClassA";

	protected void Fun() {
		System.out.println(message);
	}
	
}

ClassB Code

package mainPackage.Parent;

import mainPackage.Parent.ClassA;

public class Hello {

	public static void main(String[] args) {
		
		ClassA classA = new ClassA();
		classA.Fun();
		
		}

}

The Output of the Program

Message from ClassA

Explanation

The Fun() method is accessible because one condition is fulfilled that both the ClassA and the Hello class are in the same package.

The protected Access Modifier Different Package Sub-Class

ClassA

package mainPackage.Parent;

public class ClassA {
	
	protected String message = "Message from ClassA";
	
}

ClassB

package mainPackage.Child;

import mainPackage.Parent.ClassA;

public class ClassB extends ClassA {
	
	protected String MessagefromDaughter = message;

	public String getMessagefromDaughter() {
		return MessagefromDaughter;
	}

}

Hello Class with Main Method

package mainPackage;

import mainPackage.Child.ClassB;
import mainPackage.Parent.ClassA;

public class Hello {

	public static void main(String[] args) {
		ClassB classB = new ClassB();
		System.out.println(classB.getMessagefromDaughter());
		
		
	}
		

}

Result

Message from ClassA

Explanation

As you can see the string variable called message is a protected variable in ClassA. The message protected variable is accessible inside Child class ClassB because ClassB is a child class of ClassA.

You must be thinking why did I not access the message variable of ClassA directly in the Hello class by creating a ClassB object. The reason is that the protected access modifier says the protected object will not be accessible if the package of other classes is different and there is no child-parent relationship between the two classes. The two classes we are talking about are –

  • The first is where the protected property is located. In this example it is ClassA.
  • The second is where the protected property is being accessed. In this example, it is the Hello class.

Please read further explanation very carefully.

The OOPs Rule - When two classes are in the child-parent relationship. If you create an object of child class it is like creating an object of the parent class. 
The protected access modifier rule - In order to access a protected object we need to maintain at least one relationship, either the other class should be in the same package or the other class should be a subclass.  

The ClassA is not a child class of Hello class. Instead, the ClassA is a parent class of ClassB. So only ClassB can access the properties of ClassA, not Hello class. When we create an object of ClassB, the compiler understands as if we have created an object of ClassA, this is why it does not allow the access of ClassA protected property because ClassA is in a different package and there is no child-parent relationship between Hello class and ClassA. I hope you have understood the example and explanation.

The protected Access Modifier Different Package, Non-Sub-Class

This is the only situation where a protected variable or method can not be accessed. The protected access modifier says that there should be at least one relationship maintained.

Either the other class should be in the same package or the other class should be in a child-parent relationship. If someone will try to access such property that does not follow the above rule, the compiler will give the same error that the protected property or method is not visible.

The Default Access Modifier or No Modifier

With this modifier, property or method can be accessed as long as the host class is in the same package as the class that is accessing the No modifier property.

The default or no Access Modifier Same Class

The Hello Class with Main Method

package mainPackage;

public class Hello {
	
	String message = "Message from Hello Class";

	public static void main(String[] args) {
		Hello hello = new Hello();
		System.out.println(hello.message);

	}
}

Result

Message from Hello Class

Explanation

You can see the above example, the string variable message has no access modifier but it is accessible inside the same class by creating the object of Hello class.

The default or no Access Modifier Same Package Sub-Class

ClassA Code

package mainPackage.Parent;

public class ClassA {
	
	String message = "Message from ClassA";
	
}

ClassB Code

package mainPackage.Parent;

import mainPackage.Parent.ClassA;

public class ClassB extends ClassA {
	
	String messageofClassB = message;
	void ClassBMessage() {
		System.out.println(messageofClassB);
	}

}

The Hello Class with Main Menu

package mainPackage.Parent;

import mainPackage.Parent.ClassB;

public class Hello {

	public static void main(String[] args) {
		
		ClassB classB = new ClassB();
		classB.ClassBMessage();

	}
}

Result

Message from ClassA

Explanation

As you can see in the above example that the string variable message is being accessed in the Hello class through the method of ClassB. Both variables and method have no access modifier. This is possible due to two reasons.

  • All the classes are in the same package.
  • ClassA and ClassB are in child-parent relationships.

The default or no Access Modifier Same Package Non-Sub-Class

ClassA Code

package mainPackage.Parent;

public class ClassA {
	
	String message = "Message from ClassA";
	
}

The Hello Class with Main Method

package mainPackage.Parent;

public class Hello {

	public static void main(String[] args) {
		
		ClassA classA = new ClassA();
		System.out.println(classA.message);

	}
}
Message from ClassA

Explanation

The string variable in ClassA is without any access modifier but still accessible in Hello class, this is possible because the Hello class and ClassA are in the same package.

Conclusion

I hope the above examples are helpful and will assist you to understand the access modifiers in detail. Let us meet in the next article. Till then take care.



Leave a Comment

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More